MVC:归属控制器中的动态路由,而不会影响其他控制器

时间:2019-05-11 16:15:03

标签: asp.net-mvc .net-core routes

这不是关于控制器和动作如何工作的普遍问题,而是关于在dotnet核心MVC客户端中向用户呈现已知url结构的问题。

我想用博客建立一个“主页”,也许以后还要在商店建立一个“主页”。通用网址结构应为

https://xxx.xx/... => Homepage content
https://xxx.xx/Blog/... => Blog content
https://xxx.xx/Shop/... => Shop content

“博客”和“商店”是网站中的特定区域,因此用户和控制器熟悉额外的路径,并且操作可以按预期进行。

对于主页,通常,您的结构如下:

https://xxx.xx/ => Index
https://xxx.xx/privacy
https://xxx.xx/about
https://xxx.xx/company/team

(眼睛)不需要的东西

https://xxx.xx/Home/privacy

此外,我喜欢从数据库中获取这些“页面”,以便Home控制器本身具有两个条件:

  1. 如果域后没有任何内容,请调用Home控制器,Index操作和Index.cshtml
  2. 如果该域之后的内容中没有路径“ Blog /”或“ Shop /”,则它是页面的名称或子段,因此使用“页面操作”调用Home控制器并显示Page。包含数据库内容的cshtml。

如果我在Home控制器中执行类似的操作

[HttpGet("{slug?}")]
public async Task<IActionResult> Index(string slug)

我喜欢主页可以工作的那种,但是我不能再调用任何其他控制器了。

我玩过自定义路线,但是我的问题是显然路线无法区分“路径”和“动作”。

我的问题有解决方案吗?还是我必须处理?

1 个答案:

答案 0 :(得分:1)

尝试此路线并将其重定向到目标

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


            routes.MapRoute(
                name: "Link",
                url: "{slug}",
                defaults: new { controller = "Slug", action = "GoTo" }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }

和在slug控制器中:

public async Task<ActionResult> GoTo(string ShortLink)
        {
            if (String.IsNullOrWhiteSpace(ShortLink))
                return RedirectToAction("Index", "Home");


            LinkModels linkModels = db.Links.Where(sl => sl.ShortLinkURL == ShortLink).FirstOrDefault();

            if (linkModels == null)
            {
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ClickModels cm = new ClickModels();
                if (System.Web.HttpContext.Current.Request.UrlReferrer != null)
                {
                    linkModels.ReferralCount++;
                    cm.LinkType = 1;
                    cm.RequestURL = System.Web.HttpContext.Current.Request.UrlReferrer.AbsoluteUri;
                    cm.RequestIP = BitOneWeb.Helper.GetClientIP.GetIP();
                    cm.ClickDateTime = DateTime.Now;


                }
                else
                {
                    linkModels.DirectCount++;
                    cm.LinkType = 0;
                    //cm.RequestURL = "Direct";
                    cm.RequestIP = BitOneWeb.Helper.GetClientIP.GetIP();
                    cm.ClickDateTime = DateTime.Now;

                }
                linkModels.LinkCount = linkModels.DirectCount + linkModels.ReferralCount;
                db.Clicks.Add(cm);
                linkModels.Clicks.Add(cm);

                db.Entry(linkModels).State = EntityState.Modified;


                await db.SaveChangesAsync();
                return Redirect(linkModels.LongLinkURL);
            }
        }

这对我来说很好,但是,如果您有http://yoursite/bloghttp://yoursite/contact之类的修复控制器,则可以在弹头控制器中静态处理该问题