Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Extensible Point of MVC: Custom Response Type in MVC and WebAPI

0.00/5 (No votes)
15 Nov 2016 1  
Extensible point of MVC: Custom response type in MVC and WebAPI

Extensible point of MVC: Custom response type in MVC and WebAPI

We know that MVC has many extensible points where we can hook up our custom code and change the normal behavior of a framework. Those implementations are really helpful when the default framework is not able to meet our requirements. In this article, we will implement a custom return type in MVC and WebAPI. Those implementations could be helpful when we want to modify return type based on an application’s demand.

Custom return type in MVC

We know that ActionResult is a base class of all return types in MVC. Return types like ViewResult, JsonResult, EmptyResutl etc. are derived from ActionResult. We can derive our return type from the ActionResult class as well.

Let’s think of some use cases where we want to limit the return items in a response message. For example, we have lists of objects and on demand we will decide how many objects we will return. Though there are many ways to do this (like result filter), OData are there to implement such scenarios but we can use a custom response type to implement as well.

Here we have LimitResult class which is derived from ActionResult. Within constructor we care about filtering out items based on value of “Count”.

public class LimitResult : ActionResult
    {
        Dictionary<int, Person> _disc = new Dictionary<int, Person>();
        
        public LimitResult(List<Person> list, int Count)
        {
            foreach (var item in list.Take(Count))
            {
                _disc.Add(item.Id, item);
            }  
        }
        public override void ExecuteResult(ControllerContext context)
        {
            HttpResponseBase response = context.HttpContext.Response;
            response.ContentType = "application/json";
            response.Write(JsonConvert.SerializeObject( _disc));
        }
    }

Now we will use the custom class as a response from action.

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class HomeController : Controller
{
    public ActionResult Index()
    {
        List<Person> person = new List<Person>();
        person.Add(new Person { Id = 1, Name = "Sourav" });
        person.Add(new Person { Id = 2, Name = "Kayal" });

        return new LimitResult(person , 1);
    }
}

We are seeing that only one item has returned because we set that only one result is allowed in response.

Image 1

Custom Result in WebAPI 2

We know that Web API 2 supports IHttpActionResult as type. Though we can use HttpResponse as return type. In this example, we will implement IHttpActionResult in our custom response class. Here we have wrap ForbiddenResult class and InternalServerErrorResult class by CustomResultApiController class. So the CustomResultApiController looks like a package of custom response type.

public abstract class CustomResultApiController : ApiController
    {
        public class ForbiddenResult : IHttpActionResult
        {
            private readonly HttpRequestMessage _request;
            private readonly string _reason;

            public ForbiddenResult(HttpRequestMessage request, string reason)
            {
                _request = request;
                _reason = reason;
            }

            public ForbiddenResult(HttpRequestMessage request)
            {
                _request = request;
                _reason = "Forbidden";
            }

            public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
            {
                var response = _request.CreateResponse(HttpStatusCode.Forbidden, _reason);
                return Task.FromResult(response);
            }
        }


        public class InternalServerErrorResult : IHttpActionResult
        {
            private readonly HttpRequestMessage _request;
            private readonly string _errormessage;

            public InternalServerErrorResult(HttpRequestMessage request, string error)
            {
                _request = request;
                _errormessage = error;
            }

            public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
            {
                var response = _request.CreateResponse(HttpStatusCode.InternalServerError, _errormessage);
                return Task.FromResult(response);
            }
        }

    }

The IHttpActionResult interface contains the ExecuteAsync() function and we have implemented in both classes. Here is how we can use our custom classes as a response object.

public class HomeController : CustomResultApiController
    {
        [System.Web.Http.HttpGet]
        public IHttpActionResult Forbidded()
        {
            return new ForbiddenResult(Request, "My Custom Reason");
        }
    }

We are seeing that the response message is embedded in the body of the response object.

Image 2

In same way we can invoke InternalServerErrorResult.

[System.Web.Http.HttpGet]
public IHttpActionResult InternalError()
{
    return new InternalServerErrorResult(Request, "My Custom Error message");
}

Image 3

Conclusion

Custom response type is really helpful when you want to override default behavior of frameworks return type.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here