当前位置 > 首页 > Asp.net

Asp.net web Api源码分析-HttpResponseMessage

12/6/2012 8:11:00 PM来源:Asp.net

紧接着上文Asp.net web Api源码分析-Action的执行 我们的Action已经执行完毕,现在需要把Action的返回结果转化为HttpResponseMessage 实例,我们也知道转化工作主要在HttpRequestMessage的CreateResponse附加方法中,

public static HttpResponseMessage CreateResponse<T>(this HttpRequestMessage request, HttpStatusCode statusCode, T value, HttpConfiguration configuration)
{
if (request == null)
{
throw Error.ArgumentNull("request");
}

configuration = configuration ?? request.GetConfiguration();
if (configuration == null)
{
throw Error.InvalidOperation(SRResources.HttpRequestMessageExtensions_NoConfiguration);
}

IContentNegotiator contentNegotiator = configuration.Services.GetContentNegotiator();
if (contentNegotiator == null)
{
throw Error.InvalidOperation(SRResources.HttpRequestMessageExtensions_NoContentNegotiator, typeof(IContentNegotiator).FullName);
}

IEnumerable<MediaTypeFormatter> formatters = configuration.Formatters;

// Run content negotiation
ContentNegotiationResult result = contentNegotiator.Negotiate(typeof(T), request, formatters);

if (result == null)
{
// no result from content negotiation indicates that 406 should be sent.
return new HttpResponseMessage
{
StatusCode = HttpStatusCode.NotAcceptable,
RequestMessage = request,
};
}
else
{
MediaTypeHeaderValue mediaType = result.MediaType;
return new HttpResponseMessage
{
// At this point mediaType should be a cloned value (the content negotiator is responsible for returning a new copy)
Content = new ObjectContent<T>(value, result.Formatter, mediaType),
StatusCode = statusCode,
RequestMessage = request
};
}
}

 

首先这里需要一个IContentNegotiator实例,这里有这么一句代码:

  IContentNegotiator contentNegotiator = configuration.Services.GetContentNegotiator();在DefaultServices中有   SetSingle<IContentNegotiator>(new DefaultContentNegotiator());这句,我们知道默认的contentNegotiator是DefaultContentNegotiator实例。DefaultContentNegotiator构造函数也比较普通,这里我们还需要一个数据的格式化Formatters,这里有这么一句 IEnumerable<MediaTypeFormatter> formatters = configuration.Formatters;,在Asp.net web Api源码分析-HttpServer的创建
曾提到Formatters主要有JsonMediaTypeFormatter,XmlMediaTypeFormatter, FormUrlEncodedMediaTypeFormatter,JQueryMvcFormUrlEncodedFormatter这4个。接着我们知道要干什么了,需要把我们的value转换为需要的格式,这里创建一个 ContentNegotiationResult result = contentNegotiator.Negotiate(typeof(T), request, formatters);实例,其中Negotiate的主要实现如下:

public virtual ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
        {
             ....。。。。。。
            // Go through each formatter to compute how well it matches.
            Collection<MediaTypeFormatterMatch> matches = ComputeFormatterMatches(type, request, formatters);

            // Select best formatter match among the matches
            MediaTypeFormatterMatch bestFormatterMatch = SelectResponseMediaTypeFormatter(matches);

            // We found a best formatter
            if (bestFormatterMatch != null)
            {
                // Find the best character encoding for the selected formatter
                Encoding bestEncodingMatch = SelectResponseCharacterEncoding(request, bestFormatterMatch.Formatter);
                if (bestEncodingMatch != null)
                {
                    bestFormatterMatch.MediaType.CharSet = bestEncodingMatch.WebName;
                }

                MediaTypeHeaderValue bestMediaType = bestFormatterMatch.MediaType;
                MediaTypeFormatter bestFormatter = bestFormatterMatch.Formatter.GetPerRequestFormatterInstance(type, request, bestMediaType);
                return new ContentNegotiationResult(bestFormatter, bestMediaType);
            }

            return null;
        }
这里的Negotiate方法实现比较复杂,首先找到当前请求支持的一个MediaTypeFormatterMatch集合,然后再从这个集合中找到找最合适一个


  • 《MOSS工作流权限设置》之一 “我的任务不给你看”

    8/21/2007 2:17:00 AM

    摘要: 一直以来都被MOSS的工作流权限问题所困扰. 我们虽然将任务分配给了某人,但事实上,所有在任务列表中有编辑权限的用户都可以编辑该任务. 而我们并不希望用户能够看到不属于自己的任务.

  • Web框架比较

    5/23/2007 11:27:00 PM

    摘要: 对比几个常见的Web framework. 同时简单介绍了一下工作中使用Spring Web Flow的感受! 阅读全文 Anders小明 2007-05-23 22:43 发

  • ASP.NET MVC Controller激活系统详解:IoC的应用[下篇]

    4/1/2012 12:43:00 PM

    [ 上篇 ]除了通过自定义ControllerFactory的方式引入IoC之外,在使用默认DefaultControllerFactory情况下也可以通过一些扩展使基于IoC的Controller

  • WORD/EXCEL内容替换

    4/28/2009 5:25:00 PM

    最近,在做一个小项目时,需要用到WORD/EXCEL(目前只针对OFFICE2003)文档中内容的替换,在网上搜寻了一番,找到了一些解决方法,自己再整理了一下,记录出来与大家共享。 1、在项目

  • .NET中的设计模式——利用空模式构造安全代码

    9/4/2010 7:38:00 PM

    作者: 倪大虾 发表于 2010-09-04 16:24 原文链接 阅读: 210 评论: 3 题记: 《.NET中的设计模式》系列随笔停下有一段时间了,一则总结个东西不容易,另一

  • WawaKM征集4名有兴趣参与开源项目人员(暂放首页一天)

    5/29/2007 10:24:00 PM

    WawaKM征集4名有兴趣参与开源项目人员(暂放首页一天) WawaKM是要做一个个人应用的软件,包括个人知识管理和个人辅助管理,及一些针对个人的web服务。 WawaKM现在要做三块儿内容 1、

  • My Crush List of 2009

    4/28/2009 11:10:00 PM

    These are few things which currently I am working on and some technologies which I want to learn in

  • My move to Graffiti

    4/30/2009 3:50:00 AM

    Technorati Tags: ASP.NET , CMS , Graffiti Many folks have asked me to share the results of the eval

  • visual studio 2008的鸡肋:母版页

    8/18/2007 11:03:00 AM

    在以前的网站一直没有用过母版页,习惯了ascx用户控件,新安装了visual studio 2008 beta2,打算把母版页应用于实际项目中,但切发现其功能甚鸡肋,不得不放弃这项MS的新功能。

  • re: WPF/E CTP Quick Start - 第九部分:动画(翻译)

    2/10/2007 4:56:00 AM

    @heweitykc 主要是FLASH图形计算完全依赖于CPU,FLASH里无法通过AS调用显卡资源 老陈 2007-02-09 23:31 发表评论