ASP.NET MVC 框架实践总结

  我公司开发团队采用asp.net mvc大致经过了三个阶段

  1、摸索期:从今年初公司开发一个新项目时选用了asp.net MVC Preview2,然后用了几天我发现routing似乎有bug,正在这时发现了已经出现了preview2-590,我赶紧将框架“升级”到了590。

  2、应用期:项目开发一个多月后我们发现了一些不方便不顺手的地方,感觉缺少一些提高效率的小功能,如当一个路径的参数经过routing路由到一个action后,action及视图页(.aspx/.ascx)上下文里获取它不符合我们的开发逻辑——在应用mvc之前我们都是用Request["id"]的方式获取,但是如果此时如果一个参数被routing"美化"后就得不到了,代码如下:

ContractedBlock.gif ExpandedBlockStart.gif 路由条目例
1 routeCollection.Add("0"new System.Web.Routing.Route("{id}/space/{action}/{page}/{size}",
2                 new RouteValueDictionary(new { controller = "space", action = "index", id = "0", page = "3", size = "76" }),
3                 new RouteValueDictionary(new { controller = "[^/]+", action = "[^/]+", id = "\\d+", page = "\\d*" }),
4                 null

 

相应的控制器和action代码如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
    public partial class SpaceController : AjaxController
ExpandedBlockStart.gifContractedBlock.gif    
{
        [Bll.Filter.SpaceViewFilter]
        
public void Story(long id, long? classid, int? page, int? size)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
            RenderView(
"Story");
        }

}

ContractedBlock.gif控制器代码

 现在story方法体内以及story.aspx里Request["id"],Request["page"] 获取不到相应的值!由于开发项目时有些路由规则没有写,打算以后总体调整路由规则,但是出错了,因为根本获取不到参数,我们非常郁闷!

  于是我开始下载源码、检阅、跟踪、修改,经过一周左右的时间终于将MVC的流程及原理理了个顺,最后修改加进了一些我们急需的小功能:
修改了System.Web.Mvc的控制器、视图相关的代码,实现了在Action、.aspx/.ascx/.master里可以沿用Request["key"]的方式获取参数(不论routing怎么变都不影响),不区分key的大小
修改了ViewData类,使ViewData["key"]不区分大小写;

增加了一个路由配置类,使路由器可以能过.config文件来配置,如下:

ContractedBlock.gif ExpandedBlockStart.gif routing配置文件
<configuration>
  
<configSections>
    
<section name="routeTable" type="System.Web.Mvc.RouteTableSection,System.Web.Mvc" allowDefinition="Everywhere" allowExeDefinition="MachineToApplication" restartOnExternalChanges="true" />
  
</configSections>
  
<routeTable>
    
<routes>
      
<add name="StoryTaglist" url="/Story/Tag/{id}/{page}/{size}"  routeHandlerType="System.Web.Mvc.MvcRouteHandler, System.Web.Mvc">
        
<defaults controller="Story" action="Tag" classid="0" size="null"/>
      
</add>

    
</routes>
  
</routeTable>
</configuration>

 给ViewData增加了一些扩展方法Get<T>(key)类方法,取得viewdata里的某个值,并且转换成指定的对象类型,如果不是该类型或如果是一个数组类型而元素为0个或没有此key都将返回null,代码如下:

ContractedBlock.gif ExpandedBlockStart.gif ViewData.Get()
var ams = ViewData.Get<IList<KeyValuePair<Duw.Mod.DB.Album, Duw.Mod.DB.ViewFriendandfriendtype>>>("albumList");
  
if (ams != null)
ExpandedBlockStart.gifContractedBlock.gif  
{ 。。。
}

类完整代码如下:

ContractedBlock.gif ExpandedBlockStart.gif ViewData.Get()
using System;
using System.Collections;
using System.Collections.Generic;


namespace System.Web.Mvc
ExpandedBlockStart.gifContractedBlock.gif
{
    
using System.Collections;
    
using System.Web.UI;

    
public static partial class CustomHelper
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 取得viewdata里的某个值,并且转换成指定的对象类型,如果不是该类型或如果是一个数组类型而元素为0个或没有此key都将返回空,
        
/// </summary>
        
/// <typeparam name="T">必须为一个非值类型</typeparam>
        
/// <param name="obj"></param>
        
/// <param name="key"></param>
        
/// <returns></returns>

        public static T Get<T>(this System.Web.Mvc.ViewData obj, string key)
            
where T : class
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (!obj.ContainsDataItem(key))
                
return null;

            var val 
= obj[key];

            
if (val == null)
                
return null;

            var val2 
= val as T;
            
if (val2 == null)
                
return null;

            
if (val2 is IEnumerable)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                var a 
= (IEnumerable)(val2);

                var b 
= a.GetEnumerator();

                
//try
                
//{
                if (b.MoveNext())
                    
return val2;
                
else
                    
return null;
                
//}
                
//catch
                
//{
                
//    return null;
                
//}
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return val2;
            }


        }



ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 如果没有此key,返回""
        
/// </summary>
        
/// <param name="obj"></param>
        
/// <param name="key"></param>
        
/// <returns></returns>

        public static string GetString(this System.Web.Mvc.ViewData obj, string key)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (!obj.ContainsDataItem(key))
                
return "";

            var val 
= obj[key];
            
if (val == nullreturn "";
            
return val.ToString();
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 如果没有此key或不能转换成数值类型,返回-1
        
/// </summary>
        
/// <param name="obj"></param>
        
/// <param name="key"></param>
        
/// <returns></returns>

        public static long GetLong(this System.Web.Mvc.ViewData obj, string key)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (!obj.ContainsDataItem(key))
                
return -1;
            var val 
= obj[key];
            
if (val == nullreturn -1;

            
long v;
            
if (long.TryParse(val.ToString(), out v))
                
return v;
            
else
                
return -1;
        }



ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 如果没有此key或不能转换成数值类型,返回-1
        
/// </summary>
        
/// <param name="obj"></param>
        
/// <param name="key"></param>
        
/// <returns></returns>

        public static int GetInt(this System.Web.Mvc.ViewData obj, string key)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (!obj.ContainsDataItem(key))
                
return -1;
            var val 
= obj[key];
            
if (val == nullreturn -1;

            
int v;
            
if (int.TryParse(val.ToString(), out v))
                
return v;
            
else
                
return -1;
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 如果没有此key或不能转换成布尔类型,返回false
        
/// </summary>
        
/// <param name="obj"></param>
        
/// <param name="key"></param>
        
/// <returns></returns>

        public static bool GetBool(this System.Web.Mvc.ViewData obj, string key)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (!obj.ContainsDataItem(key))
                
return false;
            var val 
= obj[key];
            
if (val == nullreturn false;

            
bool v;
            
if (bool.TryParse(val.ToString(), out v))
                
return v;
            
else
                
return false;
        }




ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 如果没有此key或不能转换成数值类型,返回-1.0
        
/// </summary>
        
/// <param name="obj"></param>
        
/// <param name="key"></param>
        
/// <returns></returns>

        public static double GetDouble(this System.Web.Mvc.ViewData obj, string key)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (!obj.ContainsDataItem(key))
                
return -1.0;
            var val 
= obj[key];
            
if (val == nullreturn -1.0;

            
double v;
            
if (double.TryParse(val.ToString(), out v))
                
return v;
            
else
                
return -1.0;
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 如果没有此key或不能转换成数值类型,返回0.0;如果超过float的范围并且在double范围内则自动截取为float类型值返回
        
/// </summary>
        
/// <param name="obj"></param>
        
/// <param name="key"></param>
        
/// <returns></returns>

        public static float GetFloat(this System.Web.Mvc.ViewData obj, string key)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
double val = obj.GetDouble(key);
            
if (val == 0.0)
                
return 0.0f;
            
else
                
return (float)val;
        }




ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 判断某一个key值是否存在;并且如果它是一个枚举对象还要判断它是否包含一个以上的元素
        
/// </summary>
        
/// <param name="obj"></param>
        
/// <param name="key"></param>
        
/// <returns></returns>

        public static bool Has(this System.Web.Mvc.ViewData obj, string key)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{

            
if (!obj.ContainsDataItem(key))
                
return false;

            var val 
= obj[key];

            
if (val == null)
                
return false;

            
if (val is IEnumerable)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                var a 
= (IEnumerable)(val);

                var b 
= a.GetEnumerator();

                
try
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
if (b.MoveNext())
                        
return true;
                    
else
                        
return false;
                }

                
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
return false;
                }

            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return true;
            }

        }

    }

}

 

给controller增加一个类似.aspx里的Url.Action("story","space",{id=34})的方法Util.GetUrl():

ContractedBlock.gif ExpandedBlockStart.gif Util.GetUrl()
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Reflection;
using System.Web.Mvc;
using System.Web.Routing;

namespace System.Web.Mvc
ExpandedBlockStart.gifContractedBlock.gif
{
    
public class Util
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
public  static string GetUrl(ControllerContext context, RouteValueDictionary values)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string routeName = "";
            VirtualPathData vpd 
= string.IsNullOrEmpty(routeName) ? RouteTable.Routes.GetVirtualPath(context, values) : RouteTable.Routes.GetVirtualPath(context, routeName, values);
            
return vpd.VirtualPath;

            
//return UrlRewriterHelper.GetUrl(context, values, RouteTable.Routes);
        }


    }

}


 3、框架性能调优与重造,经过半年的应用开发、总结,发现MVC性能及routing不是很理想,于是又开始进行性能调优与修改,最后改成了现在的“版本”,详情请看下一篇性能调优。

 


转载于:https://www.cnblogs.com/yihuiso/archive/2008/09/10/1288504.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值