阿不

潜水

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  212 随笔 :: 0 文章 :: 3070 评论 :: 75 引用

ASP.NET MVC框架从还未正式发布时就已经成为了我工作的方向和重点,而它也在不断的完善和发展,前两天,ASP.NET MVC2 RTM已经发布了,MVC2主要是在提高我们基于ASP.NET MVC框架之上的WEB程序开发效率上下功夫,新增了很多的常用功能的集成,API的优化以及IDE的改善支持等方面。随着开发效率的不断提高和资源的不断丰富,以及MVC框架本身所具备的天生的优点,我相信未来ASP.NET平台的WEB开发将会逐步走向MVC方向。至少在ASP.NET Mobile Web的开发中,Webform已经被MVC所取代,在未来的ASP.NET中,包含Mobile WebForm 控件的System.Web.Mobile.dll程序将会被标上过期标志,以及发布新的基于ASP.NETMVC的Mobile Web开发指导。同时,ASP.NET MVC2仍然开放了它的所有源码,源码下载(最下方的mvc2-ms-pl.zip文件)。

以上是关于ASP.NET MVC的一些感想,并不是我本文的重点。本文要叙述的是关于ASP.NET MVC Action参数值来源的优先顺序问题。我们知道在ASP.NET MVC的Controller Action函数中,我们可以添加一些参数,不管这些参数的类型是简单类型,还是复杂类型的对象,MVC都会自动从请求的上下文中寻找全适匹配的值自动赋值到参数中。我们还知道,一次的HTTP请求中,传值的方式可以有很多种,可以用QueryString,Header,Post Form等等。在MVC中,还可能会有经过Route解析过的Route Values。我们Action的参数值来源是从哪些传值方式中取值的呢?他们的优先级又是如何呢?这是很早以前一位同事提出的问题。花了几分钟阅读了一下MVC关于赋值绑定的代码,大家可以从ValueProviderDictionary里的一段代码中找到答案。这段代码是获取要做为ModelBinder绑定的数据源,ModelBinder在绑定参数据值所需的数据源就是从这里得到的:

private void PopulateDictionary()
{
    CultureInfo currentCulture = CultureInfo.CurrentCulture;
    CultureInfo invariantCulture = CultureInfo.InvariantCulture;
    NameValueCollection form = this.ControllerContext.HttpContext.Request.Form;
    if (form != null)
    {
        foreach (string str in form.AllKeys)
        {
            string[] rawValue = form.GetValues(str);
            string attemptedValue = form[str];
            ValueProviderResult result = new ValueProviderResult(rawValue, attemptedValue, currentCulture);
            this.AddToDictionaryIfNotPresent(str, result);
        }
    }
    RouteValueDictionary values = this.ControllerContext.RouteData.Values;
    if (values != null)
    {
        foreach (KeyValuePair<string, object> pair in values)
        {
            string key = pair.Key;
            object obj2 = pair.Value;
            string str4 = Convert.ToString(obj2, invariantCulture);
            ValueProviderResult result2 = new ValueProviderResult(obj2, str4, invariantCulture);
            this.AddToDictionaryIfNotPresent(key, result2);
        }
    }
    NameValueCollection queryString = this.ControllerContext.HttpContext.Request.QueryString;
    if (queryString != null)
    {
        foreach (string str5 in queryString.AllKeys)
        {
            string[] strArray4 = queryString.GetValues(str5);
            string str6 = queryString[str5];
            ValueProviderResult result3 = new ValueProviderResult(strArray4, str6, invariantCulture);
            this.AddToDictionaryIfNotPresent(str5, result3);
        }
    }
}

从代码中我们可以获知,Action 参数的数据首先会从当前请求的form表单中取值,之后是route解析过的route values,最后是从QueryString中取得所前面没有重复出现过的值。重复出现的以最先取的值为优先。在某些情况下,我们可能会因为这个细节而花费大量的时间在调试为什么我们Action中的参数值不正确。

posted on 2010-03-14 20:55 阿不 阅读(...) 评论(...) 编辑 收藏