【问题标题】:Changing URL parameters with routing in MVC 4在 MVC 4 中使用路由更改 URL 参数
【发布时间】:2016-09-15 02:41:25
【问题描述】:

我的几个 API 函数允许名为“attribute”和“attributeDelimiter”(单数)的参数,这意味着预期 URL 的格式为

SomeController/SomeAction?aaa=bbb&attribute=ccc&attributeDelimiter=ddd.

我希望在这些参数名称中也支持复数 - 'attributes' 和 'attributesDelimiter'。

  1. 有没有办法在 RouteConfig 中重写 url? (将复数名称变为单数)
  2. 如果这不可能或不是最佳做法,那么进行这种重写的最佳方法是什么?

【问题讨论】:

    标签: c# asp.net-mvc-4 url-rewriting routing asp.net-mvc-routing


    【解决方案1】:

    MVC 不对查询字符串值使用路由。查询字符串值由value providers 提供给操作方法。因此,要解决这个问题,您只需要一个自定义值提供程序来处理单数或复数的情况。

    示例

    using System;
    using System.Collections.Specialized;
    using System.Globalization;
    using System.Web.Mvc;
    
    public class SingularOrPluralQueryStringValueProviderFactory : ValueProviderFactory
    {
        private readonly string singularKey;
        private readonly string pluralKey;
    
        public SingularOrPluralQueryStringValueProviderFactory(string singularKey, string pluralKey)
        {
            if (string.IsNullOrEmpty(singularKey))
                throw new ArgumentNullException("singularKey");
            if (string.IsNullOrEmpty(pluralKey))
                throw new ArgumentNullException("pluralKey");
    
            this.singularKey = singularKey;
            this.pluralKey = pluralKey;
        }
    
        public override IValueProvider GetValueProvider(ControllerContext controllerContext)
        {
            return new SingularOrPluralQueryStringValueProvider(this.singularKey, this.pluralKey, controllerContext.HttpContext.Request.QueryString);
        }
    }
    
    public class SingularOrPluralQueryStringValueProvider : IValueProvider
    {
        private readonly string singularKey;
        private readonly string pluralKey;
        private readonly NameValueCollection queryString;
    
    
        public SingularOrPluralQueryStringValueProvider(string singularKey, string pluralKey, NameValueCollection queryString)
        {
            if (string.IsNullOrEmpty(singularKey))
                throw new ArgumentNullException("singularKey");
            if (string.IsNullOrEmpty(pluralKey))
                throw new ArgumentNullException("pluralKey");
    
            this.singularKey = singularKey;
            this.pluralKey = pluralKey;
            this.queryString = queryString;
        }
    
        public bool ContainsPrefix(string prefix)
        {
            return this.GetSingularOrPluralValue(prefix) != null;
        }
    
        public ValueProviderResult GetValue(string key)
        {
            var value = this.GetSingularOrPluralValue(key);
            return (value != null) ? 
                new ValueProviderResult(value, value.ToString(), CultureInfo.InvariantCulture) : 
                null;
        }
    
        private bool IsKeyMatch(string key)
        {
            return (this.singularKey.Equals(key, StringComparison.OrdinalIgnoreCase) ||
                this.pluralKey.Equals(key, StringComparison.OrdinalIgnoreCase));
        }
    
        private string GetSingularOrPluralValue(string key)
        {
            if (this.IsKeyMatch(key))
            {
                return this.queryString[this.singularKey] ?? this.queryString[this.pluralKey];
            }
            return null;
        }
    }
    

    用法

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
    
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
    
            // Insert our value provider factories at the beginning of the list 
            // so they override the default QueryStringValueProviderFactory
            ValueProviderFactories.Factories.Insert(
                0, new SingularOrPluralQueryStringValueProviderFactory("attribute", "attributes"));
            ValueProviderFactories.Factories.Insert(
                1, new SingularOrPluralQueryStringValueProviderFactory("attributeDelimiter", "attributesDelimiter"));
        }
    }
    

    现在,在您的操作方法甚至模型的属性中,无论值是在查询字符串中指定为单数还是复数,这些值都将被填充。如果查询字符串中同时包含单数和复数,则单数优先。

    public ActionResult Index(string attribute, string attributeDelimiter)
    {
        return View();
    }
    

    【讨论】:

      猜你喜欢
      • 2011-11-11
      • 1970-01-01
      • 2013-04-21
      • 2014-02-15
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      • 2016-07-06
      • 1970-01-01
      相关资源
      最近更新 更多