2

ASP.Net MVC アプリケーションのルートにマップしたい古い URL があります。

e.g. http://my.domain.com/article/?action=detail&item=22

ルートの作成actionには特別な意味があるので、このルートを作成するにはどうすればよいですか? コントローラーは RedirectController で、アクションは Item です。

routes.MapRoute(
            name: "Redirect",
            url: "article",
            defaults:new { controller = "redirect", action = "item"}
            );

したがって、私の問題はaction、クエリ文字列が によって上書きされるactionことdefaultsです。これを回避する方法はありますか?

4

2 に答える 2

4

controlleractionおよびareaasp.net MVC の唯一の予約語です。「予約済み」とは、MVC が特にルーティングに対して特別な意味を与えることを意味します。

URL に含めることのできない、asp.net に固有ではない他の単語 ( COM1-9LPT1-9AUXPRT、 ) もあります。これは、なぜここで説明され、ここでバイパスする方法が説明されています。NULCON

編集:asp.net mvcはルートデータでそれらに依存しているため、それらを使用する方法はありません。

UrlHelper から取得した逆コンパイルされた例を次に示します。

// System.Web.Mvc.RouteValuesHelpers
public static RouteValueDictionary MergeRouteValues(string actionName, string controllerName, RouteValueDictionary implicitRouteValues, RouteValueDictionary routeValues, bool includeImplicitMvcValues)
{
    RouteValueDictionary routeValueDictionary = new RouteValueDictionary();
    if (includeImplicitMvcValues)
    {
        object value;
        if (implicitRouteValues != null && implicitRouteValues.TryGetValue("action", out value))
        {
            routeValueDictionary["action"] = value;
        }
        if (implicitRouteValues != null && implicitRouteValues.TryGetValue("controller", out value))
        {
            routeValueDictionary["controller"] = value;
        }
    }
    if (routeValues != null)
    {
        foreach (KeyValuePair<string, object> current in RouteValuesHelpers.GetRouteValues(routeValues))
        {
            routeValueDictionary[current.Key] = current.Value;
        }
    }
    if (actionName != null)
    {
        routeValueDictionary["action"] = actionName;
    }
    if (controllerName != null)
    {
        routeValueDictionary["controller"] = controllerName;
    }
    return routeValueDictionary;
}
于 2013-07-16T06:14:48.170 に答える
2

カスタム ModelBinder を使用してクラックすることができました。という基本クラスを作成しますQueryString

    public class QueryString
    {
            private readonly IDictionary<string,string> _pairs;

            public QueryString()
            {
                    _pairs = new Dictionary<string, string>();
            }

            public void Add(string key, string value)
            {
                    _pairs.Add(key.ToUpper(), value);
            }

            public string Get(string key)
            {
                    return _pairs[key.ToUpper()];
            }

            public bool Contains(string key)
            {
                    return _pairs.ContainsKey(key.ToUpper());
            }
    }

次に、そのためのカスタム バインダーを作成します。

    public class QueryStringModelBinder : IModelBinder
    {
            public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                    var queryString = new QueryString();
                    var keys = controllerContext.HttpContext.Request.QueryString.AllKeys;

                    foreach (var key in keys)
                    {
                            queryString.Add(key, controllerContext.HttpContext.Request.QueryString[key]);
                    }

                    return queryString;
            }
    }

私のGlobal.asaxに登録します:-

ModelBinders.Binders.Add(typeof(QueryString), new QueryStringModelBinder());

これで、RedirectController でそれを使用できます:-

public RedirectToRouteResult Item(QueryString queryString)
{
    // user QueryString object to get what I need
    // e.g. queryString.Get("action");
}
于 2013-07-17T16:43:09.093 に答える