سؤال

I had this working yesterday and why it has stopped working is completely beyond me. I have the following, basic scenario:

There are two types of roles in my application, Tenant and Landlord. When a Tenant logs in they should be directed to the Tenant profile page, the same goes for Landlord (at the moment I'm only working with Tenants).

Here's the workflow of the scenario:

  1. A user logs in via _LoginPartial, I'm sure the logic in the partial is correct, but for some reason SO won't let me propertly paste the razor code in here...

  2. Clicking the log in button calls the Login ActionResult in the AccountController. The method validates the user and checks to see what role they are in. If the user is in role Tenant they should be redirected to the MyProfile ActionResult in the TenantsController. Code for Login:

    public ActionResult Login(LoginModel model)
    {
        if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
        {
            if (Roles.IsUserInRole("Tenant"))
            {
                return RedirectToAction("MyProfile", "Tenants");
            }
        }
    
        // If we got this far, something failed, redisplay form
        ModelState.AddModelError("", "The user name or password provided is incorrect.");
        return View(model);
    }
    
  3. Upon being invoked MyProfile should display the user's profile. Code for MyProfile ActionResult:

    public ActionResult MyProfile()
    {
        var db = new LetLordContext();
        var currentTenant = db.UserProfile.First(t => t.UserName == HttpContext.User.Identity.Name);
    
        return View(currentTenant);
    }
    

As I said this was working yesterday, but I get the following error when I click the login button on _RegisterPartial:

The view 'Login' or its master was not found or no view engine supports the searched locations. The following locations were searched: ~/Views/Account/Login.aspx ~/Views/Account/Login.ascx ~/Views/Shared/Login.aspx ~/Views/Shared/Login.ascx ~/Views/Account/Login.cshtml ~/Views/Account/Login.vbhtml ~/Views/Shared/Login.cshtml ~/Views/Shared/Login.vbhtml

Why is MVC looking for a view called Login? I havn't specified it to route to a view called Login. Is there something wrong with my routing/controller logic? Help would be much appreciated.

هل كانت مفيدة؟

المحلول 5

The problem was being caused by using this...

if (Roles.IsUserInRole("Tenant"))

...instead of this:

if (Roles.IsUserInRole(model.UserName, "Tenant"))

The former can be called after a user is logged in. It seems the latter has to be used when called inside Login - may have something to with the user not being in the session / fully logged in etc.

It works anyway.

نصائح أخرى

Because these lines are executed:

// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);

Apparently either login attempt failed, or input was invalid. Now the last return of the Login action is executed. Since you have not stated the view's name directly, the naming convention tries to find view with the same name as the action (Login in this case). Try specifying View name explicitly:

return View("ViewName", model);

Your Login action of AccountsController returns a View(model).

By convention, MVC will look for a view name matching the action name in the folder matching the controller name. Hence it is looking for Login view under Accounts controller.

Do the following trick and check if it prints "Hello User" on the browser, if yes then it means that it is not validating the user and redirecting to login page as mentioned at the bottom of your method.

public ActionResult Login(LoginModel model)
{
    if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
    {
        if (Roles.IsUserInRole("Tenant"))
        {
            return RedirectToAction("MyProfile", "Tenants");
        }
    }

    // If we got this far, something failed, redisplay form
    ModelState.AddModelError("", "The user name or password provided is incorrect.");
    return Content("Hello User");
}

Open your web.config.

Look here:

<system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login" timeout="2880" />
    </authentication>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top