当前位置 > 首页 > Asp.net

Asp.net web Api源码分析-HttpResponseMessage

2012-12-6 20:11:00来源: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集合,然后再从这个集合中找到找最合适一个


  • PDB Files: What Every Developer Must Know

    2009-5-26 21:11:00

    I did not know about the importance of PDB files until I read this article. John Robbins wrote abou

  • Html.RenderAction and Html.Action

    2009-11-19 5:21:00

    One of the upcoming new features being added to ASP.NET MVC 2 Beta is a little helper method called

  • How to disable an ASP.NET linkbutton when clicked

    2011-2-15 4:32:00

    Scenario: User clicks a LinkButton in your ASP.NET page and you want to disable it immediately usin

  • 如何使用dotnetbar控件来构造多文档界面

    2010-12-18 1:21:00

    在前段时间一篇随笔《 利用优秀的.NET界面控件,打造新潮的界面效果 》中介绍过Dotnetbar的界面效果,虽然引发不少关于该控件效果的争议,不过话说回来,使用该控件也不失为一个界面的解决方案,本

  • 用 C# 设计与实现一个四则算术运算解释器

    2009-5-27 1:22:00

    摘要: 今天下午用 C# 写了一个简单的四则算术解释器 (Interpreter)。该解释器主要有两个功能:一是能够进行基本的四则运算,也即加减乘除;二是能够检测输入的语法错误,对于不合法的运算指令

  • Observer Design Pattern

    2010-1-12 19:04:00

    Hi, Many times when programming we come across situation where by change in one change needs

  • 我就是那个福娃

    2007-5-10 11:13:00

    很小以来,对于大型充气玩具一直充满好奇,也曾经在麦当劳门口看到麦当劳叔叔的充气娃娃,甚至过去和他握手,询问他在里面感觉如何。而在刚过去的五一节当中,我也体验了一把做充气娃娃的感觉。(本来想让大家猜猜

  • 使用CLR存储过程方便快捷导出数据到Excel

    2009-12-3 15:54:00

    阅读: 680 评论: 2 作者: 小No 发表于 2009-12-03 12:05 原文链接 今天早上看到一篇文章( Exporting to Excel Using a CLR St

  • ASP.NET MVC中Controller与View之间的数据传递总结

    2009-12-11 2:11:00

    阅读: 145 评论: 3 作者: 深山老林 发表于 2009-12-10 23:20 原文链接 在 ASP.NET MVC 中,经常会在 Controller 与 View 之间传递数

  • Using Custom Validation with LINQ to SQL in an ASP.Net application

    2010-12-16 2:28:00

    A friend of mine is working in an ASP.Net application and using SQL Server as the backend. He also