ASP.NET MVC 2 外键列表的强类型部分视图 - 传入什么类型?

发布于 2024-09-28 03:47:01 字数 4081 浏览 0 评论 0原文

我想将下拉列表的项目列表传递到强类型部分视图中。父视图使用 ViewModel 类,该类包含我要设置的值的属性以及关联的下拉列表应包含的选项列表。

我的 ViewModel 看起来像:

public class EntityFormViewModel
{
    private MyDBEntity Entity { get; set; }

    // *** The list of options. ***
    public SelectList DataTypeSelectList { get; private set; }

    public int EntityId { get; set; }
    public byte FormatId { get; set; }

    // *** The property the options relate to. ***
    [UIHint("DataTypesDropDownST")]
    public string DataType { get; set; }
    // Other properties snipped...


    public EntityFormViewModel(EntityModel db, int Id)
    {
        Entity = db.MyDBEntity.First(e => e.EntityId == Id);
        DataTypeSelectList = new SelectList(db.SDDS_DataType.ToList(), "DataType", "Description", this);

        EntityId = Entity.EntityId;
        FormatId = Entity.FormatId;
        DataType = Entity.DataType;
        // Etc ...
    }

    public void Update(EntityModel db)
    {
        Entity.EntityId = EntityId;
        Entity.FormatId = FormatId;
        Entity.DataType = DataType;
        // Etc ...

        db.SaveChanges();
    }
};

EditorTemplates/DataTypesDropDown.ascx 中的部分视图看起来

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcApp.Controllers.EntityFormViewModel>" %>

<!-- Doesn't work. -->
<%= Html.DropDownListFor(m => Model, Model.DataTypeSelectList) %>

<!-- Doesn't work either. -->
<!-- <% Html.DropDownListFor(m => Model, Model.DataTypeSelectList); %> -->

像 我的父视图看起来像

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApp.Controllers.EntityFormViewModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Edit
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Edit</h2>

    <% using (Html.BeginForm()) {%>
        <%: Html.ValidationSummary(true) %>

        <fieldset>
            <legend>Fields</legend>

            <%: Html.EditorFor(m => m) %>

            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>

    <% } %>

    <div>
        <%: Html.ActionLink("Back to List", "Index") %>
    </div>

</asp:Content>

我可以通过传递 ViewData 字典中的项目列表来使其正常工作,而无需强类型输入,因此:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

<%: Html.DropDownList("", new SelectList(ViewData["DataTypes"] as IEnumerable, "DataType", "Description", Model)) %>

但我得到以下结果强类型错误:

传递到字典中的模型项的类型为“System.String”,但该字典需要类型为“MvcApp.Controllers.EntityFormViewModel”的模型项。

看起来错误的类型(字符串)被传递到分部视图中,但是我可以做什么来更改我传递的类型?或者我的方法完全错误?如果是的话,应该怎么做呢?我想这是一个非常常见的场景。

我知道我应该使用“存储库”类进行数据库访问,但我希望在围绕它构建太多其他东西之前让它工作。请注意,我的 ViewModel 位于控制器命名空间中。我想我应该将其移至模型命名空间,但我怀疑这就是我的问题的原因。

=================================================== ===============================

更新

我仍然有问题,但至少我解决了编译器错误。我按如下方式更改了视图模型

    // Make this private
    private string DataType { get; set; }

    // Add this which supplies all the list information.
    [UIHint("DataTypesDropDownST")]
    public DataTypeOptsAndVal DataTypeAndOpts
    {
        get { return new DataTypeOptsAndVal(DataType, DataTypeSelectList); } 
        set { DataType = value.DataType; } 
    }

这个想法源于属性的返回值控制传递到分部视图的类型这一事实;整个模型没有通过,这是我之前的错误。因此,我返回一个包含部分视图所需的所有内容的类型。新的部分视图是

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcApp.Controllers.DataTypeOptsAndVal>" %>

<%: Html.DropDownListFor(m => m.DataType, Model.DataTypeSelectList) %>

但是,现在呈现的表单完全不存在该字段。我尝试在部分视图中包含静态文本,但即使这样也没有呈现。

任何帮助表示赞赏。强式输入选项列表肯定不那么难吧?

I would like to pass the item list for a drop-down list into a strongly-typed partial view. The parent view uses a ViewModel class that contains the properties both for the value I want to set and the list of options the associated drop-down list should contain.

My ViewModel looks like:

public class EntityFormViewModel
{
    private MyDBEntity Entity { get; set; }

    // *** The list of options. ***
    public SelectList DataTypeSelectList { get; private set; }

    public int EntityId { get; set; }
    public byte FormatId { get; set; }

    // *** The property the options relate to. ***
    [UIHint("DataTypesDropDownST")]
    public string DataType { get; set; }
    // Other properties snipped...


    public EntityFormViewModel(EntityModel db, int Id)
    {
        Entity = db.MyDBEntity.First(e => e.EntityId == Id);
        DataTypeSelectList = new SelectList(db.SDDS_DataType.ToList(), "DataType", "Description", this);

        EntityId = Entity.EntityId;
        FormatId = Entity.FormatId;
        DataType = Entity.DataType;
        // Etc ...
    }

    public void Update(EntityModel db)
    {
        Entity.EntityId = EntityId;
        Entity.FormatId = FormatId;
        Entity.DataType = DataType;
        // Etc ...

        db.SaveChanges();
    }
};

My partial view in EditorTemplates/DataTypesDropDown.ascx looks like

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcApp.Controllers.EntityFormViewModel>" %>

<!-- Doesn't work. -->
<%= Html.DropDownListFor(m => Model, Model.DataTypeSelectList) %>

<!-- Doesn't work either. -->
<!-- <% Html.DropDownListFor(m => Model, Model.DataTypeSelectList); %> -->

And my parent view looks like

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApp.Controllers.EntityFormViewModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Edit
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Edit</h2>

    <% using (Html.BeginForm()) {%>
        <%: Html.ValidationSummary(true) %>

        <fieldset>
            <legend>Fields</legend>

            <%: Html.EditorFor(m => m) %>

            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>

    <% } %>

    <div>
        <%: Html.ActionLink("Back to List", "Index") %>
    </div>

</asp:Content>

I can get it to work fine without strong typing by passing the list of items in the ViewData dictionary, thus:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

<%: Html.DropDownList("", new SelectList(ViewData["DataTypes"] as IEnumerable, "DataType", "Description", Model)) %>

but I get the following error with strong typing:

The model item passed into the dictionary is of type 'System.String', but this dictionary requires a model item of type 'MvcApp.Controllers.EntityFormViewModel'.

It looks like the wrong type (a string) is being passed into the partial view, but what can I do to change the type I pass? Or is my approach completely wrong? If so, how should it be done? I imagine this is a very common scenario.

I know I should use a "repository" class for database access, but I want to get this working before building too much other stuff around it. Note my ViewModel is in the controllers namspace. I guess I should move it to the Model namespace, but I doubt that's the cause of my problem.

=================================================================================

UPDATE

I still have a problem, but at least I solved the compiler error. I changed the view model as follows

    // Make this private
    private string DataType { get; set; }

    // Add this which supplies all the list information.
    [UIHint("DataTypesDropDownST")]
    public DataTypeOptsAndVal DataTypeAndOpts
    {
        get { return new DataTypeOptsAndVal(DataType, DataTypeSelectList); } 
        set { DataType = value.DataType; } 
    }

The idea being derived from the fact the return value of the property controls the type passed into the partial view; the whole model is not passed, which was my earlier mistake. Therefore, I return a type that contains everything the partial view needs. The new partial view is

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcApp.Controllers.DataTypeOptsAndVal>" %>

<%: Html.DropDownListFor(m => m.DataType, Model.DataTypeSelectList) %>

However, the form now renders with this field completely absent. I tried including static text in the partial view, but even this was not rendered.

Any help appreciated. Surely it isn't that hard to strongly type a list of options?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╄→承喏 2024-10-05 03:47:01

在您的主视图中,而不是:

<%: Html.EditorFor(m => m) %>

使用:

<%: Html.EditorForModel() %>

它等效但更具可读性。

至于编辑器模板未呈现的原因,您在模型上使用了 UIHint 属性。这意味着它将查找~/Views/Home/EditorTemplates/DataTypesDropDownST.ascx。确保该文件存在于该位置并且包含您在更新中显示的代码。

In your main view instead of:

<%: Html.EditorFor(m => m) %>

use:

<%: Html.EditorForModel() %>

It's equivalent but more readable.

As far as why the editor template is not rendered you used an UIHint attribute on your model. This means that it will look for ~/Views/Home/EditorTemplates/DataTypesDropDownST.ascx. Make sure this file is present at that location and contains the code you've shown in your update.

和我恋爱吧 2024-10-05 03:47:01

好吧,既然我在这里没有得到答案,我想这里没有人知道!但是,有一个答案,并记录在此处:

http://www.dalsoft.co.uk/blog/index.php/2010/04/26/mvc-2-templates/#Complex_Types

我绝对正确,问题是因为默认的MVC框架模板匹配只支持简单类型。然而,简单的解决方案只是告诉它使用什么模板:

<%: Html.EditorFor(m => m.DataTypeAndOpts, "DataTypesDropDownST") %>

“DataTypesDropDownST”是部分视图名称。

但是,为什么它不能与 EditorForModel() 和 [UIHint] 一起使用,我仍然不知道。 (当然,UIHint 所做的事情与上面的代码完全相同?)

OK, since I got no answer here, I figured nobody here knows! But, there is an answer and it is documented here:

http://www.dalsoft.co.uk/blog/index.php/2010/04/26/mvc-2-templates/#Complex_Types

I was absolutely right that the issue was because the default MVC framework template matching supports only simple types. However, the simple solution is just to tell it what template to use:

<%: Html.EditorFor(m => m.DataTypeAndOpts, "DataTypesDropDownST") %>

With "DataTypesDropDownST" being the partial view name.

However, why it doesn't work with EditorForModel() and [UIHint] I still don't know. (Surely, UIHint is doing exactly the same thing as the above code?)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文