Click here to Skip to main content
15,889,808 members
Articles / Web Development / ASP.NET / ASP.NETvNext
Article

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

Rate me:
Please Sign up or sign in to vote.
3.00/5 (2 votes)
15 Nov 2016CPOL2 min read 10.7K   2   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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer DELL International
India India
I am software developer from INDIA. Beside my day to day development work, i like to learn new technologies to update myself. I am passionate blogger and author in various technical community including dotnetfunda.com , c-sharpcorner.com and codeproject. My area of interest is modern web technology in Microsoft stack. Visit to my personal blog here.

http://ctrlcvprogrammer.blogspot.in/

Comments and Discussions

 
QuestionBad example Pin
bborac24-Jan-17 14:56
bborac24-Jan-17 14:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.