使用 MVC 和 ASP.Net Core 重写动态 url [英] Dynamic url rewriting with MVC and ASP.Net Core

查看:23
本文介绍了使用 MVC 和 ASP.Net Core 重写动态 url的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ASP.Net Core 和 MVC 6 重新编写我的 FragSwapper.com 网站(目前在 Asp 2.0 中!),我正在尝试做一些我通常必须打破 URL 重写工具的事情使用 db 代码和一些重定向,但我想知道在 ASP.Net Core 中是否有更好"的方法可以使用 MVC 路由和重定向.

I am re-writing my FragSwapper.com website (currently in Asp 2.0!) with ASP.Net Core and MVC 6 and I'm trying to do something I would normally have to break out a URL Re-Write tool along with db code and some Redirects but I want to know if there is a "better" way to do it in ASP.Net Core possibly with MVC Routing and Redirecting.

这是我的场景...

  • 访问网站的 URL:[root]

做什么: 转到通常的 [Home] 控制器和 [Index] 视图(没有 [ID])....它现在这样做了:

What to do: Go to the usual [Home] Controller and [Index] View (no [ID]). ...it does this now:

app.UseMvc(routes =>
{
  routes.MapRoute(
  name: "default",
  template: "{controller=Home}/{action=Index}/{id?}");
});

  • 访问网站的 URL:[root]/ControllerName/...yada yada...

    怎么做:去控制器,等等......这一切也都有效.

    What to do: Go to the Controller, etc...all THIS works too.

    棘手的一个:URL 访问站点:[root]/SomeString

    该怎么做: 访问数据库并执行一些逻辑来决定是否找到事件 ID.如果我这样做,我会转到 [Event] Controller 和 [Index] View 以及我找到的任何内容的 [ID].如果不是,我尝试查找主机 ID 并使用我找到的 [ID] 转到 [Home] Controller 和 [Organization] View.如果我没有找到事件或主机,请转到通常的 [Home] 控制器和 [Index] 视图(没有 [ID]).

    What to do: Access the database and do some logic to decide if I find an Event ID. If I do I go to [Event] Controller and [Index] View and an [ID] of whatever I found. If not I try to find a Host ID and go to [Home] Controller and [Organization] View with THAT [ID] I found. If I don't find and Event or Host go to the usual [Home] Controller and [Index] View (no [ID]).

    这里的大问题是我想重定向到 2 个不同控制器中的三个完全不同的视图之一.

    The big gotcha here is that I want to Redirect to one of three completely different views in 2 different controllers.

    所以底线是当用户来到我网站的根目录并且上面有一个/Something"并且该逻辑是数据库驱动时,我想做一些逻辑.

    So the bottom line is I want to do some logic when the user comes to my site's root and has a single "/Something" on it and that logic is database driven.

    如果您理解了这个问题,您现在可以停止阅读...如果您觉得有必要了解为什么需要所有这些逻辑,您可以继续阅读以获得更详细的上下文.

    If you understand the question you can stop reading now...If you feel the need to understand why all this logic is needed you can read on for a more detailed context.

    我的网站基本上有两种模式:查看活动和不查看活动事件!通常一次运行 4 或 5 个事件,但大多数用户只对一个事件感兴趣,但这是一个不同的事件每 4 个月左右..我有一个 [Host] 实体,每个 Host 最多支持一年4场,一次一场.大多数用户只关心一个主机的事件.

    My site has basically two modes: Viewing an Event and Not Viewing an Event! There are usually 4 or 5 events running at an one time but most users are only interested in one event but it's a DIFFERENT event every 4 months or so..I have a [Host] entity and each Host holds up to 4 events a year, one at a time. Most users only care about one Host's events.

    我试图避免让用户总是去事件地图并找到事件并点击它,因为我有次数限制显示地图(免费),这真的没有必要.99.99% 的当用户在我的网站上时,他们在事件屏幕上,而不是在我的主页上屏幕,并且一次只对一个事件感兴趣.在里面未来我想对其进行编码,所以如果他们来到我的网站,他们就会正确参加他们的活动或他们最喜欢的主持人的新活动,这样我就可以避免大量的点击并将我的 [Home] 控制器页面集中在新手上......但我还没有自动登录功能,所以它在后面.

    I'm trying to avoid making a user always go to an event map and find the event and click on it since I have a limit to how many times I can show a map (for free) and it's really not necessary. 99.99% of the time a user is on my site they are on an Event screen, not my Home screens, and are interested in only one event at a time. In the future I want to code it so if they come to my website they go right to their event or a new event from their favorite host so I can avoid a LOT of clicks and focus my [Home] controller pages for newbs...but I don't have auto-login working yet so that's on the back burner.

    但现在我希望主持人始终拥有相同的活动网址:FragSwapper.com/[Host Abbreviation] ...并且知道它总是会转到他们的当前事件每 4 个月有一个不同的 ID!!!

    But for now I want hosts to always have the same url for their events: FragSwapper.com/[Host Abbreviation] ...and know it will always go to their current event which has a different ID every 4 months!!!

    疯了...我知道...但从技术上讲很容易做到,我只是不知道如何在 MVC 中正确执行操作.

    Crazy...I know...but technically very easy to do, I just don't know how to do it properly in MVC with how things are done.

    推荐答案

    更新:ASP.Net Core 1.1

    根据 发行说明,一个新的 RewriteMiddleware 已创建.

    According to the release notes, a new RewriteMiddleware has been created.

    这提供了几种不同的预定义重写选项和实用程序扩展方法,最终可能会修改请求路径,就像在此答案中所做的那样.例如,参见 的实现重写规则

    This provides several different predefined rewrite options and utility extension methods, which might end up modifying the request path as it has been done in this answer. See for example the implementation of RewriteRule

    具体到 OP 问题,您需要实现自己的 IRule 类(从头开始或扩展现有的类,例如基于正则表达式的 RewriteRule).您可能会使用 RewriteOptions 的新 AddMyRule() 扩展方法来补充它.

    Specifically to the OP question, you would need to implement your own IRule class (either from scratch or extending an existing one like RewriteRule, which is based on a regex). You would possibly complement it with a new AddMyRule() extension method for RewriteOptions.

    您可以创建自己的中间件并将其添加到MVC 路由之前的请求管道.

    You can create your own middleware and add it to the request pipeline before the MVC routing.

    这允许您在评估 MVC 路由之前将代码注入管道.这样您就可以:

    This allows you to inject your code into the pipeline before the MVC routes are evaluated. This way you will be able to:

    1. 检查传入请求中的路径
    2. 在数据库中搜索具有相同值的 eventId 或 hostId
    3. 如果找到事件或主机,则将传入请求路径更新为 Event/Index/{eventId}Home/Organization/{hostId}
    4. 让下一个中间件(MVC 路由)处理请求.他们会看到之前的中间件对请求路径所做的任何更改

    例如,创建自己的 EventIdUrlRewritingMiddleware 中间件,它将尝试将传入请求路径与数据库中的 eventId 进行匹配.如果匹配,则将原来的请求路径改为Event/Index/{eventId}:

    For example, create your own EventIdUrlRewritingMiddleware middleware that will try to match the incoming request path against an eventId in the database. If matched, it will change the original request path to 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;
        }
    }
    

    然后按照同样的方法创建另一个类HostIdUrlRewritingMiddleware.

    Then create another class HostIdUrlRewritingMiddleware following the same approach.

    最后在 Startup.Configure 方法中将新的中间件添加到管道中,确保在路由和 MVC 中间件之前添加它们:

    Finally add your new middlewares to the pipeline in the Startup.Configure method, making sure they are added before the Routing and MVC middleware:

            app.UseMiddleware<EventIdUrlRewritingMiddleware>();
            app.UseMiddleware<HostIdUrlRewritingMiddleware>();
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
    

    使用此配置:

    • / 转到 HomeController.Index 动作
    • /Home/About 转到 HomeController.About 动作
    • /Event/Index/1 转到 EventController.Index 动作 id=1
    • /someEventId 转到 EventController.Index 动作,id=someEventId
    • / goes to the HomeController.Index action
    • /Home/About goes to the HomeController.About action
    • /Event/Index/1 goes to the EventController.Index action id=1
    • /someEventId goes to the EventController.Index action, id=someEventId

    请注意,不涉及 http 重定向.在浏览器中打开 /someEventId 时,会有一个 http 请求,浏览器会在地址栏中显示 /someEventId.(即使在内部更新了原始路径)

    Please note there are no http redirects involved. When opening /someEventId in the browser there is a single http request and the browser will show /someEventId in the addess bar. (Even if internally the original path was updated)

    这篇关于使用 MVC 和 ASP.Net Core 重写动态 url的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆