Asp.Net MVC<四>:路由器

时间:2023-01-04 07:40:27

ASP.NET的路由系统:路由映射

ASP.NET MVC路由扩展:路由映射

ASP.NET的路由系统:根据路由规则生成URL

ASP.NET MVC 请求流程:Route

http://www.cnblogs.com/zeusro/p/RouteConfig.html

路由的核心类型基本定义于System.Web.dll中,路由机制同样可应用与Web Forms,实现请求地址和物理文件的分离。

web form中使用路由器的示例

路由配置

protected void Application_Start(object sender, EventArgs e)
{
var defaults = new RouteValueDictionary { { "name", "*" }, { "id", "*" } };
//将物理文件路径映射到一个路由模版上
RouteTable.Routes.MapPageRoute("", "employees/{name}/{id}","~/default.aspx",true,defaults);
}

页面

public partial class Default : System.Web.UI.Page
{
protected string EmployeeId;
protected string EmployeeName;
protected void Page_Load(object sender, EventArgs e)
{
EmployeeId = this.RouteData.Values["id"] as string;
EmployeeName = this.RouteData.Values["name"] as string;
}
}
<form id="form1" runat="server">
<div>
EmployeeId:<%=EmployeeId %>
<br/>
EmployeeName:<%=EmployeeName %>
</div>
</form>

测试

访问地址:http://localhost:65042/Default.aspx

Asp.Net MVC<四>:路由器

访问地址:http://localhost:65042/employees

Asp.Net MVC<四>:路由器

访问地址:http://localhost:65042/employees/张飞

Asp.Net MVC<四>:路由器

访问地址:http://localhost:65042/employees/张飞/001

Asp.Net MVC<四>:路由器

访问地址:http://localhost:65042/employees/张飞/001/sdfs

404报错

ASP.NET路由注册

RouteTable.Routes.MapPageRoute(
routeName : "myRoute",
routeUrl : "dirtest/{name}/{id}",
physicalFile : "~/default.aspx",
checkPhysicalUrlAccess : true,
defaults : new RouteValueDictionary { { "name", "*" }, { "id", "010" } },
constraints : new RouteValueDictionary { { "id", @"0\d{2,3}" }, { "httpMethod", new HttpMethodConstraint("GET") } },
dataTokens : new RouteValueDictionary { { "city", "hangzhou" } }
);

另一种注册方式

Route route = new Route(
url:"dirtest/{name}/{id}",
defaults: new RouteValueDictionary { { "name", "*" }, { "id", "010" } },
constraints: new RouteValueDictionary { { "id", @"0\d{2,3}" }, { "httpMethod", new HttpMethodConstraint("GET") } },
dataTokens: new RouteValueDictionary { { "city", "hangzhou" } },
routeHandler:new PageRouteHandler("~/default.aspx",true)
);
RouteTable.Routes.Add("myRoute",route);

直接请求现存的物理文件

借用路由可以采用一个与路径无关的URL访问某个物理文件,但如果就是希望以物理地址的方式访问对应的物理文件时。

RouteBase定义了一个布尔类型的属性RouteExistingFiles,表示是否对现有物理文件实施路由。

注册路由忽略地址

如果设置为RouteTable.Routes.RouteExistingFiles = true; 路由系统会对所有请求实施路由,但这同样会带来一些问题。

例如如果应用运行在集成模式下,则静态资源的请求也会进入ASP.NET管道,于是针对静态文件的请求也可能会被重定向。

通过Ignore方法来添加例外,Ignore方法的调用必需放在路由注册之前。

RouteTable.Routes.RouteExistingFiles = true;
RouteTable.Routes.Ignore("content/{filename}.css/{*pathInfo}");

默认值

defaults 为路由模版中的两个变量指定了默认值。

约束

constraints 可以为变量指定基于正则的约束,也可以指定一个RouteConstraint对象。

路由变量

在Route对象的DataTokens属性中可添加路由变量

根据路由规则生成URL

通过RouteCollection的GetVirtualPath方法。

RequestContext requestContext = new RequestContext();
requestContext.HttpContext = new HttpContextWrapper(HttpContext.Current);
requestContext.RouteData = this.RouteData;
RouteValueDictionary values = new RouteValueDictionary { { "name", "刘备" }, { "id", "013" } };
Response.Write("<br>");
Response.Write(RouteTable.Routes.GetVirtualPath(requestContext, values).VirtualPath);
Response.Write("<br>");
Response.Write(RouteTable.Routes.GetVirtualPath(requestContext, null).VirtualPath);
Response.Write("<br>");
Response.Write(RouteTable.Routes.GetVirtualPath(null, null).VirtualPath);

Asp.Net MVC<四>:路由器

MVC路由

MapPageRoute方法和Ignore方法的调用可以完成针对某个物理文件的路由。返回的RouteData中的RouteHander属性会返回一个PageRouteHandler对象。PageRouteHandler对象最终会创建一个针对映射.aspx文件的Page对象来处理请求。

而MVC为RouteCollection增加了一系列扩展方法,定义在System.Web.Mvc.RouteCollectionExtensions中。新增了两组方法 MapRoute和IgnoreRoute

MapRoute方法的几个重载中都不能直接操作DataTokens,但可以往DataTokens中添加命名空间列表。当存在多个同名的Controller类型时,在激活Controller类型时会因为无法确定Controller的类型而抛出异常。DataTokens中得Namespaces成员用于设置优先级。

MapRoute方法返回的RouteData中的RouteHander属性会返回一个MvcRouteHandler对象。

UrlParameter.Optional

将变量的默认值设置为UrlParameter.Optional,则只有请求URL中真正包含具体变量值的情况下生成的RouteData的Values属性中才会包含相应的路由变量。

基于Area的路由映射

通过Area可以从功能上将应用划分为几个较小的单元。每个Area相当于一个独立的子系统。它们具有一套包含Models,Views,Controllers在内的目录结构和配置文件。每个路由结构一般也会具有各自独立的路由规则,通过AreaRegistration类型进行注册。

protected void Application_Start()
{
//针对所有Area的注册
AreaRegistration.RegisterAllAreas();
}

RegisterAllAreas方法执行时,所有被当前Web应用直接或间接引用的程序集都会被加载(如果尚未被加载),ASP.NET MVC会从中找到所有继承自AreaRegistration的类型,并通过反射创建相应的对象。针对每个被创建出来的AreaRegistration对象,一个作为Area注册上下文的AreaRegistrationContext对象会被创建出来,作为参数调用AreaRegistration对象的RegisterArea方法对相应的Area的路由进行注册。
AreaRegistrationContext对象的State属性的值来自AreaRegistration.RegisterAllAreas方法指定的参数state。

public class adminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "admin";
}
} public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
name: "admin_default",
url: "admin/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

  

当存在相同的Controller类型名时,如域Area中也定义了一个Home控制器,则全局路由器会因为重复匹配而报错。需要对其设置优先匹配的命名空间。

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "WebApplication1.Controllers.*" }
);
}

AreaRegistration注册的路由对象

由AreaRegistration注册的路由对象生成的RouteData的不同之处主要表现在DataTokens属性上,默认多出两个变量:

  1. area:                           标记Area的名称
  2. UseNamespaceFallback: 当MapRoute方法显式地指定了命名空间或者对应的AreaRegistration定义在某个命名空间下,则UseNamespaceFallback为False,反之则被设置为True。如果MapRoute方法显式地指定了命名空间,则AreaRegistration类型所在的命名空间也会被忽略。

MVC中生成URL的快捷方式

MVC则定义了两个帮助类: HtmlHelper 和UrlHelper,通过调用它们的ActionLink/RouteLink 和Action/RouteUrl方法生成Url。从本质上讲,最终依赖于RouteCollection对象的GetVirtualPathData方法。

Action、ActionLink

UrlHelper.Action(……)返回相对地址或绝对地址,HtmlHelper.ActionLink(……) 则不仅仅返回一个Url,而是生成一个链接(<a>……</a>)。

调用的是GetVirtualPathData(RequestContext requestContext,RouteValueDictionary values)方法。 也就是使用路由表中第一个匹配的Route对象来生成URL或者链接。

RouteUrl、RouteLink

UrlHelper.RouteUrl(……)方法和HtmlHelper.RouteLink (……) 方法则可以针对注册的某个具体的Route对象来生成URL或者链接。也即是调用GetVirtualPathData(RequestContext requestContext,string name,RouteValueDictionary values)方法。

特性路由

特性路由是对现有路由系统的扩展,提供了一种针对某个具体Controller类型或Action方法的路由注册方式。从而可以对路由规则进行细粒度的设计。

特性路由(Attribute Route)就是利用标注在Controller类型或Action方法上的特性来提供路由规则的路由注册方式

注册

默认情况下特性路由功能是关闭的,需要调用RouteCollection的扩展方法MapMvcAttributeRoutes来开启。

这个方法的调用要放在路由注册之前。

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); RouteTable.Routes.MapMvcAttributeRoutes(); routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
public class MoviesController : Controller
{
// GET: Movies
public ActionResult Index()
{
return View();
}
[HttpGet]
[Route("movies/{id}")]
public ActionResult GetMoviesById(string id)
{
ViewBag.id = id;
return View();
}
[HttpGet]
[Route("movies/starring/{starring}")]
[Route("movies/starring/{starring}/{genre}")]
[Route("movies/director/{director}/{genre}")]
public ActionResult FindMovies(string starring, string director, string genre)
{
ViewBag.starring = starring;
ViewBag.director = director;
ViewBag.genre = genre;
return View();
}
}

  

默认情况下使用特性类型RouteAttribute,它实现了接口IRouteInfoProvider。

Asp.Net MVC<四>:路由器

当使用RouteAttribute时,需要提供一个路由模版来对Template这个只读属性进行初始化。而如果需要用这个路由特性注册的路由对象来生成URL,还需要为它提供一个Name,以便可以从路由表中把它提取出来。

为特性路由的变量添加约束

路由变量基本都会直接绑定到目标Action方法相应的参数上,由于这些变量值在请求URL中以字符串的形式体现,所以被绑定参数必需支持源自字符串的类型转换。

为了确保参数绑定的正常进行,需要对路由变量在数据类型上进行约束。这些约束可以直接以内联的形式定义在路由模版里。

[HttpGet]
[Route("movies/{id:range(20,50)}")]
public ActionResult GetMoviesById(int id)

对于路由系统来说,约束通过RouteContraint对象来表示,所有RouteContraint类型均实现了IRouteContraint接口。

特性路由的这些以内联形式定义在路由模版中的约束,它们的约束类型也是实现了IRouteContraint接口。

系统提供的约束
约束 描述 用法 类型
bool 类型匹配 (布尔类型) {x:bool} BoolRouteContraint
datetime 类型匹配 (DateTime类型) {x:datetime} DateTimeRouteContraint
decimal 类型匹配 (Decimal类型) {x:decimal} DecimalRouteContraint
double 类型匹配 (Double类型) {x:double} DoubleRouteContraint
float 类型匹配 (Float类型) {x:float} FloatRouteContraint
guid 类型匹配 (Guid类型) {x:guid} GuidRouteContraint
int 类型匹配 (32位整数) {x:int} IntRouteContraint
long 类型匹配 (64位整数) {x:long} LongRouteContraint
alpha 字符组成(必须有拉丁字母组成) {x:alpha} AlphaRouteContraint
regex 字符组成(必须与指定的正则匹配) {x:regex(^\d{3}-\d{3}-\d{4}$)} RegexRouteContraint
max 值范围(小于或等于指定的最大值) {x:max(20)} MaxRouteContraint
min 值范围(大于或等于指定的最小值) {x:max(20)} MinRouteContraint
range 值范围(在指定的最大值和最小值之间) {x:range(20,50)} RangeRouteContraint
maxlength 字符串长度(小于或等于指定的最大长度) {x:maxlength(20)} MaxLengthRouteContraint
minlength 字符串长度(大于或等于指定的最小长度) {x:minlength(20)} MinlengthRouteContraint
length 字符串长度(等于指定的长度或者在指定的范围内) {x:length(6)} LengthRouteContraint

为路由变量设置缺省值

1.将对应的参数定义为可缺省参数,路由模版里使用“?”

[HttpGet]
[Route("movies/language/{language?}")]
public ActionResult GetMoviesByLanguage(string language = "en")
{
return View();
}

2.将默认值定义在路由模版中

[HttpGet]
[Route("movies/language/{language=en}")]
public ActionResult GetMoviesByLanguage(string language)
{
return View();
}

设置模版前缀

使用RoutePrefixAttribute类型的特性,它只有一个只读属性Prefix,表示目标Controller所有Action方法共享的URL前缀。这个属性只能应用在Controller类型上,且只能有一个。

Asp.Net MVC<四>:路由器

[RoutePrefix("movies")]
public class MoviesController : Controller
{
[HttpGet]
[Route("{id:range(20,50)}")]
public ActionResult GetMoviesById(int id)
{
ViewBag.id = id;
return View();
}
[HttpGet]
[Route("starring/{starring}")]
[Route("starring/{starring}/{genre}")]
[Route("director/{director}/{genre}")]
public ActionResult FindMovies(string starring, string director, string genre)
{
ViewBag.starring = starring;
ViewBag.director = director;
ViewBag.genre = genre;
return View();
} [HttpGet]
[Route("~/actors/{criteria}")] //使用“~”为前缀,屏蔽掉Controller类型上的前缀“movies”
public ActionResult FindActors(string criteria)
{
return View();
}
}

设置Area名

使用RouteAreaAttribute类型的特性,它由两个属性AreaName和AreaPrefix,默认情况下使用AreaName做模版前缀,如果希望具有一个不同于Area名称的前缀,则要通过设置AreaPrefix属性来实现。

如果没有使用字符“~”前缀,特性路由的完整格式为{AreaPrefix}/{RoutePrefix}/{Template} 或者{AreaName}/{RoutePrefix}/{Template} 。

Asp.Net MVC<四>:路由器

[RouteArea("MoviesArea")]//[RouteArea()]
[RoutePrefix("movies")]
public class MoviesController : Controller
{
[HttpGet]
[Route("{id:range(20,50)}")]
public ActionResult GetMoviesById(int id)
{
ViewBag.id = id;
return View();
}
[HttpGet]
[Route("starring/{starring}")]
[Route("starring/{starring}/{genre}")]
[Route("director/{director}/{genre}")]
public ActionResult FindMovies(string starring, string director, string genre)
{
ViewBag.starring = starring;
ViewBag.director = director;
ViewBag.genre = genre;
return View();
} [HttpGet]
[Route("~/admin/actors/{criteria}")] //使用“~”为前缀,屏蔽掉Controller类型上的前缀“movies”
public ActionResult FindActors(string criteria)
{
return View();
}
}

直接应用到Controller上的RouteAttribute

[RouteArea("vedio")]
[RoutePrefix("movies")]
[Route("{action}/{id}", Name = "FindMovies")]
public class MoviesController : Controller
{
public ActionResult Index(string id)
{
throw new NotImplementedException();
}
}

自定义约束

内联表达式约束的解析

约束是以内联表达式的形式定义在路由模版里的,ASP.NET MVC通过一个实现IInlineConstraintResolver接口的对象来完成约束从字符串表达式到RouteConstraint对象之间的转换。

系统提供的这个解析类型是DefaultInlineConstraintResolver。

public class MyInlineConstraintResolver : IInlineConstraintResolver
{
public IDictionary<string, Type> ConstraintMap { get; private set; }
public MyInlineConstraintResolver()
{
this.ConstraintMap = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
this.ConstraintMap.Add("bool", typeof(BoolRouteConstraint));
this.ConstraintMap.Add("datetime", typeof(DateTimeRouteConstraint));
this.ConstraintMap.Add("decimal", typeof(DecimalRouteConstraint));
this.ConstraintMap.Add("double", typeof(DoubleRouteConstraint));
this.ConstraintMap.Add("float", typeof(FloatRouteConstraint));
this.ConstraintMap.Add("guid", typeof(GuidRouteConstraint));
this.ConstraintMap.Add("int", typeof(IntRouteConstraint));
this.ConstraintMap.Add("long", typeof(LongRouteConstraint));
this.ConstraintMap.Add("minlength",typeof(MinLengthRouteConstraint));
this.ConstraintMap.Add("maxlength",typeof(MaxLengthRouteConstraint));
this.ConstraintMap.Add("length", typeof(LengthRouteConstraint));
this.ConstraintMap.Add("min", typeof(MinRouteConstraint));
this.ConstraintMap.Add("max", typeof(MaxRouteConstraint));
this.ConstraintMap.Add("range", typeof(RangeRouteConstraint));
this.ConstraintMap.Add("alpha", typeof(AlphaRouteConstraint));
this.ConstraintMap.Add("regex", typeof(RegexRouteConstraint));
} public IRouteConstraint ResolveConstraint(string inlineConstraint)
{
string[] split = inlineConstraint.Split('(');
string type = split[0];
string argumentList = split.Length > 1 ? split[1].Trim().TrimEnd(')') : "";
Type constraintType;
if (this.ConstraintMap.TryGetValue(type, out constraintType))
{
split = string.IsNullOrEmpty(argumentList)? new string[0] : argumentList.Split(',');
ConstructorInfo[] constructors =(from c in constraintType.GetConstructors()
where c.GetParameters().Count() == split.Length
select c).ToArray();
if (constructors.Length != 1)
{
throw new InvalidOperationException("找不到与指定参数匹配的构造函数");
}
ConstructorInfo constructor = constructors[0];
ParameterInfo[] parameters = constructor.GetParameters();
object[] arguments = new object[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
arguments[i] = Convert.ChangeType(split[i],parameters[i].ParameterType);
}
return (IRouteConstraint)constructor.Invoke(arguments);
}
return null;
}
}
static void Main(string[] args)
{
string[] inlineConstraints = new string[]{
"bool","datetime", "decimal","double","float","guid","int",
"long","alpha", @"regex(^\d{3}-\d{7}$)","max(50)","min(10)","range(10,50)","maxlength(50)","minlength(10)","length(10,50)"};
MyInlineConstraintResolver constraintResolver = new MyInlineConstraintResolver();
IDictionary<string, IRouteConstraint> constraints = inlineConstraints.ToDictionary(inlineConstraint => inlineConstraint, inlineConstraint => constraintResolver.ResolveConstraint(inlineConstraint));
Console.WriteLine("{0,-24}{1}", "Expression", "RouteConstraint");
foreach (var item in constraints)
{
Console.WriteLine("{0,-24}{1}", item.Key,
item.Value.GetType().Name);
} Console.ReadKey();
}

自定义针对Culture的约束

约束类型的定义

public class CultureRouteConstraint : IRouteConstraint
{
private static IList<string> allCultures;
static CultureRouteConstraint()
{
allCultures = CultureInfo.GetCultures(CultureTypes.AllCultures).Select(culture => culture.Name).ToList();
} public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
object culture;
if (values.TryGetValue(parameterName, out culture))
{
return allCultures.Any(c => string.Compare(c, culture.ToString(),true) == 0);
}
return false;
}
}

应用自定义的约束

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); DefaultInlineConstraintResolver constraintResolver = new DefaultInlineConstraintResolver();
constraintResolver.ConstraintMap.Add("culture", typeof(CultureRouteConstraint));
routes.MapMvcAttributeRoutes(constraintResolver); //其他操作
}

使用  

public class ResourcesController : Controller
{
[Route("resources/{name}/{culture:culture=zh-cn}")]
public string GetString(string name, string culture)
{
CultureInfo currentUICulture = CultureInfo.CurrentUICulture;
CultureInfo currentCulture = CultureInfo.CurrentCulture;
try
{
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
return Resources.ResourceManager.GetString(name.ToLower());
}
finally
{
Thread.CurrentThread.CurrentUICulture = currentUICulture;
Thread.CurrentThread.CurrentCulture = currentCulture;
}
}
}

特性路由注册的路由对象

路由对象的创建

特性路由主要涉及3种类型的特性:

  1. 以RouteAttribute为代表的RouteInfoProvider特性
  2. 设置路由模版前缀的RoutePrefixAttribute特性
  3. 设置所在Area名称的RouteAreaAttribute特性

针对应用到Controller和Action上的这些特性,ASP.NET MVC的路由系统最终会为之创建相应的路由对象(VS调试中发现RouteTable细节上有了一些变化,下面的部分描述不对了)。

  1. 特性路由的路由模版经过格式化(拼接前缀、去除约束、默认值、“?”等)后转换为路由对象的模版。
  2. 路由模版中的变量约束及[HttpGet] 被解析后添加到路由对象的Contraint属性表示的约束集合中。
  3. 路由模版中的变量默认值及目标Controller和Action名称保存到Defaults属性中。
  4. 如果RouteAttribute是加在Action上的,则DataTokens属性中具有一个名为“TargetActionMethod”的成员,它的值代表目标Action方法的MethodInfo对象。
  5. 如果RouteAttribute是加在Controller上的,则DataTokens属性中具有一个名为“MS_DirectControllerRoute”的成员,它的值为描述目标Controller类型的ControllerDescriptor对象。
  6. RouteAreaAttribute特性除了改变最终的路由模版外,还会在DataTokens属性中额外添加两个成员:“Namespaces”、“UseNamespaceFallback”。

当我们调用MapMvcAttributeRoutes方法时,ASP.NET MVC 会提取注册到当前DependencyResolver上的用于激活目标Controllerde的ControllerFactory,如果没有没有对ControllerFactory进行显式注册或者显式注册的并不是一个DefaultControllerFactory对象,它会创建一个DefaultControllerFactory对象。这个DefaultControllerFactory对象会解析出所有合法有效的Controller类型,并对它们实施缓存。ASP.NET MVC 利用它得到所有合法有效的Controller类型后,针对每个类型得到对应的ControllerDescriptor对象(默认通过AsyncControllerActionInvoker对象获得,后者会缓存Controller类型与对应的ControllerDescriptor之间的映射关系以避免ControllerDescriptor的频繁创建)。

在得到所有Controller类型的ControllerDescriptor对象后,会遍历描述Action方法的每个ActionDescriptor对象,并利用它提取应用在对应Action方法上的RouteInfoProvider特性。利用这个RouteInfoProvider特性及所在Controller类型上应用的RoutePrefixAttribute和RouteAreaAttribute特性提供的路由规则创建最终的Route对象。这个对象最终被添加到全局路由表中。

被特性路由标记的Controller、Action在特性路由功能开启后, 将不能再通过普通路由对象的Url模版来访问

public class HomeController : Controller
{
[Route("movies")] //不能再通过home/about访问
public ActionResult About()
{
return View();
}
}

Controller的激活和Action方法的选择

因为路由对象的属性DataTokens中的成员在路由解析匹配成功时,会直接拷贝到解析生成的RouteData的DataTokens属性中。

DefaultControllerFactory在激活目标Controller实例前必须先解析出目标Controller的类型。在正常情况下,它会根据路由解析得到的Controller名称来匹配。但是如果它能够从RouteData中提取到描述目标Controller的ControllerDescriptor或者描述目标Action方法的MethodInfo对象,就可以根据它们直接得到Controller类型。

ControllerDescriptor内的FindAction方法可以根据提供的ControllerContext从候选的Action方法中选择与当前请求匹配度最高的那一个。对于默认使用的ReflectedControllerDescriptor来说,当FindAction方法被执行时,它会先从提供的ControllerContext中提取RouteData对象,如果能够从中获取描述目标Action方法的MethodInfo对象,返回得ActionDescriptor对象会直接依据此MethodInfo对象来创建。

public interface IControllerFactory
{
IController CreateController(RequestContext requestContext, string controllerName); SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName); void ReleaseController(IController controller);
} public abstract class ControllerDescriptor : ICustomAttributeProvider, IUniquelyIdentifiable
{
protected ControllerDescriptor(); public virtual string ControllerName { get; } public abstract Type ControllerType { get; } public virtual string UniqueId { get; } public abstract ActionDescriptor FindAction(ControllerContext controllerContext, string actionName); public abstract ActionDescriptor[] GetCanonicalActions(); public virtual object[] GetCustomAttributes(bool inherit); public virtual object[] GetCustomAttributes(Type attributeType, bool inherit); public virtual IEnumerable<FilterAttribute> GetFilterAttributes(bool useCache); public virtual bool IsDefined(Type attributeType, bool inherit);
}
public abstract class ActionDescriptor : ICustomAttributeProvider, IUniquelyIdentifiable
{
protected ActionDescriptor(); public abstract string ActionName { get; } public abstract ControllerDescriptor ControllerDescriptor { get; } public virtual string UniqueId { get; } public abstract object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters); public virtual object[] GetCustomAttributes(bool inherit); public virtual object[] GetCustomAttributes(Type attributeType, bool inherit); [EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Please call System.Web.Mvc.FilterProviders.Providers.GetFilters() now.", true)]
public virtual FilterInfo GetFilters(); public abstract ParameterDescriptor[] GetParameters(); public virtual ICollection<ActionSelector> GetSelectors(); public virtual bool IsDefined(Type attributeType, bool inherit);
}

  

Asp.Net MVC<四>:路由器的更多相关文章

  1. 七天学会ASP&period;NET MVC &lpar;四&rpar;——用户授权认证问题

    小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在第四天的学习中,我们主要了学习如何在MVC中如何实现认证授权等问题,本节主要讲了验证错误时的错误值,客户端验 ...

  2. 七天学会ASP&period;NET MVC &lpar;四&rpar;——用户授权认证问题 【转】

    http://www.cnblogs.com/powertoolsteam/p/MVC_four.html 小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在 ...

  3. &period;NET、C&num;和ASP&period;NET,ASP&period;NET MVC 四者之间的区别

    经常,会有一些人搞不清楚.NET和c#和ASP.NET这三者之间的关系,她们都是什么呢?他们之间有什么关系呢?总结一下 首先:什么是.NET? .NET是微软公司下的一个开发平台,.NET核心就是.N ...

  4. 学习ASP&period;NET MVC&lpar;四&rpar;——我的第一个ASP&period;NET MVC 实体对象

    今天我将根据数据库中的表结构添加一些类.这些类将成为这个ASP.NET MVC应用程序中“模型”的一部分.       我们使用Entity Framework(实体框架)来定义和使用这些模型类,并且 ...

  5. &period;NET、C&num;和ASP&period;NET、ASP&period;NET MVC四者之间的区别

    什么是.NET? .NET是微软公司下的一个开发平台,.NET核心就是.NET Framwork(.NET框架)是.NET程序开发和运行的环境,在这个平台下可以用不同的语言进行开发,因为.NET是跨语 ...

  6. ASP&period;NET MVC 四种传值方法

    1.后台传值: public class DataController : Controller { // GET: Data public ActionResult Index() { //1 Vi ...

  7. ASP&period;NET MVC 四种Controller向View传值方法

    控制器: // Get: Data public ActionResult Index() { //ViewData 方式 ViewData["UserName"] = &quot ...

  8. 七天学会ASP&period;NET MVC &lpar;四&rpar;——Layout页面使用和用户角色管理 (代码下载)

    中文翻译链接: http://www.cnblogs.com/powertoolsteam/p/MVC_four.html 360云盘: https://yunpan.cn/cYuEeLtXUvrgC ...

  9. Asp&period;Net MVC :路由器

    特性路由 特性路由是对现有路由系统的扩展,提供了一种针对某个具体Controller类型或Action方法的路由注册方式.从而可以对路由规则进行细粒度的设计. 特性路由(Attribute Route ...

随机推荐

  1. wpf 遮住输入法 问题

    可以参考这个代码   http://www.cnblogs.com/Leaco/p/3164394.html 当你发现没用的时候 可以改这句代码  var hwnd = ((HwndSource)Pr ...

  2. mysql查询表的数据大小

    在需要备份数据库里面的数据时,我们需要知道数据库占用了多少磁盘大小,可以通过一些sql语句查询到整个数据库的容量,也可以单独查看表所占容量. 1.要查询表所占的容量,就是把表的数据和索引加起来就可以了 ...

  3. PowerMockito&lpar;PowerMock用法&rpar;

    网络上大部分是powermock 的用法, PowerMock有两个重要的注解: –@RunWith(PowerMockRunner.class) –@PrepareForTest( { YourCl ...

  4. 不一样的风格,C&num;的lambda表达式

    下面贴出代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using S ...

  5. 区域、模板页与WebAPI初步

    区域.模板页与WebAPI初步 一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域( ...

  6. 第三章 jQuery中的事件与动画

    第三章jQuery中的事件与动画 一. jQuery中的事件 jQuery事件是对javaScript事件的封装. 1.基础事件 在javaScript中,常用的基础事件有鼠标事件.键盘事件.wind ...

  7. Lodop 打印控件

    1.下载 2.使用 一 下载安装控件 官网下载地址:http://www.lodop.net/download.html 参考:http://www.c-lodop.com/demolist/Prin ...

  8. 8 Ways to Become a Better Coder

    It’s time to get serious about improving your programming skills. Let’s do it! That’s an easy career ...

  9. Django popup示例

    urls.py urlpatterns = [ url('popup_test1',views.popup_test1), url('popup_test2',views.popup_test2), ...

  10. 【贪心】【字典树】Gym - 101466A - Gaby And Addition

    题意:定义一种无进位加法运算,给你n个正整数,问你取出两个数,使得他们加起来和最大/最小是多少. 无进位加法运算,其实是一种位运算,跟最大xor那个套路类似,很容易写出对于每个数字,其对应的最优数字是 ...