Asp.net mvc3 – Controller method returns View(viewName, string) but weirdness ensues

asp.net-mvc-3

has anyone seen this issue? I'm an ASP.NET MVC newbie. I have an ASP.NET MVC 3 site that uses .aspx and .ascx views. Throughout the site, I use return View() or return View(viewName) in my controller methods, which directs to the appropriate aspx/ascx view. However, in my stock AccountController (modified to use DotNetOpenAuth), I take the same approach, but the MVC framework doesn't seek out aspx or ascx views. Instead, it's searching the path for .cshtml or .vbhtml views (Razor engine I'm assuming). Why woulnd't it just seek out aspx and ascx views like the rest of my site? Controller method follows:

public ActionResult Authenticate()
{
    var response = openid.GetResponse();
    var statusMessage = "";
    if (response == null)
    {
        Identifier id;
        //make sure your users openid_identifier is valid.
        if (Identifier.TryParse(Request.Form["openid_identifier"], out id))
        {
            try
            {
                //request openid_identifier
                return openid.CreateRequest(Request.Form["openid_identifier"])
                   .RedirectingResponse.AsActionResult();
            }
            catch (ProtocolException ex)
            {
                statusMessage = ex.Message;
                return View("LogOn", statusMessage);
            }
        }
        else
        {
            statusMessage = "Invalid identifier";
            return View("LogOn", statusMessage);
        }
    }
    else
    {
        //check the response status
        switch (response.Status)
        {
            //success status
            case AuthenticationStatus.Authenticated:
                Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
                FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false);

                //TODO: response.ClaimedIdentifier, to login or create new account 

                return RedirectToAction("Index", "Home");

            case AuthenticationStatus.Canceled:
                statusMessage = "Canceled at provider";
                return View("LogOn", statusMessage);

            case AuthenticationStatus.Failed:
                statusMessage = response.Exception.Message;
                return View("LogOn", statusMessage);
        }
    }
    return View("LogOn");
}

Error detail follows:

The view 'LogOn' or its master was not
found or no view engine supports the
searched locations. The following
locations were searched:
~/Views/Account/Canceled at
provider.master
~/Views/Shared/Canceled at
provider.master
~/Views/Account/LogOn.cshtml
~/Views/Account/LogOn.vbhtml
~/Views/Shared/LogOn.cshtml
~/Views/Shared/LogOn.vbhtml
~/Views/Account/Canceled at
provider.cshtml
~/Views/Account/Canceled at
provider.vbhtml
~/Views/Shared/Canceled at
provider.cshtml
~/Views/Shared/Canceled at
provider.vbhtml

Description: An unhandled exception
occurred during the execution of the
current web request. Please review the
stack trace for more information about
the error and where it originated in
the code.

Exception Details:
System.InvalidOperationException: The
view 'LogOn' or its master was not
found or no view engine supports the
searched locations. The following
locations were searched:
~/Views/Account/Canceled at
provider.master
~/Views/Shared/Canceled at
provider.master
~/Views/Account/LogOn.cshtml
~/Views/Account/LogOn.vbhtml
~/Views/Shared/LogOn.cshtml
~/Views/Shared/LogOn.vbhtml
~/Views/Account/Canceled at
provider.cshtml
~/Views/Account/Canceled at
provider.vbhtml
~/Views/Shared/Canceled at
provider.cshtml
~/Views/Shared/Canceled at
provider.vbhtml

Source Error:

An unhandled exception was generated
during the execution of the current
web request. Information regarding the
origin and location of the exception
can be identified using the exception
stack trace below.

Stack Trace:

[InvalidOperationException: The view
'LogOn' or its master was not found or
no view engine supports the searched
locations. The following locations
were searched:
~/Views/Account/Canceled at
provider.master
~/Views/Shared/Canceled at
provider.master
~/Views/Account/LogOn.cshtml
~/Views/Account/LogOn.vbhtml
~/Views/Shared/LogOn.cshtml
~/Views/Shared/LogOn.vbhtml
~/Views/Account/Canceled at
provider.cshtml
~/Views/Account/Canceled at
provider.vbhtml
~/Views/Shared/Canceled at
provider.cshtml
~/Views/Shared/Canceled at
provider.vbhtml]
System.Web.Mvc.ViewResult.FindView(ControllerContext
context) +315050
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext
context) +129
System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext
controllerContext, ActionResult
actionResult) +13
System.Web.Mvc.<>c_DisplayClass1c.b_19()
+23 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter
filter, ResultExecutingContext
preContext, Func1 continuation) +260
System.Web.Mvc.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b()
+19 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext
controllerContext, IList
1 filters,
ActionResult actionResult) +177
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext
controllerContext, String actionName)
+343 System.Web.Mvc.Controller.ExecuteCore()
+116 System.Web.Mvc.ControllerBase.Execute(RequestContext
requestContext) +97
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext
requestContext) +10
System.Web.Mvc.<>c_DisplayClassb.b_5()
+37 System.Web.Mvc.Async.<>c_DisplayClass1.b_0()
+21 System.Web.Mvc.Async.<>c_DisplayClass81.<BeginSynchronous>b__7(IAsyncResult
_) +12 System.Web.Mvc.Async.WrappedAsyncResult
1.End()
+62 System.Web.Mvc.<>c
_DisplayClasse.b_d()
+50 System.Web.Mvc.SecurityUtil.b
_0(Action
f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action
action) +22
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult
asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult
result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
+8841105 System.Web.HttpApplication.ExecuteStep(IExecutionStep
step, Boolean& completedSynchronously)
+184

Thanks
Shan

Best Answer

The key is in the first line of your exception:

The view 'LogOn' or its master was not found or no view engine supports 
the searched locations. The following locations were searched: 
~/Views/Account/Canceled at provider.master 

If you pass two strings to View(), the first one is the view name and the second one is the name of the master view or template to use. If you want to pass statusMessage as the model for your view you can cast it to object which will force calling the overridden View() method where you pass a model:

return View("LogOn", (object)statusMessage);

You are apparently getting the "Cancelled at provider" message and passing that as the master page name to use. If the "Logon.aspx" view used a master page and you had a master page "Canceled at provider.master" in your Shared view folder for instance, this would load the "LogOn.aspx" view and force it to use the "Canceled at provider.master" master page even if it was setup to use a different master page by default:

string statusMessage = "Canceled at provider";
return View("LogOn", statusMessage);
Related Topic