You could write an action filter that understands the fields parameter and converts the response. I have a sample implementation that translates the response object into a Dictionary. The keys are the fields that the client had asked and the values are the values of the fields from the object being returned in the response. The implementation is a sample and is no where near complete :)
public class FieldFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var fieldsParameter = actionExecutedContext.Request.GetQueryNameValuePairs().Where(kvp => kvp.Key == "fields");
if (fieldsParameter.Count() == 1)
{
object response;
object newResponse;
if (actionExecutedContext.Response.TryGetContentValue(out response))
{
string[] fields = fieldsParameter.First().Value.Split(',');
IEnumerable<object> collection = response as IEnumerable<object>;
if (collection != null)
{
newResponse = collection.Select(o => SelectFields(fields, o));
}
else
{
newResponse = SelectFields(fields, response);
}
actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.OK, newResponse);
}
}
}
private static Dictionary<string, object> SelectFields(string[] fields, object value)
{
Dictionary<string, object> result = new Dictionary<string, object>();
foreach (string field in fields)
{
result.Add(field, GetValue(field, value));
}
return result;
}
private static object GetValue(string indexer, object value)
{
string[] indexers = indexer.Split('.');
foreach (string property in indexers)
{
PropertyInfo propertyInfo = value.GetType().GetProperty(property);
if (propertyInfo == null)
{
throw new Exception(String.Format("property '{0}' not found on type '{1}'", property, value.GetType()));
}
value = propertyInfo.GetValue(value);
if (value == null)
{
return null;
}
}
return value;
}
}