We know that MVC has many
extensible point where we can hook up our custom code and change normal behavior
of framework. Those implementations are really helpful when default framework
is not able to meet our requirement.
In this article we will implement
custom return type both in MVC and WebAPI. Those implementation could be
helpful when we want to modify return type based on application’s demand.
Custom return type in MVC
We know that ActionResult is base
class of all return type in MVC. Return type like ViewResult, JsonResult ,
EmptyResutl etc are derived from ActionResult. We can derive our return type
from ActionResult class as well.
Let’s think some use case where we
want to limit return items in response message. For example we have list of
objects and on demand we will decide how many objects we will return.
Though there are many ways like result
filter , OData are there to implement such scenario but we can use custom
response type too to implement.
Here we have LimitResult class
which is derived from ActionResult. Within constructor we care 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
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 1 result is allowed in response.
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 ExecuteAsync()
function and we have implemented in both classes.
Here is how, we can use our custom classes as 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 body
of response object.
In same way we can invoke InternalServerErrorResult.
[System.Web.Http.HttpGet]
public IHttpActionResult InternalError()
{
return new InternalServerErrorResult(Request, "My Custom
Error message"); }
Conclusion:Custom response type is really helpful when you
want to override default behavior of frameworks return type.
No comments:
Post a Comment