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

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

问题描述

我正在使用ASP.Net Core和MVC 6重写我的FragSwapper.com网站(当前在Asp 2.0中!),而我试图做一些通常必须打破URL Re-Write工具的事情带有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]

  • URL Accessing the site: [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 ...

  • URL Accessing the site: [root]/ControllerName/...yada yada...

    做什么:转到控制器,等等...这也可以工作.

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

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

    The tricky one: URL Accessing the site: [root]/SomeString

    要做的事情::访问数据库并做一些逻辑决定我是否找到事件ID.如果可以,请转到[事件]控制器和[索引]视图以及所找到内容的[ID].如果没有,我尝试找到一个主机ID,并使用找到的那个[ID]转到[家庭]控制器和[组织]视图.如果找不到事件或主机",请转到常规的主页"控制器和索引"视图(无[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个月左右..我有一个[主机]实体,每个主机最多 一年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.

    但是现在,我希望主机的事件始终具有相同的url: FragSwapper.com/[主机缩写] ...并且知道它将始终会转到 他们当前的事件每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

    根据发行说明,一个新的

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

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

    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路由)处理请求.他们会看到以前的中间件对请求路径所做的任何更改
    1. Inspecting the path in the incoming request
    2. Search in the database for an eventId or hostId with the same value
    3. If event or host were found, update the incoming request path to Event/Index/{eventId} or Home/Organization/{hostId}
    4. Let the next middleware (MVC routing) take care of the request. They would see any changes to the request path made by the previous middleware

    例如,创建自己的 中间件,它将尝试将传入的请求路径与数据库中的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;
        }
    }
    

    然后按照相同的方法创建另一个类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请求,浏览器将在addess栏中显示/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天全站免登陆