网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 设计资源 > .Net编程 > 正文

MVC技巧总结

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务

刚用MVC完成了一个小项目,MVC技术又有了一次提升,所以,再次写一点总结性的东西。

开发环境:Visual Studio 2010 RC, MVC 2 RC, Entity Framework, SQL Server 2008

1、不对IIS做任何修改,如何在IIS6下运行MVC?
 
(原创,和微软官方做法不同,可以不修改IIS设置就达到目的)

2、不同Areas的Controller重复导致的问题
两个不同的Areas会有不同的命名空间,但是会有相同的 Controller
而在网站MapRoute的时候却只能识别 Controller,因此会出现错误。

假设,我在新建一个MVC项目后,直接新建一个Areas,并且命名为Admin,新建一个Home Controller
运行,弹出以下错误:

 

“/”应用程序中的服务器错误。


The controller name 'Home' is ambiguous between the following types:
MvcApplication1.Controllers.HomeController
MvcApplication1.Areas.Admin.Controllers.HomeController

遇到这种情况,只要这样就可以了

  1. context.MapRoute( 
  2.                 "Web_default"
  3.                 "{controller}/{action}/{id}"
  4.                 new {controller="Home", action = "Index", id = "" }, 
  5.                 new string[] { "MvcApplication1.Areas.Web.Controllers" } 
  6.             ); 

 

调用 MapRoute 的时候在后面多传入一个 String[] ,并且填入你需要 Route 的那个 Areas 的 Controller 所在的命名空间

注意!2个地方都要改

3、关于Filter
MVC提供的4个Filter很方便,但是有一个问题,Filter中不能直接调用 ViewData,TempData等字段。
虽然可以在传入的 filterContext 中调用到,但是很不方便。
这时候,其实可以把4个Filter继承一下,自己写一个新的,并在内部放入ViewData等私有字段
用 IAuthorizationFilter 来举个例子:

  1. public abstract class BaseFilterAttribute : FilterAttribute 
  2.     { 
  3.         //这里可以根据自己的喜好来设定 
  4.         protected HttpSessionStateBase Session; 
  5.         protected ModelStateDictionary State; 
  6.         protected ViewDataDictionary ViewData; 
  7.         protected TempDataDictionary TempData; 
  8.         protected HttpRequestBase Request; 
  9.         protected Dictionary<stringstring> RouteValues; 
  10.         protected UrlHelper Url; 
  11.  
  12.         protected void Initialize(ControllerContext filterContext) 
  13.         { 
  14.             //初始化 
  15.             Request = filterContext.RequestContext.HttpContext.Request; 
  16.             RouteValues = new Dictionary<stringstring>(); 
  17.             foreach (var v in filterContext.RequestContext.RouteData.Values) 
  18.             { 
  19.                 RouteValues.Add(v.Key,v.Value.ToString()); 
  20.             } 
  21.             ViewData = filterContext.Controller.ViewData; 
  22.             TempData = filterContext.Controller.TempData; 
  23.             State = ViewData.ModelState; 
  24.             Session = filterContext.RequestContext.HttpContext.Session; 
  25.             Url = new UrlHelper(filterContext.RequestContext); 
  26.         } 
  27.     } 
  28.  
  29.     public abstract class AuthorizationFilter : BaseFilterAttribute, IAuthorizationFilter 
  30.     { 
  31.         public void OnAuthorization(AuthorizationContext filterContext) 
  32.         { 
  33.             //调用初始化函数 
  34.             Initialize(filterContext); 
  35.             onAuthorization(filterContext); 
  36.         } 
  37.         //这里把原来的 OnAuthorization 替换了一下 
  38.         public abstract void onAuthorization(AuthorizationContext filterContext); 
  39.     } 

 

然后需要使用 IAuthorizationFilter 的时候只要继承上面的 AuthorizationFilter 即可

4、MVC中如何实现弹出一个Javascript对话框,并且跳转?
大家觉得MVC的架构变了,但其实原理和Asp.net一样,还是用 Response来输出数据
所以,只要在 Action 的 Return 函数前调用 Response.Write("text"); 即可实现。
其实和以前一样,下面举个例子,在一个页面中弹出一个对话框后再跳转到别的页面

  1. public ActionResult Test() 
  2.         { 
  3.             //弹出对话框 
  4.             Response.Write(<script>alert('test');</script>)); 
  5.             //跳转到index 
  6.             Response.Write("<script>window.location.href='" + Url.Action("index") + "';</script>"); 
  7.             return null
  8.         } 

 

5、Web.Debug.config 和 Web.Release.config 的用法
利用 Web.config, Web.Debug.config, Web.Release.config
可以在不同环境下生成3中不同的Web.config版本
在VS中调试的时候,直接使用Web.config
用Debug发布的时候,使用Web.Debug.config
用Release发布的时候,使用Web.Release.config

然后,这三个文件怎么用呢?
你可以实现 Web.config 存在一个字段,然后当发布的时候用 Web.Debug.config 内的字段替换掉
也可以本来不存在,发布的时候添加
更可以本来存在,发布的时候删除

这里就做简单的介绍,介绍一种替代的方法:

  1. //Web.config下,假设有这个字段 
  2.   <connectionStrings> 
  3.     <add name="ModelContainer" 
  4.        connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=192.168.174.131,1433;Initial Catalog=Port80;User ID=port80;Password=port80;MultipleActiveResultSets=True&quot;" 
  5.        providerName="System.Data.EntityClient"/> 
  6.   </connectionStrings> 
  7.  
  8. //在Web.Debug.config下 
  9.  
  10.   <connectionStrings> 
  11.     <add name="ModelContainer" 
  12.          connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.\sqlexpress;Initial Catalog=Port80;Integrated Security=True&quot;" 
  13.          providerName="System.Data.EntityClient" 
  14.          xdt:Transform="Replace" 
  15.          xdt:Locator="Match(name)"/> 
  16.   </connectionStrings> 

 

这样,在用Debug发布的时候,那个字段就会被替换掉,具体用法在Web.Debug.config文件内写了一个网站,上面有全部的语法

6、MVC中捕捉错误
MVC中,有一个Filter可以捕捉错误,但是它的用法是利用Attribute来实现的,而且只能加在Controller和Action上,所以不能捕捉别出的错误
其实理论上所有的错误肯定产生于Controller中,但有2种情况下,就不会被捕捉了
1、页面不存在的时候,找不到对应的Controller,那没有任何Controller被执行,所以自然也不会捕捉到错误了
2、在 IAuthorizationFilter 下发生错误的时候,错误捕捉代码在IExceptionFilter中,而IAuthorizationFilter的优先权高于IExceptionFilter,所以也就捕捉不到了
那有没有别的方法?参考了一个老外的代码,发现了一种完美的方法

  1. protected void Application_Error(object sender, EventArgs e) 
  2.         { 
  3.  
  4.             Exception exception = Server.GetLastError(); 
  5.  
  6.             Response.Clear(); 
  7.  
  8.  
  9.             HttpException httpException = exception as HttpException; 
  10.             RouteData routeData = new RouteData(); 
  11.             routeData.Values.Add("controller""Error"); 
  12.  
  13.             if (httpException == null
  14.             { 
  15.                 routeData.Values.Add("action""Index"); 
  16.             } 
  17.             else //It's an Http Exception, Let's handle it. 
  18.             { 
  19.  
  20.                 switch (httpException.GetHttpCode()) 
  21.                 { 
  22.                     case 404: 
  23.                         // Page not found. 
  24.                         routeData.Values.Add("action""HttpError404"); 
  25.                         break
  26.                     case 500: 
  27.                         // Server error. 
  28.                         routeData.Values.Add("action""HttpError500"); 
  29.                         break
  30.                     // Here you can handle Views to other error codes. 
  31.                     // I choose a General error template   
  32.                     default
  33.                         routeData.Values.Add("action""General"); 
  34.                         break
  35.                 } 
  36.             } 
  37.  
  38.             // Pass exception details to the target error View. 
  39.             routeData.Values.Add("error", exception.Message); 
  40.  
  41.             // Clear the error on server. 
  42.             Server.ClearError(); 
  43.  
  44.             // Call target Controller and pass the routeData. 
  45.             IController errorController = new WEB.Controllers.ErrorController(); 
  46.             errorController.Execute(new RequestContext( 
  47.            new HttpContextWrapper(Context), routeData)); 
  48.  
  49.         } 

 

把这段代码放到 Global.asax 中,并且新建一个 Controller 叫做 Error

  1. namespace WEB.Controllers 
  2.     public class ErrorController : Controller 
  3.     { 
  4.         public ActionResult Index(string error) 
  5.         { 
  6.             ViewData["Title"] = "WebSite 网站内部错误"
  7.             ViewData["Description"] = error; 
  8.             return View("Index"); 
  9.         } 
  10.  
  11.         public ActionResult HttpError404(string error) 
  12.         { 
  13.             ViewData["Title"] = "HTTP 404- 无法找到文件"
  14.             ViewData["Description"] = error; 
  15.             return View("Index"); 
  16.         } 
  17.  
  18.         public ActionResult HttpError500(string error) 
  19.         { 
  20.             ViewData["Title"] = "HTTP 500 - 内部服务器错误"
  21.             ViewData["Description"] = error; 
  22.             return View("Index"); 
  23.         } 
  24.  
  25.  
  26.         public ActionResult General(string error) 
  27.         { 
  28.             ViewData["Title"] = "HTTP 发生错误"
  29.             ViewData["Description"] = error; 
  30.             return View("Index"); 
  31.         } 
  32.     } 

 

这样,就可以捕捉所有错误了。

但其实,这样也不是完美的,因为如果你参考了我第一个问题中,在IIS6下不修改IIS设置,运行了MVC,那当后缀名不是.aspx的时候,错误不会被捕捉
因为这时候输入的地址根本没有交给网站来处理,IIS直接抛出了错误,因为IIS认为这个后缀名不是你所能执行的。

  • 下一篇资讯: ASP.NETMVC实战演练
  • 设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
    版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师