65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2016 年 11 月 15 日

CPOL

2分钟阅读

viewsIcon

11373

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

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

我们知道 MVC 具有许多可扩展点,我们可以在这些点上挂载自定义代码并更改框架的正常行为。当默认框架无法满足我们的需求时,这些实现非常有帮助。 在本文中,我们将实现 MVC 和 WebAPI 中的自定义返回类型。 当我们想要根据应用程序的需求修改返回类型时,这些实现可能会有所帮助。

MVC 中的自定义返回类型

我们知道 ActionResult 是 MVC 中所有返回类型的基类。 诸如 ViewResultJsonResultEmptyResutl 等返回类型都派生自 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");
        }

结论

当您想要覆盖框架返回类型的默认行为时,自定义响应类型非常有用。

© . All rights reserved.