2017-02-13 54 views
2

は、私はMVCでこのようなものを使用:ASP.NET Core MVCで破線ルーティング?コア前

public class HyphenatedRouteHandler : MvcRouteHandler 
    { 
     protected override IHttpHandler GetHttpHandler(RequestContext requestContext) 
     { 
      requestContext.RouteData.Values["controller"] = requestContext.RouteData.Values["controller"].ToString().Replace("-", "_"); 
      requestContext.RouteData.Values["action"] = requestContext.RouteData.Values["action"].ToString().Replace("-", "_"); 
      return base.GetHttpHandler(requestContext); 
     } 
    } 

はどのようにASP.Netコアで私は、URLにダッシュを使用することができますか? ... http://www.example.com/my-friendly-url ...のように、アクションmy_friendly_urlに変換します。

属性ルートは使用しません。

おかげ

答えて

1

はConfigureServices方法で起動して、この規則を追加します。UseMvcで

options.Conventions.Add(new DashedRoutingConvention()); 

ルートは動作しません。 ASP.Net自体は単純に考慮されません。私はGitHubで問題を作成しました...しかし、それが行く方法はわかりません。今のところ、メソッドの属性を持つルートを指定することができます。コンベンションでは元のルートを再利用/コピーし、{controller}/{action}という形式で新しい破線のパスを更新/追加します。

public class DashedRoutingConvention : IControllerModelConvention 
{ 
    public void Apply(ControllerModel controller) 
    { 
     string parent = this.Convert(controller.ControllerName); 

     foreach (ActionModel action in controller.Actions) 
     { 
      string child = this.Convert(action.ActionName); 

      string template = $"{parent}/{child}"; 

      if (this.Lookup(action.Selectors, template) == true) 
       continue; 

      List<SelectorModel> selectors = action.Selectors.Where(item => item.AttributeRouteModel?.Template == null).ToList(); 
      if (selectors.Count > 0) 
      { 
       foreach (SelectorModel existing in selectors) 
       { 
        if (existing.AttributeRouteModel == null) 
         existing.AttributeRouteModel = new AttributeRouteModel(); 

        existing.AttributeRouteModel.Template = template; 
       } 
      } 
      else 
      { 
       selectors = action.Selectors.Where(item => item.AttributeRouteModel?.Template != null).ToList(); 

       foreach (SelectorModel existing in selectors) 
       { 
        SelectorModel selector = new SelectorModel(existing); 

        selector.AttributeRouteModel.Template = template; 

        if (action.Selectors.Any(item => this.Compare(item, selector)) == false) 
         action.Selectors.Add(selector); 
       } 
      } 
     } 
    } 

    private string Convert(string token) 
    { 
     if (token == null) 
      throw new ArgumentNullException(nameof(token)); 

     if (token == string.Empty) 
      throw new ArgumentException("Failed to convert empty token."); 

     return Regex.Replace(token, "(?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z])", "-$1", RegexOptions.Compiled).Trim().ToLower(); 
    } 

    private bool Lookup(IEnumerable<SelectorModel> selectors, string template) 
    { 
     foreach (SelectorModel selector in selectors) 
     { 
      string current = selector.AttributeRouteModel?.Template; 

      if (string.Compare(current, template, StringComparison.OrdinalIgnoreCase) == 0) 
       return true; 
     } 

     return false; 
    } 
    private bool Compare(SelectorModel existing, SelectorModel adding) 
    { 
     if (existing.AttributeRouteModel == null && adding.AttributeRouteModel != null) 
      return false; 

     if (existing.AttributeRouteModel != null && adding.AttributeRouteModel == null) 
      return false; 

     if (existing.AttributeRouteModel != null && adding.AttributeRouteModel != null) 
     { 
      if (existing.AttributeRouteModel.Template != adding.AttributeRouteModel.Template) 
       return false; 

      if (existing.AttributeRouteModel.Order != adding.AttributeRouteModel.Order) 
       return false; 
     } 

     if (existing.ActionConstraints == null && adding.ActionConstraints != null) 
      return false; 

     if (existing.ActionConstraints != null && adding.ActionConstraints == null) 
      return false; 

     if (existing.ActionConstraints != null && adding.ActionConstraints != null) 
     { 
      if (existing.ActionConstraints.Count != adding.ActionConstraints.Count) 
       return false; 
     } 

     return true; 
    } 
} 
関連する問題