何时使用HttpResponseMessage和Request.CreateResponse?

36

我们什么时候应该使用HttpResponseMessage对象,什么时候应该使用Request.CreateResponse(...)方法?

另外,HttpResponseMessage对象和Request.CreateResponse(...)方法之间有什么区别?


CreateResponse()CreateErrorResponse() 只是帮助开发人员更轻松地完成工作的辅助方法(扩展方法)。 - abatishchev
@abatishchev: 我认为还有一个不同之处,那就是CreateResponse(可能还有CreateErrorResponse)将使用当前请求头来响应,但是HttpResponseMessage会创建新的响应和头部,这是真的吗? - user197508
4
您可以从源代码中进行探索:https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Http/HttpRequestMessageExtensions.cs。 - abatishchev
2个回答

46

HttpResponseMessage对象和Request.CreateResponse(...)方法之间的区别是什么?

很明显,Request.CreateResponse是用于创建HttpResponseMessage对象的帮助方法。

我们何时必须使用HttpResponseMessage对象?何时必须使用Request.CreateResponse(...)方法?

如果你想使用内置的内容协商功能,请使用Request.CreateResponse。当你返回一个对象时,ASP.NET Web API必须将对象序列化为响应体。通常情况下,这可以是JSON或XML(还有其他可能的媒体类型,但需要创建格式化程序)。所选择的媒体类型(JSON或XML)基于请求内容类型,请求中的Accept头等,内容协商是确定要使用的媒体类型的过程。通过使用Request.CreateResponse,你自动使用此过程的结果。

另一方面,如果你自己创建了HttpResponseMessage,则必须指定一个基于其进行序列化的媒体格式化程序。通过自己指定媒体格式化程序,你可以覆盖内容协商的结果。

编辑:以下是如何指定JSON格式化程序的示例。

public HttpResponseMessage Get(int id)
{
    var foo = new Foo() { Id = id };
    return new HttpResponseMessage()
    {
        Content = new ObjectContent<Foo>(foo,
                  Configuration.Formatters.JsonFormatter)
    };
}

即使您发送包含Accept:application/xml的请求,您也只会收到JSON。


我该如何指定基于哪种媒体格式化程序将对象序列化到 HttpResponseMessage 中?请给出一个例子。 - user197508
@user197508,您不必指定,因为它将通过CreateResponse自动发生-您可以在此处阅读详细信息:http://imcodebased.com/setting-httpcontext-response-using-httpresponsemessage-or-request-createresponse-in-webapi2/ - codebased

4

Request.CreateResponse(...)是一个构建器,它也返回HttpResponseMessage的实例。下面是代码:

public static HttpResponseMessage CreateResponse<T>(this HttpRequestMessage request, HttpStatusCode statusCode, T value, HttpConfiguration configuration)
{
  if (request == null)
    throw Error.ArgumentNull("request");
  configuration = configuration ?? HttpRequestMessageExtensions.GetConfiguration(request);
  if (configuration == null)
    throw Error.InvalidOperation(SRResources.HttpRequestMessageExtensions_NoConfiguration, new object[0]);
  IContentNegotiator contentNegotiator = ServicesExtensions.GetContentNegotiator(configuration.Services);
  if (contentNegotiator == null)
  {
    throw Error.InvalidOperation(SRResources.HttpRequestMessageExtensions_NoContentNegotiator, new object[1]
    {
      (object) typeof (IContentNegotiator).FullName
    });
  }
  else
  {
    IEnumerable<MediaTypeFormatter> formatters = (IEnumerable<MediaTypeFormatter>) configuration.Formatters;
    ContentNegotiationResult negotiationResult = contentNegotiator.Negotiate(typeof (T), request, formatters);
    if (negotiationResult == null)
    {
      return new HttpResponseMessage()
      {
        StatusCode = HttpStatusCode.NotAcceptable,
        RequestMessage = request
      };
    }
    else
    {
      MediaTypeHeaderValue mediaType = negotiationResult.MediaType;
      return new HttpResponseMessage()
      {
        Content = (HttpContent) new ObjectContent<T>(value, negotiationResult.Formatter, mediaType),
        StatusCode = statusCode,
        RequestMessage = request
      };
    }
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接