如果您想了解asp.net–使用“async”(即使它应该完成)作为MVC路由的一部分使路由死锁;怎么可以避免呢?的相关知识,那么本文是一篇不可错过的文章,我们将为您提供关于ASP.NetMVCC#中
如果您想了解asp.net – 使用“async”(即使它应该完成)作为MVC路由的一部分使路由死锁;怎么可以避免呢?的相关知识,那么本文是一篇不可错过的文章,我们将为您提供关于ASP .Net MVCC# 中默认路由的三个部分是什么?、ASP.NET Core中使用默认MVC路由的配置、ASP.NET MVC路由扩展:路由映射、ASP.NET MVC路由的无限URL参数的有价值的信息。
本文目录一览:- asp.net – 使用“async”(即使它应该完成)作为MVC路由的一部分使路由死锁;怎么可以避免呢?
- ASP .Net MVCC# 中默认路由的三个部分是什么?
- ASP.NET Core中使用默认MVC路由的配置
- ASP.NET MVC路由扩展:路由映射
- ASP.NET MVC路由的无限URL参数
asp.net – 使用“async”(即使它应该完成)作为MVC路由的一部分使路由死锁;怎么可以避免呢?
public ActionResult Index() { var task = SlowDouble(10); string result; if (task.Wait(2000)) { result = task.Result.ToString(); } else { result = "timeout"; } ViewBag.Message = result; return View(); } internal static Task<long> SlowDouble(long val) { taskcompletionsource<long> result = new taskcompletionsource<long>(); ThreadPool.QueueUserWorkItem(delegate { Thread.Sleep(50); result.SetResult(val * 2); }); return result.Task; }
然而,现在如果我们在混合中添加一些异步:
public static async Task<long> IndirectSlowDouble(long val) { long result = await SlowDouble(val); return result; }
并将路由中的第一行更改为:
var task = IndirectSlowDouble(10);
那么它不行;它代替了。如果我们添加断点,返回结果;在异步方法中只有在路由已经完成之后才会发生,基本上看起来系统不愿意使用任何线程恢复异步操作,直到请求完成。更糟:如果我们使用了.Wait()(或访问.Result),那么它将完全死锁。
那是什么呢?明显的解决方法是“不要异步”,但是在使用库时并不容易。最后,SlowDouble和IndirectSlowDouble之间没有任何功能上的区别(尽管有明显的结构差异)。
注意:在控制台/ winform / etc中完全相同的东西可以正常工作。
解决方法
Task.WaitAll hanging with multiple awaitable tasks in ASP.NET
Asp.net SynchronizationContext locks HttpApplication for async continuations?
在ASP.NET 4.5中,本文介绍了同步上下文的一个新实现。
http://blogs.msdn.com/b/webdev/archive/2012/11/19/all-about-httpruntime-targetframework.aspx
ASP .Net MVCC# 中默认路由的三个部分是什么?
ASP.Net MVC 路由模块负责映射传入的浏览器 对特定 MVC 控制器操作的请求。当 ASP.NET MVC 应用程序 启动,然后应用程序向框架注册一个或多个模式 路由表告诉路由引擎如何处理与这些匹配的任何请求 模式。当路由引擎在运行时收到请求时,它会匹配该请求 请求的 URL 与注册的 URL 模式相对应并给出响应 根据模式匹配。
ASP.NET 引入了路由来消除将每个 URL 映射到一个 物理文件。路由使我们能够定义映射到请求的 URL 模式 处理程序。 System.Web.Routing 由 MVC 框架使用,但也被 ASP.NET 动态数据。 MVC 框架利用路由来引导请求 到控制器。 Global.asax 文件是我们应用程序的一部分,我们将在其中 定义我们的应用程序的路由。
下面是 mvc 应用程序的路由配置 -
public class RouteConfig{ 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 } ); } }
路由名称
路由是映射到处理程序的 URL 模式。处理程序可以是控制器 处理请求的 MVC 应用程序。路线名称可以用作 对给定路由的具体引用。
约束
针对 URL 模式应用的一组约束,以更狭义地定义 它匹配的 URL。
URL 模式
URL 模式可以包含文字值和变量占位符。文字和 占位符位于 URL 中由斜杠 (/) 分隔的部分中 字符。
当发出请求时,URL 被解析为段和占位符,并且 变量值被提供给请求处理程序。这个过程类似于 查询字符串中的数据被解析并传递给请求处理程序。在这两种情况下 变量信息包含在 URL 中并以以下形式传递给处理程序 键值对。对于查询字符串,键和值都在 URL 中。为了 路由,键是 URL 模式中定义的占位符名称,并且只有 值位于 URL 中。
默认值
当我们定义路由时,可以为参数分配默认值。默认值是 包含默认路由值的对象。默认路由的三段 包含控制器、操作和 ID。
在上面的URL中,将匹配相应的控制器和操作。如果我们是 不发送 URL 中的控制器和操作方法并基于默认值 路由相应的控制器操作方法将被调用。
以上就是ASP .Net MVCC# 中默认路由的三个部分是什么?的详细内容,更多请关注php中文网其它相关文章!
ASP.NET Core中使用默认MVC路由的配置
ASP.NET Core里Route这块的改动不大,只是一些用法上有了调整,提供了一些更加简洁的语法。
而对于自定义路由的支持当然也是没有问题的,这个功能应该是从MVC1.0版本就已经有这个功能。
先看看ASP.NET Core里面实现默认MVC路由的配置方式
通常情况下,在使用MVC项目的时候,默认的路由就足够了,就是常见的通过Controller和Action获取具体的方法的方式。
从一个最基本的项目开始,执行以下步骤,就可以使得项目支持MVC路由
1.创建一个空白的ASP.NET Core(Empty) Web项目
2.打开project.json,在”dependencies”节点下增加如下依赖项目
"Microsoft.AspNetCore.Mvc": "1.0.0"
保存之后,项目会自动restore packages到本地
3.加入默认MVC路由配置
打开Startup.cs文件
在ConfigureServices方法,加入如下代码
services.AddMvc();
这个扩展方法把Mvc的一些服务都注入到容器中
在Configure方法,注释最后兜底的那个“hello world”语句,这个语句的作用是不管什么请求都它来负责。
然后在Configure方法加入如下代码
app.UseMvcWithDefaultRoute();
这个扩展方法实际上使用了一个Middleware,默认的Url template跟之前MVC版本的一致,上述代码等同于以下效果
app.UseMvc(routes => { routes.MapRoute( name: "Default", template: "{controller}/{action}/{id?}", defaults: new {controller = "Home", action = "Index"} ); });
最终的Startup.cs代码如下
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } //app.Run(async (context) => //{ // await context.Response.WriteAsync("Hello World!"); //}); app.UseMvcWithDefaultRoute(); } }
4.到此配置已经完成,但是运行站点直接显示404,没显示Hello world说明已经生效了,只是Empty的项目没有Controller,那么定义一个Controller吧。
手动在项目根目录创建Controllers目录,然后新建一个Controller,名字为HomeController,然后直接运行网站(应该刷新一下就可以了)。
站点继续提示错误,但不是404了,是提示找不到Index这个View。
继续在项目根目录创建Views目录,然后在Views目录下新建一个Home目录,在Home目录新建一个Index.cshtml,填写一些内容,再次刷新就可以了。
当然这是最基本的配置,比如要进一步支持在cshtml里面实现智能感知,支持静态文件路由等还得加入更多的依赖和配置。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
- ASP.NET Core中MVC模式实现路由二
- ASP.NET Core中MVC模式实现路由一
- ASP.NET Core MVC学习教程之路由(Routing)
- 详解ASP.NET Core MVC 源码学习:Routing 路由
- ASP.NET Core MVC 配置全局路由前缀
- ASP.NET Core MVC路由(Routing)的用法
ASP.NET MVC路由扩展:路由映射
上周我写了三篇文章(一、二、三)详细地介绍了ASP.NET的路由系统。ASP.NET的路由系统旨在通过注册URL模板与物理文件之间的映射进而实现请求地址与文件路径之间的分离,但是对于ASP.NET MVC应用来说,请求的目标不再是一个具体的物理文件,而是定义在某个Controller类型中的Action方法。出于自身路由特点的需要,ASP.NET对ASP.NET的路由系统进行了相应的扩展。
目录
一、基本路由映射
二、实例演示:注册路由映射与查看路由信息
三、基于Area的路由映射
1、AreaRegistration与AreaRegistrationContext
2、AreaRegistration的缓存
3、实例演示:查看基于Area路由信息
一、基本路由映射
通过前面的介绍我们知道基于某个物理文件的路由映射通过调用代表全局路由表的RouteTable的静态属性Routes(一个RouteCollection对象)的MapPageRoute方法来完成,为了实现针对目标Controller和Action的路由,ASP.NET MVC针对RouteCollection类型定义了一系列的扩展方法以实现文件路径无关的路由映射,这些扩展方法定义在RouteCollectionExtensions类型中。如下面的代码片断所示,RouteCollectionExtensions定义了两组方法,方法IgnoreRoute用于注册不需要进行路由的URL模板,对应于RouteCollectionExtensions的Ignore方法;仿佛MapRoute用于进行基于URL模板的路由注册,对应于RouteCollectionExtensions的MapPageRoute方法。
1: public static class RouteCollectionExtensions
2: {
3: //其他成员
4: public static void IgnoreRoute(this RouteCollection routes, string url);
5: public static void IgnoreRoute(this RouteCollection routes, string url, object constraints);
6:
7: public static Route MapRoute(this RouteCollection routes, string name, string url);
8: public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults);
9: public static Route MapRoute(this RouteCollection routes, string name, string url, string[] namespaces);
10: public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints);
11: public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces);
12: public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces);
13: }
由于ASP.NET MVC的路由注册与具体的物理文件无关,所以MapRoute方法中并没有一个表示文件路径的physicalFile参数。与直接定义在RouteCollectionExtensions中的Ignore和MapPageRoute方法不同的是,表示默认变量的参数defaults和基于正则表达式的变量约束的参数constraints都不再是一个RouteValueDictionary对象,而是一个普通的object。这主要是为了编程上的便利,使得我们可以通过匿名类型的方式来指定这两个参数值。该方法在内部会通过反射的方式得到指定对象所有属性值,并转换为RouteValueDictionary对象,其属性名和属性值作为字典元素的Key和Value。
对于ASP.NET MVC来说,最终需要通过在请求地址中指定的Controller名称来创建具体的Controller实例。由于Controller名称 仅仅对应着类型的名称,Controller的成功实例化的前提是我们能够正确地解析出它的具体类型,所以我们需要使用了命名空间。在调用MapRoute方法的时候我们可以通过字符串数组类型的参数namespaces来指定一个命名空间的列表。对于注册的命名空间,可以指定一个代表完整命名空间的字符串,也可以使用“*”作为通配符。
添加的命名控件列表最终是被存储于Route对象的DataTokens属性中,对应的Key为“Namespaces”。MapRoute方法没有为初始化Route对象的DataTokens属性提供相应的参数,如果没有指定命名空间列表,所有通过该方法添加的Route对象的DataTokens属性总是一个空的RouteValueDictionary对象。
对于针对定义在某个Controller中的某个Action的请求,如果注册的路由表与之匹配,具体匹配的某个路由对象的GetRouteData被调用并返回一个具体的RouteData对象。根据对请求地址进行解析得到的目标Controller和Action的名称必须包含在该RouteData的Values属性对应的RouteValueDictionary对象中,其对应的Key分别为controller和action。
二、 实例演示:注册路由映射与查看路由信息
ASP.NET MVC通过定义在RouteCollectionExtensions中的扩展方法MapRoute进行路由映射,为了让读者对此有一个深刻的认识,我们来进行一个简单的实例演示。我们依然沿用之前关于获取天气信息的场景,看看通过这种方式进行注册的Route对象针对匹配的HTTP请求返回怎样的RouteData对象。[源代码从这里下载]
我们在创建的ASP.NET Web应用(不是ASP.NET MVC应用)添加一个Web页面(Default.aspx),并按照之前的方式以内联代码的方式直接将RouteData的相关属性显示出来,页面主体部分的HTML如下所示。需要注意的是我们显示的RouteData是从定义的方法GetRouteData方法获取的,而不是对应于当前页面的RouteData属性。
1: <body>
2: <form id="form1" runat="server">
3: <div>
4: <table>
5: <tr>
6: <td>Route:</td>
7: <td><%=GetRouteData().Route != null? GetRouteData().Route.GetType().FullName:"" %></td>
8: </tr>
9: <tr>
10: <td>RouteHandler:</td>
11: <td><%=GetRouteData().RouteHandler != null? GetRouteData().RouteHandler.GetType().FullName:"" %></td>
12: </tr>
13: <tr>
14: <td>Values:</td>
15: <td>
16: <ul>
17: <%foreach (var variable in GetRouteData().Values)
18: {%>
19: <li><%=variable.Key%>=<%=variable.Value%></li>
20: <% }%>
21: </ul>
22: </td>
23: </tr>
24: <tr>
25: <td>DataTokens:</td>
26: <td>
27: <ul>
28: <%foreach (var variable in GetRouteData().DataTokens)
29: {%>
30: <li><%=variable.Key%>=<%=variable.Value%></li>
31: <% }%>
32: </ul>
33: </td>
34: </tr>
35: </table>
36: </div>
37: </form>
38: </body>