MVC使用路由系统处理请求的URL。路由系统主要功能

  • 检查请求的URL,并理解该URL对应的控制器和方法
  • 生成URL地址

在MVC程序中有两种方式创建路由:convention-based routing和attribute routing,其中attribute routing是mvc5.0新特性

 一、新建与注册路由

路由是在App_Start/RouteConfig.cs文件静态方法RegisterRoutes定义的,该方法在Global.asax.cs被调用

例1.新建并注册一个路由

 public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
Route myRoute = new Route("{controller}/{action}",new MvcRouteHandler());
routes.Add("myRoute",myRoute);
}
}

此处注册路由使用routes.Add方法,大部分情况注册路由使用的是routes.MapRoute方法,如例2(与例1等价)

 public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute", "{controller}/{action}");
}
}

二、设置路由的默认值

设置程序默认起始页码也就是设置路由的默认值(用匿名类赋值),如下

例1.

 public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"myRoute",
"{controller}/{action}",
new { action="Index"});//匿名类赋值
}
}

此处路由匹配两个segment的URL和单个segment的URL,即以下URL匹配:

http://localhost:51248/Admin/Index

http://localhost:51248/Home

例2.

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"myRoute",
"{controller}/{action}",
new { controller="Home",action="Index"});//
}
}

以下URL都匹配上面代码的路由

http://localhost:51248/Admin/Index

http://localhost:51248/Home

http://localhost:51248  即程序默认起始页码是Home/Index的视图页面

三、使用static URL segment

 public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"myRoute",
"mySiteCompany/{controller}/{action}",
new { controller="Home",action="Index"});
}
}

以下URL都匹配上面代码的路由

http://localhost:51248/mySiteCompany/Customer/List

http://localhost:51248/mySiteCompany/Admin

http://localhost:51248/mySiteCompany

例3.

  public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"myRoute",
"X{controller}/{action}",
new { controller="Home",action="Index"});
}
}

匹配URL的例子:

http://localhost:51248/XAdmin/Index

http://localhost:51248/XAdmin

http://localhost:51248/Xhome

四、路由顺序

routes are applied in the order in which they are in the RouteCollection object.而每次routes.MapRoute注册路由都是添加到RouteCollection 列表最后,因此注册路由代码顺序就是路由顺序。当路由系统接收到一个URL请求,先和第一个路由匹配,匹配不成功再和第二个路由匹配....直到匹配成功一个路由或者没有。

例如:

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{ routes.MapRoute("Default",
"{controller}/{action}",
new {controller="Home",action="Index"}
);//第一个 routes.MapRoute(
"myRoute",
"X{controller}/{action}",
new { controller="Home",action="Index"});//第二个
}
}

由于第一个路由可以匹配任何URL。因此该URL:http://localhost:51248/XAdmin/Index请求时,路由系统查找时匹配第一个路由成功不会继续匹配第二个路由,从而报404错误。因此上面代码应该改为如下:即两个路上顺序调换

 public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{ routes.MapRoute(
"myRoute",
"X{controller}/{action}",
new { controller = "Home", action = "Index" }); routes.MapRoute("Default",
"{controller}/{action}",
new {controller="Home",action="Index"}
);
}
}

例子:假如你重构了应用程序,将控制器Shop修改为Home,此时可以利用路由兼容重构之前的URL

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("ShopSchema",
"Shop/{Action}",
new { controller = "Home"
});

routes.MapRoute(
"myRoute",
"X{controller}/{action}",
new { controller = "Home", action = "Index" }); routes.MapRoute("Default",
"{controller}/{action}",
new {controller="Home",action="Index"}
);
}
}
 public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{ routes.MapRoute("ShopShcema1",
"Shop/OldAction",
new { controller = "Home", action = "Index"
});

routes.MapRoute("ShopSchema",
"Shop/{Action}",
new { controller = "Home" }); routes.MapRoute(
"myRoute",
"X{controller}/{action}",
new { controller = "Home", action = "Index" }); routes.MapRoute("Default",
"{controller}/{action}",
new {controller="Home",action="Index"}
);
}
}

五、定可变长度的路由

{*catchall}

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional}
);
}
}

以上路由可以匹配任何URL

六、URL参数

后台获取URL参数方法RouteData.Values["参数名"]

例1.

public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
ViewBag.Controller = "Home";
ViewBag.Action = "Index";
return View("ActionName");
} public ActionResult CustomerVariable()
{
ViewBag.Controller = "Home";
ViewBag.Action = "CustomerVariable";
ViewBag.CustomerVariable = RouteData.Values["id"];
return View();
}
}
对应视图 @{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>CustomerVariable</title>
</head>
<body>
<div>The Controller is :@ViewBag.Controller</div>
<div>The Action is :@ViewBag.Action</div>
<div>The Customer Variable is :@ViewBag.CustomerVariable</div>
</body>
</html>

路由设置:

 public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index",id="DefaultId"}
);
}
}

则http://localhost:51248/Home/CustomerVariable请求结果为

http://localhost:51248/Home/CustomerVariable/Hello请求结果显示为:

1.URL参数作控制器方法的方法参数:控制器方法的参数名称应与URL参数名称相同(路由定义的名称)

例子:CustomerVariable方法修改为如下,则页面显示与上面一样

 public ActionResult CustomerVariable(string id)
{
ViewBag.Controller = "Home";
ViewBag.Action = "CustomerVariable";
ViewBag.CustomerVariable = id;
return View();
}

2.设置URL参数可选:在路由定义时设置

例子:

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional}
);
}
}

修改控制器方法

 public ActionResult CustomerVariable(string id)
{
ViewBag.Controller = "Home";
ViewBag.Action = "CustomerVariable";
ViewBag.CustomerVariable = id??"<no value>";//判断id是否为null
return View();
}

七、使用命名空间设置控制器的优先级

假如应用程序存在两个Home控制器,假设为AdditionalController文件夹下有一个Home控制器,Controllers下也有一个Home控制器。此时程序运行会报错。可以在路由定义的地方设置路由默认值时增加命名空间来解决,如下:

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional},
new[] { "UrlsAndRoutes.AdditionalController" }
);
}
}

此时程序处理请求时默认是先在路由添加的命名空间中查找,即UrlsAndRoutes.AdditionalController空间查找控制器,如果找不到对应的控制器则查找所有文件夹。

在路由中设置命名空间也是有顺序的,例如

 public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional},
new[] { "UrlsAndRoutes.AdditionalController", "UrlsAndRoutes.Controllers" }
);
}
}

此时运行程序任然会报错。如果想要一个控制器在一个命名空间,而其他控制器在另一个命名空间,则通过添加路由来解决程序查找时命名空间顺序,例如

  public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("AddControllerRoute",
"Home/{action}/{id}/{*catchal}",
new {controller="Home",action="Index",id=UrlParameter.Optional},
new[] { "UrlsAndRoutes.AdditionalController"}
);//第一个路由 routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional},
new[] { "UrlsAndRoutes.Controllers" }
);//第二个路由
}
}

第一个路由匹配URL第一个segment是Home,则调用AdditionalController空间的Home控制器,其他的控制器器请求则调用Controllers命名空间

在路由中设置程序在查找控制器时只查找指定的空间(即路由设置的命名空间)如下:

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
Route myRoute=routes.MapRoute("AddControllerRoute",
"Home/{action}/{id}/{*catchal}",
new {controller="Home",action="Index",id=UrlParameter.Optional},
new[] { "UrlsAndRoutes.AdditionalController"}
);//第一个路由
myRoute.DataTokens["UaseNamespaceFallback"] = false;//设置路由查找控制器只在AdditionalController空间查找 routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional},
new[] { "UrlsAndRoutes.Controllers" }
);//第二个路由 }
}

八、路由约束

1.使用正则表达式进行路由约束

 public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional},
new {controller= "^H.*" },
new[] { "UrlsAndRoutes.Controllers" }
); }
 public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional},
new {controller= "^H.*",action= "^Index$|^about" },
new[] { "UrlsAndRoutes.Controllers" }
);
}

2、定义一个只响应Get请求

 public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional},
new {controller= "^H.*",action= "Index|about",httpMethod=new HttpMethodConstraint("Get")},
new[] { "UrlsAndRoutes.Controllers" }
);
}

3、使用MVC自带约束类路由约束

    using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Mvc.Routing.Constraints;
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional},
new {controller= "^H.*",action= "Index|about",httpMethod =new HttpMethodConstraint("Get"),
id =new RangeRouteConstraint(10,20)},
new[] { "UrlsAndRoutes.Controllers" }
);
}
}
约束类位于命名空间System.Web.Mvc.Routing.Constraints。与RangeRouteConstraint类似的约束类还有如下:
AlpahRouteConstraint():检查是否为字母,不区分大小写
BoolRouteConstraint():匹配是否是bool类型
DateTimeRouteConstraint()
DecimalRouteConstraint()
DoubleRouteConstraint()
FloatRouteConstraint()
IntRouteConstraint()
LongRouteConstraint()
LenthRouteConstraint(len)
LenthRouteConstraint(min,max)
MaxRoute(val):匹配不大于val的数字
MinRoute(val)
MinLengthRouteConstraint(len):匹配字符串至少len个字符
MaxLengthRouteConstraint(len)
RangeRouteConstraint(min,max)匹配数据在(min,max)\
可以同时使用多个约束类进行多种约束,如下
 using System.Web.Mvc.Routing.Constraints;
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional},
new {controller= "^H.*",action= "Index|about",httpMethod =new HttpMethodConstraint("Get"),
id =new CompoundRouteConstraint(new IRouteConstraint[]
{ new AlphaRouteConstraint(),new MinLengthRouteConstraint(6
) })
},
new[] { "UrlsAndRoutes.Controllers" }
);
}
}
4、自定义约束
自定义路由约束只要实现IRouteConstraint类即可,
例子:
步骤1.定义约束类
namespace UrlsAndRoutes.Infrastructure
{
using System.Web;
using System.Web.Routing;
public class UserAgentConstraint : IRouteConstraint
{
private string requireUserAgent;
public UserAgentConstraint(string agentParam)
{
this.requireUserAgent = agentParam;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return httpContext.Request.UserAgent != null && httpContext.Request.UserAgent.Contains(requireUserAgent);
}
}
}

步骤2.运用自定义约束类

    using System.Web.Mvc;
using System.Web.Routing;
using UrlsAndRoutes.Infrastructure;
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional},
new {customConstraint=new UserAgentConstraint("Chrome")},
new[] { "UrlsAndRoutes.Controllers" }
);
}
}

九、使用属性路由

这是MVC5.0新特性。个人建议使用convention-based路由。attribute routing默认情况下是没有用的,需要在RouteConfig.cs类RegisterRoutes方法进行注册,如下:

 public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapMvcAttributeRoutes();//启用attribute routing

routes.MapRoute("myRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index",id=UrlParameter.Optional},
new[] { "UrlsAndRoutes.Controllers" }
);
}
}
设置好之后就可以使用属性路由了,如下
public class HomeController : Controller
{
[Route("Test")]
public ActionResult Index()
{
ViewBag.Controller = "Home";
ViewBag.Action = "Index";
return View("ActionName");
} public ActionResult CustomerVariable(string id)
{
ViewBag.Controller = "Home";
ViewBag.Action = "CustomerVariable";
ViewBag.CustomerVariable = id??"<no value>";//判断id是否为null
return View();
}
}
Route("Test")设置了一个静态路由,启动程序显示:

如果一个action方法被属性路由修饰,则无法通过定义RouteConfig.cs类RegisterRoutes方法中的约定路由系统进行访问。如上面的例子:Home控制器的Index被
[Route("Test")]修饰,虽然RouteConfig.cs路由定义默认启动的页面,但访问时URL必须是http://localhost:51248/Test,而http://localhost:51248/无法访问
The route attribute stops convention-based routes from targeting an action method even if attribute routing is disabled.So
take care of the MapMvcAttributeRoutes method in RouteConfig.cs
1、带URL参数的属性路由
 public class CustomerController : Controller
{
// GET: Customer
public ActionResult Index()
{
ViewBag.Controller = "Customer";
ViewBag.Action = "Index";
return View("ActionName");
} [Route("Users/Add/{user}/{id}")]
public string Create(string user,int id)
{
return string.Format("User:{0},ID:{1}",user,id);
} public ActionResult List()
{
ViewBag.Controller = "Customer";
ViewBag.Action = "List";
return View("ActionName");
}
}

2、属性路由使用约束

       [Route("Users/Add/{user}/{id:int}")]
public string Create(string user,int id)
{
return string.Format("User:{0},ID:{1}",user,id);
} [Route("Users/Add/{User}/{password}")]
public string changePass(string user,string password)
{
return $"ChangePass Method-User:{user},Pass:{password}";
}

结果为:

   

3、属性路由使用复合约束

[Route("Users/Add/{User}/{password:alpha:length(6)}")]
public string changePass(string user,string password)
{
return $"ChangePass Method-User:{user},Pass:{password}";
}

十、使用路由前缀

使用路由前缀可以为多个方法定义一个共同的前缀,如下

  [RoutePrefix("Users")]
public class CustomerController : Controller
{
[Route("~/Test")]
public ActionResult Index()
{
ViewBag.Controller = "Customer";
ViewBag.Action = "Index";
return View("ActionName");
} [Route("Add/{user}/{id:int}")]
public string Create(string user,int id)
{
return string.Format("User:{0},ID:{1}",user,id);
} [Route("Add/{User}/{password:alpha:length(6)}")]
public string changePass(string user,string password)
{
return $"ChangePass Method-User:{user},Pass:{password}";
} public ActionResult List()
{
ViewBag.Controller = "Customer";
ViewBag.Action = "List";
return View("ActionName");
}
}

其中[Route("~/Test")]表示Index方法不需要这个前缀,其他方法都要。

 十一、路由高级特性

1、@Html.ActionLink

例1.

@Html.ActionLink("This is an outgoing URL", "CustomerVariable")
@Html.ActionLink("This target another controller","Index", "Admin")

例2.URL传参

@Html.ActionLink("This is an outgoing URL", "CustomerVariable",new { id="Hello"})

例3.设置Hmtl属性,以@开始,例如设置样式

@Html.ActionLink("This is an outgoing URL", "Index","Home",null,new { id="Hello",@class="myCSSClass"})

=>

<a class="myCSSClass" href="/App/DoIndex" id="Hello">This is an outgoing URL</a>

例4.生成绝对URL

@Html.ActionLink("This is an outgoing URL", "Index","Home","https","myserver.mydomain",
"myFragmentName",new { id="myId"}, new { id="myAnchorID",@class="myCSSClass"})

=>

 <a class="myCSSClass" href="https://myserver.mydomain/Home/Index/myId#myFragmentName" id="myAnchorID">This is an outgoing URL</a>

2、@Url.Action

生成纯文本的URL,非链接

例1

 @Url.Action("Index", "Home", new { id="MyId"})

页面显示如下

例2、在控制器方法中生成URL

 string myActionUrl = Url.Action("Index",new { id="myID"});
string myRouteUrl = Url.RouteUrl(new { controller="Home",action="Index"});

例3、后台跳转到其他Action

 public RedirectToRouteResult MyActionMethod()
{
return RedirectToAction("Index");
}

例4、后台跳转到另一个URL

public RedirectToRouteResult MyActionMethod()
{
return RedirectToRoute(new { controller = "Home", action = "Index", id = "myID" });
}

3、@Html.RouteLink

根据某个路由生成URL

例1、

路由设置如下

public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("myRoute", "{controller}/{action}"); routes.MapRoute("myOtherRoute", "App/{action}", new { controller="Home"}); }
@Html.RouteLink("Click Me","myRoute","Index","Customer")

=>

<a Length="" href="/App/Index?Length=5">Click Me</a>

4、自定义路由系统

自定义路由系统方法定一个继承于RouteBase的类,即实现RouteBase中的两个方法

GetRouteData(HttpContextBase httpContext)

GetVirtualPath(RequestContext requestContext,RouteValueDictionary values)

步骤一、定义路由类

 public class LegacyRoute : RouteBase
{
private string[] urls;
public LegacyRoute(params string[] targetUrls)
{
urls = targetUrls;
} public override RouteData GetRouteData(HttpContextBase httpContext)
{
RouteData result = null;
string requestedURL = httpContext.Request.AppRelativeCurrentExecutionFilePath;
if (urls.Contains(requestedURL, StringComparer.OrdinalIgnoreCase))
{
result = new RouteData(this,new MvcRouteHandler());
result.Values.Add("controller", "Legacy");
result.Values.Add("action", "GetLegacyURL");
result.Values.Add("legacyURL", requestedURL);
}
return result;
} public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}

步骤二、注册路由类

 public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{ routes.Add(new LegacyRoute("~/articles/Windows_3.1_Overview.html","~/old/.NET_1.0_Class_Library")); routes.MapRoute("myOtherRoute", "App/{action}", new { controller="Home"}); }
}

4.1.自定义Route Handler

实现IRouteHandler接口即可

例子:

   using System;
using System.Web;
using System.Web.Routing;
public class CustomRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new CustomRouteHttpHandler();
} public class CustomRouteHttpHandler : IHttpHandler
{
public bool IsReusable
{
get
{
return false;
}
} public void ProcessRequest(HttpContext context)
{
context.Response.Write("Hello");
}
}
} public class LegacyRoute : RouteBase
{
private string[] urls;
public LegacyRoute(params string[] targetUrls)
{
urls = targetUrls;
} public override RouteData GetRouteData(HttpContextBase httpContext)
{
RouteData result = null;
string requestedURL = httpContext.Request.AppRelativeCurrentExecutionFilePath;
if (urls.Contains(requestedURL, StringComparer.OrdinalIgnoreCase))
{
result = new RouteData(this,new CustomRouteHandler());
result.Values.Add("controller", "Legacy");
result.Values.Add("action", "GetLegacyURL");
result.Values.Add("legacyURL", requestedURL);
}
return result;
} public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}

十二、使用区域

十三、路由请求文件

默认情况下,路由系统先检查一个URL请求是否有相应的文件,如果有直接返回该文件不再根据使用RouteConfig.cs定义的路由,如果没有才根据RouteConfig.cs路由定义的路由进行查找。可以在RouteConfig.cs文件中更改路由的这种默认情况,如下

 public static void RegisterRoutes(RouteCollection routes)
{
routes.RouteExistingFiles = true; routes.MapRoute("default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }); }

为文件设置路由

一旦设置routes.RouteExistingFiles = true后任何对文件的访问请求将会失败,此时我们可以在RouteConfig.cs为文件进行路由定义以相应相关请求,如下:
 public static void RegisterRoutes(RouteCollection routes)
{
routes.RouteExistingFiles = true; routes.MapRoute("DiskFile",
"Content/StaticContent.html",
new { controller = "Customer", action = "List"
}); routes.MapRoute("default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }); }

1、直接访问本地文件,绕过路由系统

        public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("Content/{fileName}.html"); routes.MapRoute("default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }); }

 

 

 
 
 

《精通MVC5.0》路由笔记的更多相关文章

  1. 《精通MVC5.0》笔记Razor

    1.1.视图声明数据类型 Razor声明都是@开始,例如@model MVC.Models.Product声明了控制器创给视图的数据类型,这样就可以在视图使用@Modle.property访问数据,如 ...

  2. vue2.0学习笔记之路由(二)路由嵌套+动画

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. vue2.0学习笔记之路由(二)路由嵌套

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. IoC实践--用Autofac实现MVC5.0的IoC控制反转方法

    Autofac是一个.net平台下发性能还不错的IoC框架,利用它可以实现依赖注入和控制反转,使自己的软件模块之间的耦合性大大降低,让软件扩展.维护更加容易.控制反转(Inversion of Con ...

  5. DirectX 总结和DirectX 9.0 学习笔记

    转自:http://www.cnblogs.com/graphics/archive/2009/11/25/1583682.html DirectX 总结 DDS DirectXDraw Surfac ...

  6. The Implementation of Lua 5.0 阅读笔记(一)

    没想到Lua的作者理论水平这么高,这篇文章读的我顿生高屋建瓴之感.云风分享了一篇中译:http://www.codingnow.com/2000/download/The%20Implementati ...

  7. MvcMovieStore mvc5.0,EF6.01

    MVC 5 实例教程(MvcMovieStore 新概念版:mvc5.0,EF6.01) - 4.创建数据上下文和数据实体模型 说明:MvcMovieStore项目已经发布上线,想了解最新版本功能请登 ...

  8. 一起学ASP.NET Core 2.0学习笔记(二): ef core2.0 及mysql provider 、Fluent API相关配置及迁移

    不得不说微软的技术迭代还是很快的,上了微软的船就得跟着她走下去,前文一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx.superviso ...

  9. vue 2.0 路由切换以及组件缓存源代码重点难点分析

    摘要 关于vue 2.0源代码分析,已经有不少文档分析功能代码段比如watcher,history,vnode等,但没有一个是分析重点难点的,没有一个是分析大命题的,比如执行router.push之后 ...

随机推荐

  1. tomcat作为服务器的配置

    tomcat在启动时,会读取环境变量的信息,需要一个CATALINA_HOME 与JAVA_HOME的信息,CATALINA_HOME即tomcat的主目录,JAVA_HOME即java安装的主目录, ...

  2. metaclass 常用方式

    一个类作为metaclass的时候,我们需要重写它的__new__方法,这个方法的参数包括要创建class object的 metaclass,类名,父类集合,类成员 class MyMetaclas ...

  3. tcpdump高级过滤技巧

    基本语法 ========过滤主机--------- 抓取所有经过 eth1,目的或源地址是 192.168.1.1 的网络数据# tcpdump -i eth1 host 192.168.1.1- ...

  4. [OC] 理解Bitcode:一种中间代码

    Tip:参考资料 理解Bitcode:一种中间代码 (内容从该博客摘录的.本随笔摘录些简要内容.) App Distribution Guide – App Thinning (iOS, watchO ...

  5. 微信小程序-图片、录音、音频播放、音乐播放、视屏、文件

    图片: wx.chooseImage(OBJECT) 从本地相册选择图片或使用相机拍照. OBJECT参数说明: 注:文件的临时路径,在小程序本次启动期间可以正常使用,如需持久保存,需在主动调用 wx ...

  6. rgba()兼容IE8

    CSS: //一般的高级浏览器都支持 background: rgba(255,255,255,0.1); //IE8下 filter:progid:DXImageTransform.Microsof ...

  7. 在ionic/cordova中使用Form模型验证(w5cValidator)

    在构建ionic项目过程中,当我们创建一个类似表单提交的页面时,可能会对用户的输入内容做某些规则验证,通过后再执行提交处理. 在验证的过程中,为了提供较好的用户体验,可能希望有类似于jquery Va ...

  8. HTML <a> download 属性,点击链接来下载图片

    Html5里面的 标签的 Download 属性可以设置一个值来规定下载文件的名称.所允许的值没有限制,浏览器将自动检测正确的文件扩展名并添加到文件 (.img, .pdf, .txt, .html, ...

  9. C# 利用NPOI 实现Excel转html

    public void ExcelToHtml(string fileName, IWorkbook workbook) { ExcelToHtmlConverter excelToHtmlConve ...

  10. springMVC下jsp引用外部js,css等静态资源的解决方法

    直入主题. 1. web.xml对springMVC配置如下: <servlet> <description>Spring MVC配置</description> ...