使用两个不同的模型在父视图中加载局部视图

时间:2015-01-27 00:31:56

标签: jquery asp.net-mvc razor twitter-bootstrap-3

我的情况很简单,但我还没有完全掌握在父视图中使用可重用下拉列表部分视图的技术。

当我的视图尝试渲染时(在检索到正确的数据后),我收到以下错误消息:

The model item passed into the dictionary is of type 'YeagerTechDB.Models.Category', but this dictionary requires a model item of type 'YeagerTechDB.ViewModels.Categories.CategoriesDDL'.

错误发生在该行:

@Html.Partial("_SelectCategoryProjects");

我知道错误意味着什么,但不知道如何解决它...我一直认为,部分视图可以包含与其父视图不同的模型。 / p>

我非常感谢答案,因为我显然错误地使用了这种技术。

我的EnumDropDownListFor的模型

using System;
using System.Runtime.Serialization;
using YeagerTechDB.Enums;

namespace YeagerTechDB.ViewModels.Categories
{
    [Serializable, DataContract(IsReference = true)]
    public class CategoriesDDL
    {
        [DataMember]
        public short CategoryID { get; set; }

        [DataMember]
        public CategoryTypeEnum CategoryType { get; set; }
    }
}

部分查看内容

@model YeagerTechDB.ViewModels.Categories.CategoriesDDL

@{
    ViewBag.Title = "CategoriesDDL";
}

<div class="form-group">
    <br />
    @Html.LabelFor(model => model.CategoryType, new { @class = "control-label required pull-left col-lg-3 col-md-3 col-sm-3 col-xs-3" })
    <div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
        @Html.EnumDropDownListFor(model => model.CategoryType, "Select Category", new { @class = "form-control" })
    </div>
</div>

相关控制器代码

// POST: Categories/CategoryProjects/Details
public ActionResult Details()
{
    return View();
}

[HttpPost]
// POST: Categories/CategoryProjects/Details/5
public async Task<ActionResult> Details(short id)
{
    if (id == 0)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Category category = await db.GetProjectsByCategoryIDAsync(id);

    if (category == null)
    {
        return HttpNotFound();
    }

    return View(category);
}

Pertinent JS

function contentDetailsCatProjects()
{
    //var Url = $("#ddlCatProjects").val();

    $('#CategoryType').change(function (e)
    {
        getCatProjects();

        return false;
    });
}

function getCatProjects()
{
    var category_Input = {
        id: $('#CategoryType').val()
    };

    var Url = $("#categoryProjectsUrl").val();

    $.ajax({
        url: Url,
        data: JSON.stringify(category_Input),
        //data: AddAntiCSRFToken(JSON.stringify(category_Input)),
        dataType: "html",
        type: "POST",
        contentType: "application/json; charset=utf-8",
        async: true,
        success: function (data, status)
        {
            if (status == "success")
            {
                //data retrieved
            }
        },
        error: function (data, status, xhr)
        {
            if (xhr == "Not Found")
            {
                bootbox.dialog({
                    message: "No Projects exist for selected Category!",
                    title: "Category",
                    buttons: {
                        danger: {
                            label: "Warning!",
                            className: "btn-warning"
                        }
                    }
                });
            }
            else
            {
                bootbox.dialog({
                    message: "Projects cannot be retrieved for selected Category!" + '\n' + status + '\n' + xhr + '\n' + data,
                    title: "Category",
                    buttons: {
                        danger: {
                            label: "Danger!",
                            className: "btn-danger"
                        }
                    }
                });
            }
        }
    });
};

相关视图代码

@model YeagerTechDB.Models.Category

@{
    ViewBag.Title = "Categories";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div>
    @Html.Partial("_SelectCategoryProjects");
</div>

@if (Model != null)
{ 
<div>
    <table class="table">
        <tr>
            <th>
                Associated Projects for selected Category
            </th>
            <th></th>
        </tr>
        <tr>
            <th>Project ID</th>
            <th>Project Description</th>
            <th>Project Name</th>
            <th>Quote</th>
            <th>Notes</th>
            <th>Created Date</th>
            <th>Updated Date</th>
        </tr>
        <tbody>
            @foreach (var item in Model.Projects)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(m => item.ProjectID)
                    </td>
                    <td>
                        @Html.DisplayFor(m => item.Description)
                    </td>
                    <td>
                        @Html.DisplayFor(m => item.Name)
                    </td>
                    <td>
                        @Html.DisplayFor(m => item.Quote)
                    </td>
                    <td>
                        @Html.DisplayFor(m => item.Notes)
                    </td>
                    <td>
                        @Html.DisplayFor(m => item.CreatedDate)
                    </td>
                    <td>
                        @Html.DisplayFor(m => item.UpdatedDate)
                    </td>
                </tr>
            }
        </tbody>
    </table>
</div>
}

<div>
    @Html.Hidden("categoryProjectsUrl", Url.Action("Details", "CategoryProjects", new { area = "Categories" }))
</div>

@section Scripts {
    <script>
        $(document).ready(function ()
        {
            if (typeof contentDetailsCatProjects == "function")
                contentDetailsCatProjects();
        });
    </script>
    }

2 个答案:

答案 0 :(得分:1)

部分视图可以引用父模型以外的模型。请参阅描述各种重载的this article

在您的情况下,您需要一种方法来实例化CategoriesDDL的实例,以便为_SelectCategoryProjects提供它所期望的模型。可能有很多方法可以做到这一点,但我不建议将此作为Details的一部分。根据您的具体情况,您可以动态创建CategoriesDDL实例,也可以实现可以提供对象实例的静态方法。

要动态制作,请将@Html.Partial("_SelectCategoryProjects")替换为@Html.Partial("_SelectCategoryProjects", new CategoriesDDL {...} )

或者,使用静态方法......

public static class MyCategoryControl
{
   public static CategoriesDDL GetCategoriesDDL() { ...some code to return instance of CategoriesDDL.. }
}

然后,将@Html.Partial("_SelectCategoryProjects")替换为@Html.Partial("_SelectCategoryProjects", MyCategoryControl.GetCategoriesDDL())

答案 1 :(得分:1)

您的主视图模型为Category。默认情况下,当您使用@Html.Partial("_SelectCategoryProjects");时,它会将Category模型传递给生成错误的方法。要么Category中包含CategoriesDDL的属性,例如

public class Category
{
  ....
  public CategoriesDDL Categories { get; set; }
}

并在主视图中

@Html.Partial("_SelectCategoryProjects", model.Categories)

注意,您需要确保Categories已初始化(在控制器或无参数构造函数中),否则如果为null,则将传递Category模型而不是CategoriesDDL }

另一种选择是使用call a child action,使用@Html.Action()

呈现局部视图