笔者对公司项目开发中应用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"美化"后就得不到了,代码如下:

路由条目例
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代码如下:

Code
public partial class SpaceController : AjaxController

{
[Bll.Filter.SpaceViewFilter]
public void Story(long id, long? classid, int? page, int? size)

{

RenderView("Story");
}
}
控制器代码
现在story方法体内以及story.aspx里Request["id"],Request["page"] 获取不到相应的值!由于开发项目时有些路由规则没有写,打算以后总体调整路由规则,但是出错了,因为根本获取不到参数,我们非常郁闷!
于是我开始下载源码、检阅、跟踪、修改,经过一周左右的时间终于将MVC的流程及原理理了个顺,最后修改加进了一些我们急需的小功能:
修改了System.Web.Mvc的控制器、视图相关的代码,实现了在Action、.aspx/.ascx/.master里可以沿用Request["key"]的方式获取参数(不论routing怎么变都不影响),不区分key的大小
修改了ViewData类,使ViewData["key"]不区分大小写;
增加了一个路由配置类,使路由器可以能过.config文件来配置,如下:

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,代码如下:

ViewData.Get()
var ams = ViewData.Get<IList<KeyValuePair<Duw.Mod.DB.Album, Duw.Mod.DB.ViewFriendandfriendtype>>>("albumList");
if (ams != null)

{ 。。。
}
类完整代码如下:

ViewData.Get()
using System;
using System.Collections;
using System.Collections.Generic;


namespace System.Web.Mvc


{
using System.Collections;
using System.Web.UI;

public static partial class CustomHelper

{

/**//// <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

{
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)

{
var a = (IEnumerable)(val2);

var b = a.GetEnumerator();

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

{
return val2;
}

}



/**//// <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)

{
if (!obj.ContainsDataItem(key))
return "";

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


/**//// <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)

{
if (!obj.ContainsDataItem(key))
return -1;
var val = obj[key];
if (val == null) return -1;

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



/**//// <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)

{
if (!obj.ContainsDataItem(key))
return -1;
var val = obj[key];
if (val == null) return -1;

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


/**//// <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)

{
if (!obj.ContainsDataItem(key))
return false;
var val = obj[key];
if (val == null) return false;

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




/**//// <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)

{
if (!obj.ContainsDataItem(key))
return -1.0;
var val = obj[key];
if (val == null) return -1.0;

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


/**//// <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)

{
double val = obj.GetDouble(key);
if (val == 0.0)
return 0.0f;
else
return (float)val;
}




/**//// <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)

{

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

var val = obj[key];

if (val == null)
return false;

if (val is IEnumerable)

{
var a = (IEnumerable)(val);

var b = a.GetEnumerator();

try

{
if (b.MoveNext())
return true;
else
return false;
}
catch

{
return false;
}
}
else

{
return true;
}
}
}
}

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

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


{
public class Util

{
public static string GetUrl(ControllerContext context, RouteValueDictionary values)

{
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不是很理想,于是又开始进行性能调优与修改,最后改成了现在的“版本”,详情请看下一篇性能调优。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库