Html.DropDownListFor第一次加载错误的值,但每次都是正确的?

时间:2015-06-11 15:45:24

标签: c# asp.net-mvc oracle razor asp.net-mvc-5

我正在研究一个MVC5应用程序(Oracle DB),并注意到我的视图中带有绑定下拉列表的一些奇怪行为。当我为Edit选择一条记录时,我的GET-Edit控制器操作会从我的TBL_OWNERS加载一个名称列表,按[OWNER_NAME]排序到我的ViewData对象中:

ViewData["Owner_List"] = new SelectList(db.TBL_OWNERS.OrderBy(x => x.OWNER_NAME), "ID", "OWNER_NAME");

然后在我的View上,我使用此ViewData列表填充填充DropDownListFor的SelectList:

@Html.DropDownListFor(model => model.OWNER, (SelectList)ViewData["Owner_List"], "NONE", htmlAttributes: new { @class = "form-control dropdown", @id = "selectOwner" })

现在,当我选择要编辑的记录没有[OWNER]的值时,我得到预期的默认值“NONE”作为下拉列表中的选定选项。但是,如果我有[OWNER](例如)“SMITH,JOHN”的值,则视图加载仍会在下拉列表中显示“NONE”。

有什么奇怪的,如果我然后保存记录(从下拉列表中指定任何名称),下次我进入我的编辑视图以获取该记录时,下拉列表已经预先选择了已存储的正确值在Oracle DB中。

任何有更多经验的人都可以权衡这里发生的事情以及如何解决这个问题?

对于一些额外的信息(如果它有帮助),我的主DAL类将[OWNER]字段定义为:

[StringLength(4000)]
public string OWNER { get; set; }

然后我还为这个主类定义了一个MetaData类:

namespace Project.DAL
{

    // This MetaData partial class is used to extend properties of the [ENT_COLLECTIONS] DAL class
    // allowing for new properties to be set explicitly filled with related FK values.
    [MetadataType(typeof(ENT_COLLECTIONSMD))]
    public partial class ENT_COLLECTIONS
    {

        // .... Other MetaData Fields ...

        [Display(Name = "Owner")]
        public string Owner_Name
        {
            get
            {
                // TBL_OWNERS is not linked to ENT_COLLECTIONS like the other child tables (Locations, Types, etc.)
                // Need to retrieve the [OWNER_NAME] from [ENT_OWNERS] to specify for [ENT_COLLECTIONS].[OWNER] instead of
                // (ex.) "47" for the value.

                // Band-Aid for Exporting where OWNER (ex.) "Smith, John" cannot be converted to a Decimal. If values is < 4 (ID), then proceed.
                if (this.OWNER != null && this.OWNER.Length < 4)
                {
                    // Convert the values of [ENT_COLLECTIONS].[OWNER] to decimal ("47" => 47)
                    var ownerID = Convert.ToDecimal(this.OWNER);
                    // Match this ID to [TBL_OWNERS].[ID] to get the singular referenced [TBL_OWNERS] entity.
                    var ownerEntity = db.TBL_OWNERS.FirstOrDefault(model => model.ID == ownerID);
                    // If a match was found, change [OWNER] from (ex.) "47" to "SMTIH, JOHN"
                    if (ownerEntity != null)
                    {
                        this.OWNER = ownerEntity.OWNER_NAME;
                    }
                }

                return this.OWNER;
            }
        }
    }

    public class ENT_COLLECTIONSMD
    {
        // ... Other Fields ...

        [StringLength(4000)]
        public string OWNER;
    }
}

1 个答案:

答案 0 :(得分:0)

ViewData["Owner_List"] = new SelectList(db.TBL_OWNERS.OrderBy(x => x.OWNER_NAME), "ID", "OWNER_NAME");

您应该使用不同的构造函数,因为您未在列表中指定所选项目。 MVC帮助器DropdownListFor不会自动选择该值,并希望您告诉SelectList选择了哪个项目。

初始化SelectList的正确方法是:

ViewData["Owner_List"] = new SelectList(db.TBL_OWNERS.OrderBy(x => x.OWNER_NAME), "ID", "OWNER_NAME", [OWNER_ID]);

当您返回视图时,请参阅您已经选择的项目的奇怪行为,可能是您的网络浏览器尝试自动完成选择。您应该进行测试,将autocomplete="off"指定为html属性。

您可以在此处找到类似的问题:How to make a select list item selected in asp.net mvc?

PS:作为附注,如果您没有被迫这样做,请尽量不要使用ViewData。使用模型和强类型视图几乎总是更好。