MVC 的可扩展点:MVC 和 WebAPI 中的自定义响应类型





5.00/5 (1投票)
MVC 的可扩展点:MVC 和 WebAPI 中的自定义响应类型
MVC 的可扩展点:MVC 和 WebAPI 中的自定义响应类型
我们知道 MVC 具有许多可扩展点,我们可以在这些点上挂载自定义代码并更改框架的正常行为。当默认框架无法满足我们的需求时,这些实现非常有帮助。 在本文中,我们将实现 MVC 和 WebAPI 中的自定义返回类型。 当我们想要根据应用程序的需求修改返回类型时,这些实现可能会有所帮助。
MVC 中的自定义返回类型
我们知道 ActionResult
是 MVC 中所有返回类型的基类。 诸如 ViewResult
、JsonResult
、EmptyResutl
等返回类型都派生自 ActionResult
。 我们可以从 ActionResult
类派生我们自己的返回类型。
让我们考虑一些我们想要限制响应消息中返回项的情况。 例如,我们有对象列表,并且会根据需要决定返回多少对象。 虽然有很多方法可以做到这一点(例如结果筛选器),但 OData
也可以用于实现此类场景,但我们也可以使用自定义响应类型来实现。
这里我们有一个从 ActionResult
派生的 LimitResult
类。 在构造函数中,我们关心根据“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)); } }
现在我们将使用自定义类作为操作的响应。
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); } }
我们看到只返回了一个项目,因为我们设置只允许在响应中返回一个结果。
WebAPI 2 中的自定义结果
我们知道 Web API 2 支持 IHttpActionResult
类型。 虽然我们可以使用 HttpResponse
作为返回类型。 在此示例中,我们将通过 CustomResultApiController
类包装 IHttpActionResult
接口中的 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<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); } } }
IHttpActionResult
接口包含 ExecuteAsync()
函数,我们已经在两个类中实现了它。 以下是我们如何使用自定义类作为响应对象:
public class HomeController : CustomResultApiController { [System.Web.Http.HttpGet] public IHttpActionResult Forbidded() { return new ForbiddenResult(Request, "My Custom Reason"); } }
我们看到响应消息嵌入在响应对象的正文中。
以同样的方式,我们可以调用 InternalServerErrorResult
。
[System.Web.Http.HttpGet] public IHttpActionResult InternalError() { return new InternalServerErrorResult(Request, "My Custom Error message"); }
结论
当您想要覆盖框架返回类型的默认行为时,自定义响应类型非常有用。