2016-03-21 10 views
1

Ich habe eine MVC Controller Aktion mit einem Parameter, der nur mit bestimmten Werten für diesen Parameter (null/leer und einige spezifische Strings) aufgerufen werden sollte, in anderen Fällen sollte es nicht getroffen werden (404 meist). Ich habe versucht, eine RegexRouteConstraint wie unten zu verwenden. Aber das filtert die spezifischen Zeichenfolgen nicht.MVC Controller Action sollte nur bestimmte Parameterwerte behandeln, sonst

var route = new Route("{soortAanbod}", new MvcRouteHandler()) 
{ 
    Defaults = new RouteValueDictionary(new { controller = "Homepage", action = "Index", soortAanbod = UrlParameter.Optional }), 
    Constraints = new RouteValueDictionary(new { soortAanbod = new RegexRouteConstraint("a|b|c|d|e") }), 
    DataTokens = new RouteValueDictionary { { "area", context.AreaName } } 
}; 
context.Routes.Add("Homepage_soortAanbod", route); 

Der Controller sieht wie folgt aus: public ActionResult Index(string soortAanbod)

ich auch ein Action-Filter versucht haben, mit aber das vermasselt andere andere Filter auf. Wie kann ich diese Route nur für die angegebenen Werte für soortAanbod anpassen?

+1

wenn diese eine bestimmte Aktion ist, haben Sie die Wahl, um es direkt durch den Code in Ihre Aktion zu behandeln – cdie

+0

Es mehrere Aktionen ist die gleiche Einschränkung verwenden. Code kann eine Option sein, aber es ist eher un-MVC – mnwsmit

Antwort

1

Sie haben 2 Ausgaben:

  1. Ihre RegEx enthält anchors (^ und $) nicht zum Abgrenzen der Zeichenfolge, die Sie abgleichen möchten. Also, es entspricht jeder Zeichenfolge, die enthält irgendwelche dieser Buchstaben.
  2. Ihre URL wird immer mit der Standardroute übereinstimmen. Selbst wenn Ihre benutzerdefinierte Route nicht übereinstimmt, gelangen Sie trotzdem zur Seite. Die Standardroute entspricht einer beliebigen URL, die 0, 1, 2 oder 3 Segmente lang ist.

Sie können dieses Problem umgehen, indem Sie Ihre individuelle Route zu entfernen und unter Verwendung ein IgnoreRoute (die hinter den Kulissen verwenden ein StopRoutingHandler) die spezifische URLs von Anpassung zu verhindern.

public class RouteConfig 
{ 
    public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     routes.IgnoreRoute("Homepage/Index/{soortAanbod}", 
      new { soortAanbod = new NegativeRegexRouteConstraint(@"^a$|^b$|^c$|^d$|^e$") }); 

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

Es gibt jedoch einen Vorbehalt. RegEx's sind not very good at doing negative matches, also, wenn Sie kein RegEx-Guru sind, ist die einfachste Lösung, ein NegativeRegexRouteConstraint zu bauen, um dieses Szenario zu behandeln.

public class NegativeRegexRouteConstraint : IRouteConstraint 
{ 
    private readonly string _pattern; 
    private readonly Regex _regex; 

    public NegativeRegexRouteConstraint(string pattern) 
    { 
     _pattern = pattern; 
     _regex = new Regex(pattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled); 
    } 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     if (parameterName == null) 
      throw new ArgumentNullException("parameterName"); 
     if (values == null) 
      throw new ArgumentNullException("values"); 

     object value; 
     if (values.TryGetValue(parameterName, out value) && value != null) 
     { 
      string valueString = Convert.ToString(value, CultureInfo.InvariantCulture); 
      return !_regex.IsMatch(valueString); 
     } 
     return true; 
    } 
} 
+0

Es waren die Anker. Dumme Wanze. Diese Website verfügt nicht über die Standardroute, sodass nur die Anker ausreichend waren. Vielen Dank! – mnwsmit

1

Ich denke, Sie können versuchen, Attribut-Routing oder vielleicht schreiben Sie Ihr eigenes Attribut für die Aktion zu überprüfen, Params oder Redirect irgendwo.

public class SomeAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     var yourstring = filterContext.RequestContext.HttpContext.Request.QueryString["string"]; 
     if (!string.IsNullOrWhiteSpace(yourstring)) 
     { 
      if (yourstring is not ok) 
      filterContext.Result = 
       new RedirectToRouteResult(
        new RouteValueDictionary 
        { 
         {"controller", "SomeCtrl"}, 
         {"action", "SomeAction"} 
        }); 
     } 
     base.OnActionExecuting(filterContext); 

    } 
+1

Dies ist mehr ein Kommentar als eine tatsächliche Antwort .... – Hackerman

+0

Ich habe versucht, so etwas (mit einem NotFoundResult), aber es vermasselt die Filter-Pipeline, die bereits vorhanden ist. – mnwsmit

Verwandte Themen