Kev*_*izz 11 asp.net-mvc asp.net-mvc-routing url-redirection asp.net-core-mvc asp.net-core
我正在用ASP.Net Core和MVC 6重写我的FragSwapper.com网站(目前在Asp 2.0中!),我正在尝试做一些我通常需要打破URL重写工具和db代码的东西和一些重定向,但我想知道是否有一个"更好"的方法在ASP.Net核心可能与MVC路由和重定向.
这是我的场景......
URL访问网站:[root]
怎么做:转到通常的[Home] Controller和[Index] View(没有[ID]).......它现在这样做:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
Run Code Online (Sandbox Code Playgroud)URL访问该站点:[root]/ControllerName/... yada yada ...
怎么做:转到控制器等...这一切都有效.
棘手的一个:URL访问网站:[root]/SomeString
怎么做:访问数据库并做一些逻辑来决定我是否找到了一个事件ID.如果我这样做,我会转到[事件]控制器和[索引]视图和我找到的任何[ID].如果不是,我尝试找到主机ID并转到[Home] Controller和[Organization] View with THAT [ID]我找到了.如果我没有找到并且事件或主机转到通常的[Home] Controller和[Index] View(没有[ID]).
这里的大问题是我想在2个不同的控制器中重定向到三个完全不同的视图之一.
所以底线是我想在用户访问我网站的根目录时做一些逻辑,并且在其上有一个"/ Something",并且该逻辑是数据库驱动的.
如果您理解了这个问题,您现在就可以停止阅读......如果您觉得需要理解为什么需要所有这些逻辑,您可以继续阅读以获取更详细的背景信息.
我的网站基本上有两种模式:查看事件而不查看事件!通常一次运行4或5个事件,但大多数用户只对一个事件感兴趣,但每4个月左右就会发生一次不同的事件.我有一个[主机]实体,每个主机每年最多可举办4个事件, 一次一个.大多数用户只关心一个主机的事件.
我试图避免让用户总是去事件地图并找到事件并点击它,因为我有限制我可以显示地图的次数(免费),而且它实际上没有必要.用户在我的网站上99.99%的时间他们在事件屏幕上,而不是我的主屏幕,并且一次只对一个事件感兴趣.在将来我想编写代码,如果他们来到我的网站,他们就可以直接参加他们的活动或者他们最喜欢的主机上的新活动,这样我就可以避免大量的点击并将我的[Home]控制器页面集中在newbs上......但我还没有自动登录工作,所以这是后来的.
但是现在我希望主机总是为他们的活动提供相同的网址:FragSwapper.com/ [Host Abbreviation] ...并且知道它总会转到他们当前的活动,每4个月有一个不同的ID!
疯狂......我知道......但技术上很容易做到,我只是不知道如何在MVC中正确地完成这些工作.
Dan*_*.G. 21
更新:ASP.Net核心1.1
根据发行说明,RewriteMiddleware已经创建了一个新的.
这提供了几种不同的预定义重写选项和实用程序扩展方法,这可能最终修改请求路径,就像在此答案中完成的那样.例如,参见实施RewriteRule
特别是对于OP问题,您需要实现自己的IRule类(从头开始或扩展现有的类RewriteRule,基于正则表达式).您可以使用新的AddMyRule()扩展方法来补充它RewriteOptions.
您可以创建自己的中间件,并在MVC路由之前将其添加到请求管道.
这允许您在评估MVC路由之前将代码注入管道.通过这种方式,您将能够:
Event/Index/{eventId}或Home/Organization/{hostId}例如,创建自己的 EventIdUrlRewritingMiddleware中间件,尝试将传入的请求路径与数据库中的eventId进行匹配.如果匹配,它会将原始请求路径更改为Event/Index/{eventId}:
public class EventIdUrlRewritingMiddleware
{
private readonly RequestDelegate _next;
//Your constructor will have the dependencies needed for database access
public EventIdUrlRewritingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
var path = context.Request.Path.ToUriComponent();
if (PathIsEventId(path))
{
//If is an eventId, change the request path to be "Event/Index/{path}" so it is handled by the event controller, index action
context.Request.Path = "/Event/Index" + path;
}
//Let the next middleware (MVC routing) handle the request
//In case the path was updated, the MVC routing will see the updated path
await _next.Invoke(context);
}
private bool PathIsEventId(string path)
{
//The real midleware will try to find an event in the database that matches the current path
//In this example I am just using some hardcoded string
if (path == "/someEventId")
{
return true;
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
然后HostIdUrlRewritingMiddleware按照相同的方法创建另一个类.
最后,在Startup.Configure方法中将新的中间件添加到管道中,确保在路由和MVC中间件之前添加它们:
app.UseMiddleware<EventIdUrlRewritingMiddleware>();
app.UseMiddleware<HostIdUrlRewritingMiddleware>();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
Run Code Online (Sandbox Code Playgroud)
使用此配置:
/去HomeController.Index采取行动/Home/About去HomeController.About采取行动/Event/Index/1转到EventController.Index动作id = 1/someEventId转到EventController.Index动作,id = someEventId请注意,不涉及http重定向./someEventId在浏览器中打开时,只有一个http请求,浏览器将显示/someEventId在addess栏中.(即使内部原始路径已更新)
| 归档时间: |
|
| 查看次数: |
9989 次 |
| 最近记录: |