何时使用 HttpResponseMessage 和 Request.CreateResponse

Posted

技术标签:

【中文标题】何时使用 HttpResponseMessage 和 Request.CreateResponse【英文标题】:When to use HttpResponseMessage and Request.CreateResponse 【发布时间】:2014-03-30 09:37:09 【问题描述】:

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

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

【问题讨论】:

CreateResponse()CreateErrorResponse() 只是帮助开发人员的工具(扩展方法)。 @abatishchev:我认为还有一个不同的地方,那就是CreateResponse(也可能是CreateErrorResponse)会使用当前的请求头来响应但是HttpResponseMessage创建新的响应和头,这是真的? 可以从源码中探索:github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/… 【参考方案1】:

HttpResponseMessage 对象和 Request.CreateResponse(...) 方法?

这可能很明显,但Request.CreateResponse 是创建HttpResponseMessage 对象的辅助方法。

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

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

另一方面,如果你自己创建HttpResponseMessage,你必须指定一个媒体格式化程序,基于该媒体格式化程序对象将被序列化,并且通过你自己指定媒体格式化程序,你可以覆盖conneg的结果。

编辑 这是一个如何指定 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 您不必指定,因为它会由 CreateResponse 自动发生 - 您可以在此处阅读详细信息 imcodebased.com/…【参考方案2】:

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
      ;
    
  

【讨论】:

以上是关于何时使用 HttpResponseMessage 和 Request.CreateResponse的主要内容,如果未能解决你的问题,请参考以下文章

如何确定是不是使用 HttpClient 从缓存中完成了 HttpResponseMessage

HttpResponseMessage 你处理了吗?

无法使用 UTF8 编码转换 HttpResponseMessage

使用 HttpResponseMessage 401 在 ajax 帖子上总是成功

将内容放在 HttpResponseMessage 对象中?

构建 ASP.NET Web Api 时是不是必须使用 HTTP 协议和 HttpResponseMessage 类?