ASP.NET MVC的正则表达式路由约束 [英] ASP.NET MVC regex route constraint

查看:331
本文介绍了ASP.NET MVC的正则表达式路由约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在与一个特定的限制,我试图建立一个路线的麻烦。我的URL必须看起来像这样:的http://主机名/ ID,我的标题灿BE-那个长的其中id是由只用数字和标题是小写字符用破折号分隔符。 ID和标题也与破折号隔开。例如:的http://主机名/ 123-我的标题

I'm having trouble with a specific constraint I'm trying to set up on a route. My URL must look like this one: http://hostname/id-my-title-can-be-that-long where id is composed with digit only and the title is lowercase character with dashes separator. The id and the title are also separated with a dash. For example: http://hostname/123-my-title.

下面是我的路由定义:

routes.MapRoute(
    "Test",
    "{id}-{title}",
    new { controller = "Article", action = "Index" },
    new { id = @"(\d)+", title = @"([a-z]+-?)+" }
);

该网址是否正确插入的HTML辅助生成的:

The URL is correctly generated with the the html helper:

<%: Html.ActionLink("My link", "Index", "Article", new { id = Model.IdArticle, title = Model.UrlTitle }, null) %>

在那里,当然,Model.IdArticle是一个Int32和Model.UrlTitle我的标题的preformed匹配字符串我的要求(小写只,空间用破折号代替)说。

where, of course, Model.IdArticle is an Int32 and Model.UrlTitle a preformed string of my title that match my requirements (lower case only, space replaced by dashes).

问题是,当我跟随链接,右侧控制器&放大器;方法不叫,它属于这是不对的下一个路由。

The problem is, when I follow the link, the right controller & method is not called, it falls to the next route which is wrong.

有关的记录,我对ASP.NET MVC 2。

For the records, I'm on ASP.NET MVC 2.

任何人有一个想法?

在此先感谢,
费边

Thanks in advance, Fabian

推荐答案

在路由几个字符是特殊,将分手的参数,如 - 和/。它可能是在路径额外-s都使其失效。尝试(编号) - {*}标题,因为这使得标题包括如下一切

Several characters in the route are "special" and will split up the parameters such as - and /. It might be that the extra -s in the route are causing it to fail. Try "{id}-{*title}" as this makes title include everything that follows.

更新

以上答案是,当你走在计算器上,你已经受够了咖啡之前发生了什么。

The answer above is what happens when you go on StackOverflow before you've had enough coffee.

我们遇到了与文件名的处理由用户上传,包括路线的文件相同的问题 - 作为分隔符,但也可以在价值在以后的参数一起使用,它可以生成正确的URL,但止跌 ŧ匹配。最后,我写了一个SpecialFileRoute类来处理这个问题,并注册了这个路线。这是一个有点难看,但虽然做这项工作。

We came across the same problem dealing with file names for files uploaded by users, the route included '-' as a delimiter but could also be used in the value in a later parameter, it could generate the correct URL but wouldn't match it. In the end I wrote a SpecialFileRoute class to handle this issue and registered this route. It's a bit ugly though but does the job.

请注意,我留在旧风格路线的MVC生成的URL,我被玩弄得到这个正确地做到这一点,但它是值得回来以后。

Note that I kept in the old style MVC route for generating the URL, I was playing around with getting this to do it properly but it is something to come back to later.

    /// <summary>
/// Special route to handle hyphens in the filename, a catchall parameter in the commented route caused exceptions
/// </summary>
public class SpecialFileRoute : RouteBase, IRouteWithArea
{
    public string Controller { get; set; }
    public string Action { get; set; }
    public IRouteHandler RouteHandler = new MvcRouteHandler();
    public string Area { get; private set; }

    //Doc/{doccode} - {CatNumber}.{version} - {*filename},

    public SpecialFileRoute(string area)
    {
        Area = area;
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        string url = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2);
        var urlmatch = Regex.Match(url, @"doc/(\w*) - (\d*).(\d*) - (.*)", RegexOptions.IgnoreCase);
        if (urlmatch.Success)
        {
            var routeData = new RouteData(this, this.RouteHandler);

            routeData.Values.Add("doccode", urlmatch.Groups[1].Value);
            routeData.Values.Add("CatNumber", urlmatch.Groups[2].Value);
            routeData.Values.Add("version", urlmatch.Groups[3].Value);
            routeData.Values.Add("filename", urlmatch.Groups[4].Value);
            routeData.Values.Add("controller", this.Controller);
            routeData.Values.Add("action", this.Action);
            return routeData;
        }
        else
            return null;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        if (values.ContainsKey("controller") && (!string.Equals(Controller, values["controller"] as string, StringComparison.InvariantCultureIgnoreCase)))
            return null;
        if (values.ContainsKey("action") && (!string.Equals(Action, values["action"] as string, StringComparison.InvariantCultureIgnoreCase)))
            return null;
        if ((!values.ContainsKey("contentUrl")) || (!values.ContainsKey("format")))
            return null;
        return new VirtualPathData(this, string.Format("{0}.{1}", values["contentUrl"], values["format"]));
    }
}

在添加路由如下:

The route is added as follows:

context.Routes.Add(new SpecialFileRoute(AreaName) { Controller = "Doc", Action = "Download" });

如上文所述这是一个有点难看,当我有时间有很多的工作,我想做些什么来改善这一点,但它解决分裂网址进入所需参数的问题。这是相当强烈追平与URL模式,正则表达式这一路线的具体要求和价值观硬codeD但它应该给你一个开始。

As stated above this is a bit ugly and when I have time there's a lot of work I'd like to do to improve this but it solved the problem of splitting the URL into the needed parameters. It's quite strongly tied in to the specific requirements of this one route with the url pattern, Regex and Values hard coded though it should give you a start.

这篇关于ASP.NET MVC的正则表达式路由约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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