ServiceStack: use attribute in DTO to set response header and response body

I am using servicestack with the AngularJS resource module. The problem is that when I call the query () method of my service to request a broken list, I want to send a custom response header with the total number of rows.

I would like the HTTP response to look like this:

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}] 

Currently, I use the following DTOs for this:

 [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; } } 

And in the service:

 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(); } 

What I would like to do in servicestack is to use custom attributes in ResponseDTO to indicate that I want some properties to be serialized in response headers and other properties serialized in the response body. The DTO answer might look like this:

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

The service will create a response like this:

 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() }; } 

And of course, the HTTP response will look exactly the same as above.

So my question is: is it possible to achieve this with custom attributes?

+4
source share
1 answer

A simpler / more subtle way to achieve what you want is to return an HttpResult and define the headers inside.

 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} } }; } 

This prevents metadata from polluting your response object.

+4
source

Source: https://habr.com/ru/post/1499923/


All Articles