Viktor
Viktor

Reputation: 71

Return some fields from ASP.NET Web API

What approach should I use if I want to return only some of fields from the model? I want to be able to ask for some fields, something like this:

?fields=email,expiration_date,avatar(thumb_width,thumb_height,thumb_url)

This expression could be also header in the request. I also have nested objects, like the Avatar inside the User.

This will save me hundred of MB of traffic, since some of my models are really heavy ones.

UPDATE: Field selection should work both with Json and XML responses.

Upvotes: 6

Views: 3270

Answers (3)

Zachary Dow
Zachary Dow

Reputation: 1947

You could also use OData. It gives you plenty of flexibility in how you want to query and API. http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint

In your case, you would use $select. I'm also guessing that Avatar is another class, so you would use $expand for that.

/api/endpoint?$select=email,expiration_date&$expand=avatar($select=thumb_width,thumb_height,thumb_url)

I'm not 100% if the syntax for the subselect is right, but I think it is.

Upvotes: 0

Alex
Alex

Reputation: 38509

I found a nuget package that does this for you

WebApi.PartialResponse

Git hub source code:
https://github.com/dotarj/PartialResponse

It essentially wraps the formatter discussed above, so that you only have to configure it like this:

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new PartialJsonMediaTypeFormatter() { IgnoreCase = true });

Then, you can specify ?fields=<whatever> in your request, and it will return the model with only those fields specified.

Upvotes: 6

Betty
Betty

Reputation: 9189

I would replace the default contract resolver (see http://frankapi.wordpress.com/2012/09/09/going-camelcase-in-asp-net-mvc-web-api/) with a custom one, override the GetSerializableMembers method from the Newtonsoft.Json.Serialization.DefaultContractResolver class and filter its results with the value of the querystring fields.

Whether you can access the querystring from that class is another question, you may be able to use the static httpcontext.current to get it, but there may be a cleaner option.

Upvotes: 2

Related Questions