asp.net-mvc - ASP.NET Core MVC 中的虚线路由?

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

在 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 Core 中在 url 中使用破折号? ...就像http://www.example.com/my-friendly-url ...并将其转换为操作 my_Friendly_url。

我不想使用属性路由。

谢谢

最佳答案

在ConfigureServices方法的Startup中添加此约定:

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;
    }
}

关于asp.net-mvc - ASP.NET Core MVC 中的虚线路由?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42198437/

相关文章:

asp.net - ASP.NET MVC 条件输出的最佳实践?

c# - 如何使用身份以编程方式在 asp.net 5 中创建用户

c# - 为什么中间件组件在 .Net Core 管道中被调用两次?

entity-framework - Entity Framework : Cannot be configured on 'xxx' class because it is a derived type

asp.net-core - 如何从公共(public)互联网访问 HTTP 端口 5001

azure - 如何修复 "Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: ' 操作返回无效状态代码 'NotFound' '"

javascript - 如何从客户端将参数添加到 HttpContext.Request.Form 中

javascript - 如何在 asp .net MVC 中调试 javascript?

asp.net-mvc - 检测页面是否从 RedirectToAction() 方法重定向

linux - 为什么 NPOI xlsx 文件生成在 Linux 服务器上不起作用