2016-03-21 1 views
1

MVCコントローラのアクションは、そのパラメータ(null/emptyと特定の文字列)に対して特定の値で呼び出す必要があります。ヒットしない(ほとんど404)。私は以下のようにRegexRouteConstraintを使ってみました。しかし、それは特定の文字列をフィルタリングしません。MVCコントローラのアクションは特定のパラメータ値のみを処理する必要があります(他の場合は404)

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); 

コントローラは次のようになります。public ActionResult Index(string soortAanbod)

私はまた、アクションフィルタを使用してみましたが、それは他の他のフィルタを台無しに。どのようにすれば、このルートはsoortAanbodの指定された値にのみ一致させることができますか?

+1

これが特定のアクションである場合は、コード – cdie

+0

でアクション内で直接処理する選択肢があります。同じ制約を使用するアクションはいくつかあります。コードはオプションですが、むしろun-MVCです – mnwsmit

答えて

1

あなたは2つの問題があります:

  1. 一致する文字列を区切るために、RegExにanchors^および$)が含まれていません。したがって、にはの文字列が含まれています。
  2. あなたのURLはで、常にがデフォルトのルートと一致するため、カスタムルートが一致しない場合でも、そのページには引き続きアクセスします。デフォルトルートは、のいずれかの URLと一致し、長さは0,1,2または3セグメントです。

あなたのカスタムルートを削除し、マッチングから、それらの特定のURLを防ぐために(舞台裏StopRoutingHandlerを使用しています)IgnoreRouteを使用することによってこの問題を回避することができます。

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 } 
     ); 
    } 
} 

警告がありますが、 RegExはnot very good at doing negative matchesです。したがって、RegExの専門家でない場合は、このシナリオを処理するための最も簡単な解決策はNegativeRegexRouteConstraintです。

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

アンカーでした。愚かなバグ。このウェブサイトにはデフォルトルートがないため、アンカーだけで十分でした。ありがとう! – mnwsmit

1

あなたは属性ルーティングを試してみるか、またはパラメータを確認したり、どこかにリダイレクトするアクションの独自の属性を記述することができます。

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

これは実際の回答よりもコメントです.... – Hackerman

+0

私は(NotFoundResultを使って)このようなことを試しましたが、すでに存在するフィルタパイプラインを駄目です。 – mnwsmit

関連する問題