[英]ASP.NET MVC constraint for query string parameter
我有2個動作
public Action HasNumber(string name) { ... }
public Action DoesntHaveNumer(string name) { ... }
是否可以創建這樣的路由,使其根據name
參數的值擊中一個或另一個?
例:
myApp/Home?name=qwe
將命中DoesntHaveNumer
myApp/Home?name=q2e
將命中HasNumber
name
是必填參數
默認的Route類不與查詢字符串交互。 但是,您可以繼承它以添加其他功能。
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;
}
}
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" })
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.