2013-08-31 42 views
4

我正在使用servicestack和AngularJS资源模块。问题是,当我调用我的服务的query()方法来请求一个分页列表时,我想发送一个自定义的响应标题和行数。ServiceStack:在DTO中使用属性来设置响应头和响应主体

我想HTTP响应看起来像这样:

HTTP/1.1 200 OK 
Content-Type: application/json; charset=utf-8 
Server: Microsoft-IIS/8.0 
X-Total-Rows: 14 
X-Powered-By: ServiceStack/3,958 Win32NT/.NET 
Content-Length: 831 

[{"id":11,"content":"Item 10","dueDate":"2013-10-17T00:00:00.0000000","priority":9}, 
{"id":13,"content":"Item 12","dueDate":"2013-06-16T00:00:00.0000000","priority":9}, 
{"id":20,"content":"Item 19","dueDate":"2013-04-06T00:00:00.0000000","priority":9}, 
{"id":32,"content":"Item 31","dueDate":"2013-01-21T00:00:00.0000000","priority":9}, 
{"id":42,"content":"Item 41","dueDate":"2013-05-16T00:00:00.0000000","priority":9}, 
{"id":19,"content":"Item 18","dueDate":"2013-07-14T00:00:00.0000000","priority":8}, 
{"id":15,"content":"Item 14","dueDate":"2013-03-06T00:00:00.0000000","priority":7}, 
{"id":12,"content":"Item 11","dueDate":"2013-02-23T00:00:00.0000000","priority":4}, 
{"id":18,"content":"Item 17","dueDate":"2013-10-21T00:00:00.0000000","priority":3}, 
{"id":14,"content":"Item 13","dueDate":"2013-01-11T00:00:00.0000000","priority":2}] 

就目前而言,要做到这一点,我用下面的DTO:

[Route("/todos", Verbs = "GET")] 
public class Todos : IReturn<List<Todo>> 
{ 
    [DataMember(Name = "q")] public string Query { get; set; } 
    [DataMember(Name = "sort")] public string Sort { get; set; } 
    [DataMember(Name = "desc")] public bool IsDesc { get; set; } 
    [DataMember(Name = "limit")] public int? Limit { get; set; } 
    [DataMember(Name = "offset")] public int Offset { get; set; } 
} 

[Route("/todos", Verbs = "POST")] 
[Route("/todos/{Id}", Verbs = "GET,PUT,DELETE")] 
public class Todo : IReturn<Todo> 
{ 
    public int Id { get; set; } 
    public string Content { get; set; } 
    public DateTime? DueDate { get; set; } 
    public int? Priority { get; set; } 
} 

而且在服务:

public object Get(Todos request) 
{ 
    long count; 
    var items = _repository.GetAll(request.Query, request.Sort, request.IsDesc, request.Limit, request.Offset, out count); 
    Response.AddHeader("X-Total-Rows", count.ToString(CultureInfo.InvariantCulture)); 
    return items.Select(Mapper.Map<TodoItem, Todo>).ToList(); 
} 

我想在服务栈中做的是在ResponseDTO中使用自定义属性来表明我想要一些要在响应头中序列化的属性以及在响应主体中序列化的其他属性。 响应DTO可能是这样的:

public class TodosResponse 
{ 
    [Header(Name = "X-Total-Rows")] public int TotalRows { get; set; } 
    [Body] public List<Todo> Todos { get; set; } 
} 

服务将创造这样的回应:

public object Get(Todos request) 
{ 
    long count; 
    var items = _repository.GetAll(request.Query, request.Sort, request.IsDesc, request.Limit, request.Offset, out count); 
    return new TodosResponse 
      { 
       TotalRows = count, 
       Todos = items.Select(Mapper.Map<TodoItem, Todo>).ToList() 
      }; 
} 

和当然,HTTP响应会是什么样子完全同上。

所以我的问题是:是否有可能实现这与自定义属性?

回答

4

实现你想要的更简单/更整洁的方法是返回一个HttpResult并在其中定义头文件。

public object Get(Todos request) 
{ 
    long count; 
    var items = _repository.GetAll(request.Query, request.Sort, request.IsDesc, request.Limit, request.Offset, out count); 
    var response = items.Select(Mapper.Map<TodoItem, Todo>).ToList(); 

    return new HttpResult(response, HttpStatusCode.OK) 
      { 
       Headers = 
         { 
          {"X-Total-Rows", count} 
         } 
      }; 
} 

这避免了与元数据

污染的响应对象