Search code examples
asp.net-mvcasp.net-web-apijson.net

Change returned object value after action execution in Web API


In ASP.Net Web API, the action returned object will be converted to XML or JSON automatically - is there a way to add additional process to the returned object before it gets converted?

What I want to achieve is to wrap returned object into a generic APIResponse (another class) type which has an object Property called Data that will be assigned with whatever the original returned object is.

for example:

public Books[] FindBooks(string keyword)
{
..
    return new Books[] {new Book(){Name="ASP.NET"}};
}

This will return JSON of book array by default, however I want to wrap the result into an object called APIResponse, so the returned object becomes:

new APIResponse(){
    Data = //the Book[] array return from the action method
}

By doing this, I will be able to keep the freedom of returning normal business objects in Web API however always return the same object type in JSON format when the front-end Ajax requests.

I believe it can be done in a way however I'm not familiar with the Web API life cycle, can any way give some guide on this?

Thank you.


Solution

  • I fixed it by creating a custom MediaTypeFormatter however simply inheriting from JSON formatter which have already got all what I need, here is the very simple code I added, which resolved all issues I have!!!

        public class APIResponseMediaFomatter : JsonMediaTypeFormatter
        {
            public override Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
            {
                ResponseMessage wrappedValue = null;
                if (type != typeof(ResponseMessage) || (value != null && value.GetType() != typeof(ResponseMessage)))
                    wrappedValue = new ResponseMessage(value);
                return base.WriteToStreamAsync(typeof(ResponseMessage), wrappedValue, writeStream, content, transportContext);
            }
        }
    

    Cheers!