MVC3多个模型 - 单页

时间:2012-01-15 02:46:25

标签: asp.net-mvc asp.net-mvc-3 razor

我有一个_layout页面,其中有一个登录框(部分视图),该视图有自己的模型。所以控制器看起来像这样:

        public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(LoginModel loginModel)
    {
        if(ModelState.IsValid)
        {
            var g = new GallaryImage();
            var user = g.LoginUser(loginModel.Username, loginModel.Password);
            if(user != null) 
            {
                FormsAuthentication.SetAuthCookie(user.username, false);
                return RedirectToAction("Index", "Home");
            }
            ModelState.AddModelError("", "Invalid Username/Password");
        }
        return View(loginModel);
    }

但是,只要我的主要内容页面需要模型,我的网络应用程序就会失败,因为“登录”框需要LoginModel类型,但我的内容页面正在发送不同的模型:

这是我的主索引屏幕的GET方法:

 public ActionResult Index()
    {
        IndexModel model = new IndexModel();
        var g = new GallaryService.GallaryImage();
        var i = g.GetRandomImage();

        if (i != null)
            model.RandomImageUrl = "~/Images/Watermarks/" + i.filename;
            return View(model);
    }

因此,我的主要内容页面有一个IndexModel,但我的部分视图有一个LoginModel。当我尝试运行它时,我收到一个错误:

“传递到字典中的模型项的类型为'GalleryPresentation.Models.IndexModel',但此字典需要类型为'GalleryPresentation.Models.LoginModel'的模型项。”

我该如何处理 - 我的_layout需要登录框的模型。

根据要求,这是Loginbox cshtml文件。

    @using GalleryPresentation.Models
@model LoginModel

<script src="../../Scripts/jquery.validate.min.js" type="text/javascript"></script>
@using (Html.BeginForm("index", "Account", FormMethod.Post))
{
    <table class="smallBox">
        <tr>
            <td>@Html.LabelFor(m => m.Username)</td>
            <td>@Html.TextBoxFor(m => m.Username, new { @class = "smallText" })</td>
            <td>@Html.LabelFor(m => m.Password)</td>
            <td>@Html.PasswordFor(m => m.Password, new { @class = "smallText" })</td>
        </tr>
        <tr>
            <td colspan="4" align="right"><input type="submit" value="Login"/></td>
        </tr>
        <tr>
            <td colspan="2">@Html.ValidationSummary()</td>
        </tr>
    </table>

}

Index.cshtml文件(主要内容屏幕)包含:

    @using GalleryPresentation.Models
@model IndexModel
@{
    ViewBag.Title = "Craig and Melanie's Digital Moments";
}

<br/>
<div style="text-align: center">
    <img src="@Url.Content( Model.RandomImageUrl)" alt="@ViewBag.Title" />
</div>

1 个答案:

答案 0 :(得分:1)

这样的问题并不总是最容易回答,因为没有直接的解决方案。虽然应该考虑几个问题。如果可能,我建议您在单独的视图中处理登录验证错误。然后,小型登录框的部分视图不需要强类型视图模型。

没有完美的解决方案,但我不认为你总是在每个呈现依赖于_Layout的视图的请求上创建LoginModel对象是很有意义的。下面的解决方案主张创建一个单独的登录视图,该视图可用于显式登录尝试和处理任何登录失败。

如果您在此过程中遇到任何问题,请在评论中随意提问,我会尽力回答。

登录框

@using (Html.BeginForm("Index", "Account"))
{
    <table class="smallBox">
        <tr>
            <td>Username</td>
            <td>@Html.TextBox("Username", new { @class = "smallText" })</td>
            <td>Password</td>
            <td>@Html.Password("Password", new { @class = "smallText" })</td>
        </tr>
        <tr>
            <td colspan="4" align="right"><input type="submit" value="Login"/></td>
        </tr>
    </table>
}

帐户控制器

public ActionResult Login()
{
    return View();
}

public ActionResult RetryLogin()
{
    ModelState.AddModelError(null, "The Username or Password you entered is invalid.  Please try again.");
    return View("Login");
}

[HttpPost]
public ActionResult Index(LoginModel loginModel)
{
    if(ModelState.IsValid)
    {
        var g = new GallaryImage();
        var user = g.LoginUser(loginModel.Username, loginModel.Password);
        if(user != null) 
        {
            FormsAuthentication.SetAuthCookie(user.username, false);
            return RedirectToAction("Index", "Home");
        }

        ModelState.AddModelError("", "Invalid Username/Password");
    }

    return RedirectToAction("RetryLogin");
}

登录视图

@using (Html.BeginForm("Index", "Account"))
{
    @Html.ValidationSummary()
    <!-- login form here -->
}