查询字符串参数的 ASP.NET MVC 约束
Posted
技术标签:
【中文标题】查询字符串参数的 ASP.NET MVC 约束【英文标题】:ASP.NET MVC constraint for query string parameter 【发布时间】:2016-01-15 01:31:49 【问题描述】:我有两个动作
public Action HasNumber(string name) ...
public Action DoesntHaveNumer(string name) ...
是否可以根据name
参数的值创建这样的路线,它会撞到一个或另一个?
例子:
myApp/Home?name=qwe
将点击DoesntHaveNumer
myApp/Home?name=q2e
将点击HasNumber
name
是必填参数
【问题讨论】:
为什么不在重定向前检查,首先确定正确的路径 @EuphoriaGrogi 重定向之前是什么意思? 在这里找到答案:*** - Can my MVC2 app specify route constraints on Query String parameters? 【参考方案1】:默认路由类不与查询字符串交互。但是,您可以继承它来添加额外的功能。
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://***.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;
用法
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,因为您有 2 种不同的操作方法。
@html.RouteLink("Link with number", "CheckNumericName", new name = "q2e" )
@Html.RouteLink("Link with no number", "CheckNumericName", new name = "qwe" )
【讨论】:
以上是关于查询字符串参数的 ASP.NET MVC 约束的主要内容,如果未能解决你的问题,请参考以下文章
具有固定 URI 的 ASP.NET 路由不映射查询字符串参数