views:

289

answers:

1

Hello, I have LogOn.ascx control which is located on master page site.master:

<% Html.RenderPartial("LogOn"); %>

This control contains form with email and password textboxed which is submitted to LoginController:

public class LoginController : Controller
{
     ...
    [HttpPost]
    public ActionResult Login(string email, string password)
    {
        if (this.userRepository.ExistByEmail(email) &&
            this.authenticationService.IsPasswordMatches(email, password))
        {
            var user = this.userRepository.GetByEmail(email);
            this.userSession.LogIn(user);
            return PartialView("LogOn", user);
        }
        return PartialView("LogOn");
    }
}

So if user is successfully authenticated I pass user into model of LogOn partial view (simplified):

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Core.Model.User>" %>
<%= this.Model.FirstName %>

I have 2 problems with this code:

  1. After calling return PartialView("LogOn") I get exception "The IControllerFactory 'UI.Services.ControllerFactory' did not return a controller for the name 'default.aspx'" This issue is solved by adding routing for "default.aspx". But why request goes to "default.aspx" when I call return PartialView(..) ? (I'm using VS web server)

  2. I get null reference exception inside LogOn.ascx even if user was successfully authenticated and non-null value was passed into PartialView on the following line:

    <%= this.Model.FirstName %>

Does anybody have an idea why user is not passed into LogOn.ascx? Thanks

A: 

I assume that your login form is doing a standard submit back to the server (i.e. sending the whole page) rather than an AJAX post?

If that's the case, then your action result from the Login action should be a whole view, not a partial - there's no page to host the partial in.

Following on from this as you've added a route for Default now, you're not actually passing the User object to the partial as you call it from the page:

<% Html.RenderPartial("LogOn"); %>

You'd need to be calling this with the user, which would mean that you need to be adding the user to either the ViewData or the models that you're passing back if you're not using membership providers.

I assume you're doing some checks in the LogOn partial to check if the request is authenticated other than checking to see if the User object has been passed in - because most of your calls to this partial will be from the master page which doesn't pass in the User object, these will mostly fail.

Zhaph - Ben Duguid
Ben, thank you for reply. You right - this is non-ajax call and in LogOn.ascx there is a check to determine is current request is authenticated (I stripped it in example).I'm starting with MVC so I can misunderstand some concepts. So I changed 'return PartialView("LogOn", user)' on 'return View("LogOn", user)' - the same result.I didn't get your point about "You'd need to be calling <% Html.RenderPartial("LogOn"); %> with the user". I thought that View shares its ViewData and model with nested partial view (if partial view has no its own explicitly passed view data). Or I'm wrong?
alex