问题描述
我试图转换this样品RouteBase实施通过以下the例如,在路由项目,但我正在逐渐绊倒如何从该方法返回异步工作
。我真的不关心,如果它实际上是异步的(欢呼的人谁可以提供答案),现在我只想把它发挥作用。
我即将离任的路由功能(即 ActionLink的
当我把在路由值正常工作)。问题是与 RouteAsync
方法。
公共任务RouteAsync(RouteContext上下文)
{
VAR requestPath = context.HttpContext.Request.Path.Value; 如果(string.IsNullOrEmpty(requestPath)及!&放大器; requestPath [0] =='/')
{
//修剪前导斜杠
requestPath = requestPath.Substring(1);
} //获取相匹配的页面。
VAR页= GetPageList()
。凡(X => x.VirtualPath.Equals(requestPath))
.FirstOrDefault(); //如果我们回到一个空值设置,这意味着URI不匹配
如果(页面!= NULL)
{
VAR的RouteData =新的RouteData(); //这不起作用
// VAR的RouteData =新的RouteData(context.RouteData); //这不起作用
//routeData.Routers.Add(this); //这不起作用
//routeData.Routers.Add(new MvcRouteHandler()); // TODO:您可能希望使用页面对象(从数据库)来
//取得两个控制器和动作,甚至可能的区域。
//或者,您可以创建为每个表和硬code路线
// 此信息。
routeData.Values [控制器] =CustomPage;
routeData.Values [行动] =详细信息; //这将是数据库行的主键。
//这可能是一个整数或GUID。
routeData.Values [ID] = page.Id; context.RouteData =的RouteData; //当有匹配,code执行在这里
context.IsHandled = TRUE; //这个测试工作
//等待context.HttpContext.Response.WriteAsync(你好); //这不起作用
//返回Task.FromResult(的RouteData); //这不起作用
//返回Task.FromResult(背景);
} //这满足了return语句,但
//我不知道它是返回正确的事情。
返回Task.FromResult(0);
}
整个方法运行一路过关斩将到最后的时候有一个匹配。但是,当它执行完毕,它不叫详细信息
的 CustomPage
控制器的方法,因为它应该。我只是得到一个空白页面在浏览器。
我添加了 WriteAsync
行是在的并将其写入你好
来的空白页,但我不明白为什么MVC是不是要求我的控制器(以previous版本,这个工作很顺利)。不幸的是,该职位涵盖除了如何实现路由的每一个部分的 IRouter
或 INamedRouter
。
我怎样才能让 RouteAsync
方法函数?
整个CustomRoute实施
使用Microsoft.AspNet.Routing;
使用Microsoft.Framework.Caching.Memory;
使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Threading.Tasks;公共类PageInfo
{
// VirtualPath不应该有一个斜线
//例如:活动/会议/ mycon
公共字符串VirtualPath {搞定;组; }
公众诠释标识{搞定;组; }
}公共接口ICustomRoute:IRouter
{}
公共类CustomRoute:ICustomRoute
{
私人只读IMemoryCache缓存;
私有对象的SyncLock =新的对象(); 公共CustomRoute(IMemoryCache缓存)
{
this.cache =高速缓存;
} 公共任务RouteAsync(RouteContext上下文)
{
VAR requestPath = context.HttpContext.Request.Path.Value; 如果(string.IsNullOrEmpty(requestPath)及!&放大器; requestPath [0] =='/')
{
//修剪前导斜杠
requestPath = requestPath.Substring(1);
} //获取相匹配的页面。
VAR页= GetPageList()
。凡(X => x.VirtualPath.Equals(requestPath))
.FirstOrDefault(); //如果我们回到一个空值设置,这意味着URI不匹配
如果(页面!= NULL)
{
VAR的RouteData =新的RouteData(); // TODO:您可能希望使用页面对象(从数据库)来
//取得两个控制器和动作,甚至可能的区域。
//或者,您可以创建为每个表和硬code路线
// 此信息。
routeData.Values [控制器] =CustomPage;
routeData.Values [行动] =详细信息; //这将是数据库行的主键。
//这可能是一个整数或GUID。
routeData.Values [ID] = page.Id; context.RouteData =的RouteData;
context.IsHandled = TRUE;
} 返回Task.FromResult(0);
} 公共VirtualPathData GetVirtualPath(VirtualPathContext上下文)
{
VirtualPathData结果= NULL;
PageInfo页= NULL; //获取所有缓存中的网页。
变种页= GetPageList(); 如果(TryFindMatch(页,context.Values,走出页))
{
结果=新VirtualPathData(这一点,page.VirtualPath);
context.IsBound = TRUE;
} 返回结果;
} 私人布尔TryFindMatch(IEnumerable的< PageInfo>页,IDictionary的<字符串对象>值,出PageInfo页)
{
页= NULL;
INT ID;
反对idObj;
对象控制器;
对象操作; 如果(!values.TryGetValue(ID,出idObj))
{
返回false;
} ID = Convert.ToInt32(idObj);
values.TryGetValue(控制器,走出控制器);
values.TryGetValue(行动,出于行动); //这里的逻辑应的逻辑在逆
// GetRouteData()。所以,我们匹配相同的控制器,操作和ID。
//如果我们有更多的路由值在那里,我们将采取所有这些
在该步骤期间//考虑。
如果(action.Equals(详细信息)及和放大器; controller.Equals(CustomPage))
{
页=页
。凡(X => x.Id.Equals(ID))
.FirstOrDefault();
如果(页面!= NULL)
{
返回true;
}
}
返回false;
} 私人的IEnumerable< PageInfo> GetPageList()
{
字符串键=__CustomPageList;
IEnumerable的< PageInfo>页; //只允许一个线程poplate数据
如果(!this.cache.TryGetValue(键,出来的网页))
{
锁(为SyncLock)
{
如果(!this.cache.TryGetValue(键,出来的网页))
{
// TODO:从这里数据库中取出PageInfo对象的列表。
页=新的List< PageInfo>()
{
新PageInfo(){ID = 1,VirtualPath =somecategory / somesubcategory /内容1},
新PageInfo(){ID = 2,VirtualPath =somecategory / somesubcategory /内容2},
新PageInfo(){ID = 3,VirtualPath =somecategory / somesubcategory / content3}
}; this.cache.Set(键,页面,
新MemoryCacheEntryOptions()
{
优先级= CacheItemPriority.NeverRemove,
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(15)
});
}
}
} 返回页面;
}
}
CustomRoute DI注册
services.AddTransient< ICustomRoute,CustomRoute>();
MVC路由配置
//添加到MVC的请求管道。
app.UseMvc(路线=>
{
routes.Routes.Add(routes.ServiceProvider.GetService&所述; ICustomRoute>()); routes.MapRoute(
名称:默认,
模板:{控制器= HOME} / {行动=指数} / {?ID}); //取消注释以下行添加路由用于移植的Web API 2控制器。
// routes.MapWebApiRoute(DefaultApi,API / {控制器} / {ID}?);
});
在情况下,重要的我使用 5测试版
, DNX 4.5.1
和 DNX Core 5的
。
As @opiants said, the problem is that you are doing nothing in your RouteAsync
method.
If your intention is to end up calling a controller action method, you could use the following approach than the default MVC routes:
In your case, start by adding an IRouter
as your inner target:
public class CustomRoute : ICustomRoute
{
private readonly IMemoryCache cache;
private readonly IRouter target;
private object synclock = new object();
public CustomRoute(IMemoryCache cache, IRouter target)
{
this.cache = cache;
this.target = target;
}
Then update your startup to set that target as the MvcRouteHandler
, which has already been set as routes.DefaultHandler
:
app.UseMvc(routes =>
{
routes.Routes.Add(
new CustomRoute(routes.ServiceProvider.GetRequiredService<IMemoryCache>(),
routes.DefaultHandler));
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
// Uncomment the following line to add a route for porting Web API 2 controllers.
// routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}");
});
Finally, update your AsyncRoute method to call the inner IRouter
, which would be the MvcRouteHandler
. You can use the implementation of that method in TemplateRoute
as a guide. I have quickly used this approach and modified your method as follows:
public async Task RouteAsync(RouteContext context)
{
var requestPath = context.HttpContext.Request.Path.Value;
if (!string.IsNullOrEmpty(requestPath) && requestPath[0] == '/')
{
// Trim the leading slash
requestPath = requestPath.Substring(1);
}
// Get the page that matches.
var page = GetPageList()
.Where(x => x.VirtualPath.Equals(requestPath))
.FirstOrDefault();
// If we got back a null value set, that means the URI did not match
if (page == null)
{
return;
}
//Invoke MVC controller/action
var oldRouteData = context.RouteData;
var newRouteData = new RouteData(oldRouteData);
newRouteData.Routers.Add(this.target);
// TODO: You might want to use the page object (from the database) to
// get both the controller and action, and possibly even an area.
// Alternatively, you could create a route for each table and hard-code
// this information.
newRouteData.Values["controller"] = "CustomPage";
newRouteData.Values["action"] = "Details";
// This will be the primary key of the database row.
// It might be an integer or a GUID.
newRouteData.Values["id"] = page.Id;
try
{
context.RouteData = newRouteData;
await this.target.RouteAsync(context);
}
finally
{
// Restore the original values to prevent polluting the route data.
if (!context.IsHandled)
{
context.RouteData = oldRouteData;
}
}
}
这篇关于在ASP.NET 5 Imlementing定制IRouter(vNext)MVC 6的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!