在开发Web应用程序时,经常需要根据特定需求调整框架的默认行为。例如,可能需要根据应用需求修改返回类型。本文将介绍如何在MVC和WebAPI中实现自定义返回类型。
在MVC框架中,ActionResult
是所有返回类型的基类。例如,ViewResult
、JsonResult
、EmptyResult
等都是从ActionResult
派生的。也可以派生自己的返回类型。
假设有一个对象列表,并且需要根据需求决定返回多少对象。虽然有多种实现方式(例如结果过滤器、OData等),但也可以使用自定义响应类型来实现。
下面是一个名为LimitResult
的类,它从ActionResult
派生。在构造函数中,根据“Count”值过滤项目。
public class LimitResult : ActionResult
{
Dictionary _disc = new Dictionary();
public LimitResult(List 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));
}
}
现在可以使用自定义类作为动作的响应。
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index()
{
List person = new List();
person.Add(new Person { Id = 1, Name = "Sourav" });
person.Add(new Person { Id = 2, Name = "Kayal" });
return new LimitResult(person, 1);
}
}
可以看到,只返回了一个项目,因为设置了只允许在响应中返回一个结果。
在Web API 2中,支持IHttpActionResult
作为返回类型。虽然可以使用HttpResponse
作为返回类型,但在这个例子中,将在自定义响应类中实现IHttpActionResult
。
有一个名为CustomResultApiController
的类,它包装了ForbiddenResult
类和InternalServerErrorResult
类。因此,CustomResultApiController
看起来像是一个自定义响应类型的包装。
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 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 ExecuteAsync(CancellationToken cancellationToken)
{
var response = _request.CreateResponse(HttpStatusCode.InternalServerError, _errormessage);
return Task.FromResult(response);
}
}
}
IHttpActionResult
接口包含ExecuteAsync()
函数,在两个类中都实现了它。以下是如何使用自定义类作为响应对象。
public class HomeController : CustomResultApiController
{
[System.Web.Http.HttpGet]
public IHttpActionResult Forbidded()
{
return new ForbiddenResult(Request, "My Custom Reason");
}
}
[System.Web.Http.HttpGet]
public IHttpActionResult InternalError()
{
return new InternalServerErrorResult(Request, "My Custom Error message");
}