在MVC 4中使用路由更改URL参数

时间:2016-05-18 14:26:40

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

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

SomeController / SomeAction AAA BBB =&安培;属性= CCC&安培; attributeDelimiter = DDD

我想在这些参数名称中允许支持复数 - 'attributes'和'attributesDelimiter'。

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

1 个答案:

答案 0 :(得分:0)

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