I have copied the following code from Wrox Professional ASP.NET 4.0 MVC 4
book, page 179 (Chapter "Understanding the Security Vectors in a Web Application") with the little modification of making it protected
and storing as utility method in my abstract application-wide Controller
protected ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
The code above is aimed at securing the MVC application from open redirection attacks, which are not subject of the question.
The code is obviously well-formed, compiles and I trust it works.
The problem arises when "smartly" changing the code above into the following one-liner
return (Url.IsLocalUrl(returnUrl)) ? Redirect(returnUrl) : RedirectToAction("Index", "Home");
The one-liner above is supposed to do exactly the same as the extended code (no, ReSharper didn't suggest me to replace, it was my initiative).
The compilation error is the following: there is no implicit conversion between System.Web.Mvc.RedirectResult and System.Web.Mvc.RedirectToRouteResult
.
ReSharper then comes to help and suggests the following modification
return (Url.IsLocalUrl(returnUrl)) ? (ActionResult) Redirect(returnUrl) : RedirectToAction("Index", "Home");
The question is "why do I have to cast Redirect method"?
Since both Redirect
and RedirectToAction
return a subclass of ActionResult
(verified via F12) and that subclass is the return value of the function, it should be automatically compatible. Or at least, in my knowledge of C#, either both codes compile or they both don't.
To be more general, the question could be reformulated as follows:
Suppose I have class A, B and C
abstract class A {}
class B: A{}
class C: A{}
And suppose the following function works
private A Function(){
if (condition) return new B();
else return new C();
}
Why the following one-liner doesn't compile?
private A Function(){
return (condition) ? new B(): new C();
}
See Question&Answers more detail:
os