Wrox Professional ASP.NET 4.0 MVC 4
本の 179 ページ (「Web アプリケーションのセキュリティ ベクターについて」の章)から次のコードをコピーしました。コードを作成しprotected
、アプリケーション全体の抽象化にユーティリティ メソッドとして格納するという少しの変更が加えられています。Controller
protected ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
上記のコードは、MVC アプリケーションをオープン リダイレクト攻撃から保護することを目的としていますが、これは問題の対象ではありません。
コードは明らかに整形式で、コンパイルされ、動作することを信頼しています。
上記のコードを次のワンライナーに「賢く」変更すると、問題が発生します
return (Url.IsLocalUrl(returnUrl)) ? Redirect(returnUrl) : RedirectToAction("Index", "Home");
上記のワンライナーは、拡張コードとまったく同じことを行うはずです (いいえ、ReSharper は私に置き換えを提案しませんでした。それは私のイニシアチブでした)。
コンパイル エラーは次のとおりですthere is no implicit conversion between System.Web.Mvc.RedirectResult and System.Web.Mvc.RedirectToRouteResult
。
ReSharper が助けに来て、次の変更を提案します
return (Url.IsLocalUrl(returnUrl)) ? (ActionResult) Redirect(returnUrl) : RedirectToAction("Index", "Home");
問題は、「なぜ Redirect メソッドをキャストする必要があるのか」ということです。
と の両方が (F12 で検証された)のサブクラスを返し、Redirect
そのサブクラスが関数の戻り値であるため、自動的に互換性があるはずです。または、少なくとも、私の C# の知識では、両方のコードがコンパイルされるか、両方ともコンパイルされないかのどちらかです。RedirectToAction
ActionResult
より一般的に言えば、この質問は次のように再定式化できます。
クラスA、B、Cがあるとします
abstract class A {}
class B: A{}
class C: A{}
そして、次の関数が機能するとします
private A Function(){
if (condition) return new B();
else return new C();
}
次のワンライナーがコンパイルされないのはなぜですか?
private A Function(){
return (condition) ? new B(): new C();
}