2017-02-13 92 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); 
     } 
    } 

我怎樣才能在URL中ASP.Net核心使用破折號? ...就像http://www.example.com/my-friendly-url ...並將其轉換爲my_friendly_url操作。

我不想使用屬性的路由。

感謝

回答

1

在啓動加入本公約的ConfigureServices方法:

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

航線UseMvc將無法正常工作。他們根本不會被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; 
    } 
}