首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查询字符串参数的ASP.NET MVC约束

查询字符串参数的ASP.NET MVC约束
EN

Stack Overflow用户
提问于 2015-10-16 18:20:24
回答 1查看 1.3K关注 0票数 0

我有两个动作

代码语言:javascript
复制
public Action HasNumber(string name) { ... }

public Action DoesntHaveNumer(string name) { ... }

有没有可能创建这样的路由,根据name参数的值,它将命中一个或另一个?

示例:

myApp/Home?name=qwe将冲击DoesntHaveNumer

myApp/Home?name=q2e将冲击HasNumber

name是必需的参数

EN

回答 1

Stack Overflow用户

发布于 2015-10-16 21:14:08

default Route类不与查询字符串交互。但是,你可以继承它来添加额外的功能。

代码语言:javascript
复制
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

public class NumericCheckingQueryStringValueRoute : Route
{
    private readonly string queryStringKey;
    private readonly RouteValueDictionary defaultsIfNumeric;
    private readonly RouteValueDictionary defaultsIfNonNumeric;

    public NumericCheckingQueryStringValueRoute(
        string url,
        string queryStringKey,
        object defaultsIfNumeric,
        object defaultsIfNonNumeric)
        : base(url, new MvcRouteHandler())
    {
        this.queryStringKey = queryStringKey;
        this.defaultsIfNumeric = new RouteValueDictionary(defaultsIfNumeric);
        this.defaultsIfNonNumeric = new RouteValueDictionary(defaultsIfNonNumeric);
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var result = base.GetRouteData(httpContext);

        // If it matches, the result will be non-null
        if (result != null)
        {
            var newResult = new RouteData(this, new MvcRouteHandler());

            // Copy the route values from the base class
            foreach (var value in result.Values)
            {
                newResult.Values[value.Key] = value.Value;
            }
            // Copy the data tokens from the base class
            foreach (var token in result.DataTokens)
            {
                newResult.DataTokens[token.Key] = token.Value;
            }

            var requestQueryString = httpContext.Request.QueryString;

            var queryStringValue = requestQueryString[this.queryStringKey];

            if (string.IsNullOrEmpty(queryStringValue))
            {
                return null;
            }

            RouteValueDictionary defaultsToUse;
            if (ContainsDigits(queryStringValue))
            {
                defaultsToUse = this.defaultsIfNumeric;
            }
            else
            {
                defaultsToUse = this.defaultsIfNonNumeric;
            }

            // Copy the numeric defaults to route values
            foreach (var value in defaultsToUse)
            {
                newResult.Values[value.Key] = value.Value;
            }

            // We matched, return the result
            return newResult;
        }

        // Return null if no match
        return null;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        // We just pass this through. If you add the value as a route value
        // when building ActionLink or RouteLink, it will automatically make
        // it into a query string value because it is not part of the url argument.
        return base.GetVirtualPath(requestContext, values);
    }

    // Fastest way to check for digits
    // http://stackoverflow.com/questions/7461080/fastest-way-to-check-if-string-contains-only-digits
    private bool ContainsDigits(string str)
    {
        foreach (char c in str)
        {
            if (c >= '0' && c <= '9')
                return true;
        }

        return false;
    }
}

用法

代码语言:javascript
复制
public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.Add(
            name: "CheckNumericName",
            item: new NumericCheckingQueryStringValueRoute(
                url: "Home",
                queryStringKey: "name",
                defaultsIfNumeric: new { controller = "Home", action = "HasNumber" },
                defaultsIfNonNumeric: new { controller = "Home", action = "DoesntHaveNumer" }
                )
            );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

要构建到页面的链接,您需要将查询字符串值添加到路由值集合中。你应该使用RouteLink,因为你有两个不同的动作方法。

代码语言:javascript
复制
@Html.RouteLink("Link with number", "CheckNumericName", new { name = "q2e" })
@Html.RouteLink("Link with no number", "CheckNumericName", new { name = "qwe" })
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33168059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档