我有2个动作
public Action HasNumber(string name) { ... }
public Action DoesntHaveNumer(string name) { ... }
是否可以根据name
参数的值创建这样的路线,使其触及一个或另一个?
示例:
myApp/Home?name=qwe
将点击DoesntHaveNumer
myApp/Home?name=q2e
将点击HasNumber
name
是必填参数
答案 0 :(得分:0)
默认的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,因为您可以使用两种不同的操作方法。
@Html.RouteLink("Link with number", "CheckNumericName", new { name = "q2e" })
@Html.RouteLink("Link with no number", "CheckNumericName", new { name = "qwe" })