1

I have an LogInOrRegister page in my application, that calls 2 child actions LogInOrRegister.cshtml

@{
    ViewBag.Title = "Log in";
}

@Html.Action("Login", "Account", new { returlUrl = ViewBag.ReturnUrl})
@Html.Action("Register", new { returlUrl = ViewBag.ReturnUrl})

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

The Login PartialView is:

@model Com.WTS.Portal.Models.LoginModel
<hgroup class="title">
    <h1>@ViewBag.Title</h1>
</hgroup>

<section id="loginForm">
<h2>Use a local account to log in.</h2>
@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
    <legend>Log in Form</legend>
    <ol>
        <li>
            @Html.LabelFor(m => m.Email)
            @Html.TextBoxFor(m => m.Email)
            @Html.ValidationMessageFor(m => m.Email)
        </li>
        <li>
            @Html.LabelFor(m => m.Password)
            @Html.PasswordFor(m => m.Password)
            @Html.ValidationMessageFor(m => m.Password)
        </li>
        <li>
            @Html.CheckBoxFor(m => m.RememberMe)
            @Html.LabelFor(m => m.RememberMe, new { @class = "checkbox" })
        </li>
    </ol>
    <input type="submit" value="Log in" />
    </fieldset>
}
</section>

My AccountController.cs contains the following code:

    [AllowAnonymous]
    public PartialViewResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return PartialView();
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public PartialViewResult Login(LoginModel model, string returnUrl)
    {
        if (ModelState.IsValid && WebSecurity.Login(model.Email, model.Password, persistCookie: model.RememberMe))
        {
            RedirectToLocal(returnUrl);
        }

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

I see correctly the 2 partial view the I GET the page LogInOrRegister.cshtml

When I submit the form, if there is validation errors in the form, the view is displayed (no layout) instead of the partial view that should be part of the LogInOrRegster

Any idea ?

Raphaël
  • 427
  • 5
  • 14

3 Answers3

2

Ok, I found te solution. By passing route parameters to the partial view form :

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))

I think we change the behaviour of the child action. Only by removing the route attribute :

@using (Html.BeginForm())

The PartialView is rendered in its container. Also, we can define the POST action as ChildActionOnly, it still work:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
[ChildActionOnly]
public PartialViewResult Login(LoginModel model, string returnUrl)
Raphaël
  • 427
  • 5
  • 14
  • If any of that fixed it, I'm not sure how. Except maybe adding `ChildActionOnly` prevented this particular `Login` action from being called. Do you have another `Login` action that actually returns a `ViewResult`? Long and short, if your action returns a `PartialViewResult` then all you're going to get is a partial view, i.e. no layout. The only way to get a layout is by returning `ViewResult`. – Chris Pratt Sep 12 '14 at 18:18
1

So if you look at the discussion about found here https://stackoverflow.com/a/10253786/30850 you will see that the ChildActionOnlyAttribute is used so that an Action can be rendered inside of a view but can not be served to the browser.

Community
  • 1
  • 1
runxc1 Bret Ferrier
  • 8,096
  • 14
  • 61
  • 100
  • And do you know why when I remove the ChildActionOnly attribute, when return PartialView() is called, I get the partial view with no layout ? – Raphaël Sep 12 '14 at 16:32
  • PartialView is supposed to return a partial view with no layout. If you want the layout you simply return a View – runxc1 Bret Ferrier Sep 16 '14 at 23:06
0

If the return type is PartialViewResult,specify the partialview name along with model in the method public PartialViewResult Login(LoginModel model, string returnUrl) otherwise use ActionResult as return type.ActionResult is an abstract class where as PartialViewResult is a subclass.

Adersh M
  • 596
  • 3
  • 19