为所有页面共有的每个部分视图发送适当的模型

时间:2014-02-13 19:17:13

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

我有两种形式:一种是注册时事通讯,另一种是在网站上搜索:  http://nsa31.casimages.com/img/2014/02/13/140213065557598803.png

因为我需要验证客户端和服务器端我为每个表单创建了2个ViewModel来指定验证属性和错误消息:

订阅模型(文件:SubscribeModel.cs):

using System.ComponentModel.DataAnnotations;

namespace SoscomAppMvc.Models
{
    public class SubscribeModel
    {
        [Required(ErrorMessage = "Veuillez saisir votre adresse mail pour s'inscrire ...")]
        [EmailAddress(ErrorMessage = "Veuillez saisir une adresse mail valide \"Ex: mail@domaine.com\"")]
        public string SubEmail { get; set; }
    }
}

Serach Model(文件:SearchModel.cs):

using System.ComponentModel.DataAnnotations;

namespace SoscomAppMvc.Models
{
    public class SearchModel
    {
        [Required(ErrorMessage = "Veuillez saisir votre mot clé avant de lancer la recherche ...")]
        public string Key { get; set; }
    }
}

这两个表单从2个部分视图渲染到布局视图中:

订阅部分视图(文件:Shared / Subscribe.cshtml):

@model SoscomAppMvc.Models.SubscribeModel

@using (Html.BeginForm("Subscribe", "Soscom"))
{
    @Html.TextBoxFor(m => m.SubEmail, new { placeholder = "Email pour s'inscrire à la newsletter", @class = "subscribebox" })
    <input class="subscribeBtn" type="submit" value="s'inscrire">
    @Html.ValidationMessageFor(m => m.SubEmail)
}

搜索部分视图(文件:Shared / Serach.cshtml):

@model SoscomAppMvc.Models.SearchModel

@using (Html.BeginForm("Search", "Soscom", FormMethod.Get))
{
    @Html.TextBoxFor(m => m.Key, new { placeholder = "Rechercher un produit, une solution ...", @class = "textfeild" })
    <input class="searchbutton" type="submit" value="Go">
}

将这两个部分视图呈现到布局页面的代码(文件:Shared / _Layout.cshtml)

 <!DOCTYPE html>
 <html>
     <head>
     ....
     </head>
     <body>
         <header>
             <div id="banner">
                 @Html.Partial("~/Views/Shared/Subscribe.cshtml")
             </div>
             <div id="navpan">
                 <nav>
                     <ul>
                         <li>@Html.ActionLink("Soscom", "Index", "Soscom")</li>
                         ....
                     </ul>
                 </nav>
                 <div id="searchbar">
                     @Html.Partial("~/Views/Shared/Search.cshtml")
                 </div>
         </header>
         ....
         <section>
             @RenderBody()
         </section>
         ....
     </body>
</html>

我还创建了2个处理发布数据的操作:

订阅行动:

[HttpPost]
public ViewResult Subscribe(SubscribeModel model)
{
    if (!ModelState.IsValid)
        return View("SubscribeErrors", model);

    // saveMailToDB(model.SubEmail)
    return View("SubscribeResult", model);
}

搜索操作:

[HttpGet]
public ViewResult Search(SearchModel model)
{
    if (!ModelState.IsValid)
        return View("SearchErrors", model);

    // searchFromDB(key, ResultSearchModel); return View(ResultSearchModel); 
    return View("SearchResult");
}

现在当我运行应用程序时,一切看起来都很好,但是当我发布订阅表单时,我收到此错误:

The model item passed into the dictionary is of type "SubscribeModel", but this dictionary requires a model item of type "SearchModel"

我在搜索表单中遇到同样的错误:

The model item passed into the dictionary is of type "SearchModel", but this dictionary requires a model item of type "SubscribeModel"

如何摆脱这些错误,

谢谢

2 个答案:

答案 0 :(得分:1)

是的。你不能使用模型的局部,除非你可以为它模型提供它,某些方式。默认情况下,如果你没有将模型传递给局部模型,Razor将传递主视图的模型,这就是你得到这些错误的原因。

可以简单地传递适当模型的新实例:

@Html.Partial("~/Views/Shared/Subscribe.cshtml", new Namespace.To.SubscribeModel());

但是,这有点笨重。更好的方法是在这些场景中使用子操作:

[ChildActionOnly]
public ActionResult Subscribe()
{
    return PartialView("Subscribe", new SubscribeModel());
}

然后在你看来:

@Html.Action("Subscribe", "MyController");

答案 1 :(得分:0)

我认为您必须将空模型传递给每个部分视图。所以你的_Layout.cshtml应该是这样的:

<!DOCTYPE html>
<html>
    <head>
     ....
    </head>
    <body>
        <header>
            <div id="banner">
                 @Html.Partial("~/Views/Shared/Subscribe.cshtml", new SubscribeModel())
            </div>
            ....
            <div id="searchbar">
                 @Html.Partial("~/Views/Shared/Search.cshtml", new SearchModel())
            </div>
        </header>
        ....
        <section>
            @RenderBody()
        </section>
        ....
    </body>
</html>