开发者

Strongly-typed layout and strongly-typed page which wants to use it

I have a problem with architecture and passing models in my Asp.NET MVC app... Here's the thing.

I created strongly-typed layout, because I have login panel inside layout (as a partial view), which needs his model. And now I have some views (registration and contact page), which use this layout and I don't know how to pass them their models...

My question is how to solve that problem e.g. by another constructing, but possibly without doubling a code. 开发者_运维技巧Building ViewModel with all possible Models for pages which used this Layout doesn't look like an option (even if there is some way to pass model further to @RenderBody()).

My code

Login panel (partial view)

@model Models.Home.LoginModel
@{
    ViewBag.Title = "Login";
}
@using (Ajax.BeginForm(new AjaxOptions() { UpdateTargetId = "login" }))
{
    //some form fields here
}

Layout

@model Models.Home.LoginModel
<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div id="login">
        @Html.Partial("Account/_Login", @Model)
    </div>
    <div id="main">
        @RenderBody()
    </div>
</body>

Page

@model Models.Home.RegisterModel
@{
    ViewBag.Title = "Registration";
}
@using (Ajax.BeginForm(new AjaxOptions() { UpdateTargetId = "registerDialog" }))
{
    //some form fields here
}

Controller action for Login

[HttpPost]
public ActionResult Index(LoginModel model, string returnUrl)
{
    // If we got this far, something failed, redisplay form
    if (Request.IsAjaxRequest())
    {
        return PartialView("Account/_Login", model);
    }
    else
    {
        return View(model);
    }
}

Controller action for Register

[HttpPost]
public ActionResult Register(RegisterModel registerModel)
{
    return View(registerModel);
}

I simplified everything by removing unnecessary lines of code.


The easiest way to do this without repeating code would probably be to implement your login logic using a Child Action (instead of a partial view).

Child Actions are like partial views but they also have their own controller method which can be used to load all the model that the partial view requires.

An example:

Controller

[ChildActionOnly]
public ActionResult Login() {
     LoginModel model;
     // do login check, set model
     return View("_Login", model);
}

Layout

<body>
<div class="header">@Html.Action("Login")</div>
@RenderBody()
</body>

_Login.cshtml

@model LoginModel
@if(Model.IsLoggedIn) {
    <text>Welcome @Model.UserName</text>
} else {
    .. do ajax form stuff here ...
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜