2010-12-30 13 views
7

私は経路上に設定しようとしている特定の制約に問題があります。私のURLは次のようにしなければなりません:http://hostname/id-my-title-can-be-that-long idは数字のみで構成され、タイトルは小文字で、ダッシュ区切り記号です。 IDとタイトルもダッシュで区切られています。例:http://hostname/123-my-title。ここでASP.NET MVCの正規表現のルート制約

は私のルート定義を以下に示します。

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

URLが正しくHTMLヘルパーで生成されます。もちろん、Model.IdArticleはのInt32とModel.UrlTitle aは、

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

私のタイトルのあらかじめ形成された文字列は私の要件に合っています(小文字のみ、スペースはダッシュで置き換えられます)。

問題は、私がリンクをたどると、正しいコントローラ&メソッドが呼び出されていない、それは間違っている次のルートに落ちます。レコードの場合

が、私はASP.NET MVCによ2.

誰もがアイデアを持って?事前に

おかげで、 ファビアン

+0

最後に、IDとタイトルの間の区別を区別しないでください。私はまだこれがなぜ機能していないのだろうと思っていますが、もはやブロックしません。ご協力いただきありがとうございます! –

答えて

0

あなたは、全体のルート文字列渡すことを試みることができる「{ID} - {タイトル}」と、それはフィル・ハークさんに似た何かをすることによって、あなたの行動になる前に、手動で自分で文字列を解析idlug actionfilter属性 - link

これは役に立ちます。

+0

私は前にそのブログの記事を読んだが、私は経路情報を分割することができるときにそれが過度のものであると感じる。私のURLはルートから作成できますが、ルートとして解決されていないので、私はMVCの何らかのバグを考えています。 –

+0

ああ、十分です。別の考えがあります:-) – WestDiscGolf

0

ルート内のいくつかの文字は「特別」で、 - や/などのパラメータを分割します。ルート内の余分なものが原因で障害が発生している可能性があります。試しに"{id}-{*title}"を試してください。

更新

上記の答えは、あなたが十分なコーヒーを持っていた前に、あなたはStackOverflowの上で行くときに何が起こるかです。

ユーザーがアップロードしたファイルのファイル名を扱う同じ問題が発生しました。このルートには区切り文字として ' - 'が含まれていますが、後のパラメータの値でも使用できますそれに合っていない。最後に、この問題を処理するためのSpecialFileRouteクラスを作成し、このルートを登録しました。それは少し醜いですが、仕事をします。

URLを生成するために私は古いスタイルのMVCルートを使用していましたが、これを正しく行うためにこれを取得して遊んでいましたが、後で戻ってくるものです。

/// <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"])); 
    } 
} 

次のようにルートが追加されます。

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

この上述したようには少し醜いと私は時間があるとき多くの仕事があります私はこれを改善するためにやりたいけど、それだろうURLを必要なパラメータに分割するという問題を解決しました。 URLパターン、Regex、Valuesは、あなたが始めるべきであるが、コード化されたこの1つのルートの特定の要件に非常に強く結びついています。

+0

情報ありがとうございますが、複数のセクションを含むセグメントでキャッチオール(*)パラメータを使用することはできません。 –

+0

もちろん、D'oh。私はもう一度同じ問題に立ち向かいました – Chao

関連する問題