MVC4 PartialViewResult return a view and not a PartialView

7.5k Views Asked by At

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 ?

3

There are 3 best solutions below

1
Raphaël On BEST ANSWER

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)
2
runxc1 Bret Ferrier On

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.

0
Adersh M On

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.