3

以下のコントローラーを考えると

public class MyController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Test()
    {
        return RedirectToRoute(new { action = "Index" });
    }

}

そしてこのルーティング

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

    routes.MapRoute(
        "Route1",
        "Route1",
        new {controller = "Account", action = "Index"});

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );

}

My/Test を参照すると、MyController の Test Action が期待どおりにヒットします。次に、RedirectToRouteアクションを「インデックス」として指定したため、結果は Route1 を使用します。また、コントローラーを指定しなかったため、デフォルトで「アカウント」になります。これにより、AccountController の Index アクションが期待どおりにヒットします。

ルーティングを以下のコードに変更すると、動作が異なり、期待どおりに動作しません。My/Test を参照すると、HomeController の Index アクションではなく、MyController の Index アクションにリダイレクトされます。

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional });

が使用されると、MVC は現在のコントローラーを推測するのでRedirectToAction、これは MyController のインデックス アクションにリダイレクトされますが、MVC ソースのコード コメントはRedirectToRoute現在のコントローラーを推測しないと述べています。

なぜこれが起こっているのか誰にも分かりますか?

4

1 に答える 1

2

現在のリクエスト値が常に使用されます。Url.ActionUrl.RouteUrl(によって使用されるRedirectToRoute)の違いは、とのUrl.Actionnull 値を現在の要求値 (MVC では決して null ではない)で上書きし、上書きしない (null のままにする) ことです。null 値は、存在しない、省略された、または未定義の値と同じではないことに注意してください。controlleractionUrl.RouteUrl

ルーティングについて書いたこの投稿をチェックしてください。

メソッドの UrlHelper.Action セットは、actionName および controllerName 文字列パラメーターを取ります。これらのメソッドの呼び出しは、 と同等のものに変換できますUrl.RouteUrl(new { action = actionName, controller = controllerName })パラメーターなしでデフォルト値に null または空の文字列を使用できないで前に確認したように、actionName および/または controllerName に null を使用すると、目的のルートの一致に失敗する可能性があります。このため、Url.Action は、actionName や controllerName に null が使用されている場合は常に、現在のリクエスト コントローラーとアクションの値を使用します。


明確にするために、最初の例は次の理由で Route1 に一致します。

  1. ルートにはトークンがありません。つまり、値が一致する必要はありません。
  2. action の値はデフォルト値と一致します。
  3. コードはコントローラーの値を提供しません。値が指定されている場合、一致するには「アカウント」である必要があります。

2 番目の例では、ルートにコントローラー トークンが含まれており、値が提供されていないため、現在の要求値から取得された My がコントローラーの値として使用されます。

于 2012-08-02T14:22:31.147 に答える