C# Html.dropdownlist首次加载值错误,但之后每次都正确吗?

C# Html.dropdownlist首次加载值错误,但之后每次都正确吗?,c#,asp.net-mvc,oracle,razor,asp.net-mvc-5,C#,Asp.net Mvc,Oracle,Razor,Asp.net Mvc 5,我正在开发一个MVC5应用程序(Oracle DB),并注意到视图中绑定的dropdownlist出现了一些奇怪的行为。当我选择一条记录进行编辑时,我的GET Edit控制器操作将从我的TBL\u所有者中加载一个名称列表,并按[OWNER\u NAME]排序到我的ViewData对象中: ViewData["Owner_List"] = new SelectList(db.TBL_OWNERS.OrderBy(x => x.OWNER_NAME), "ID", "OWNER_NAME");

我正在开发一个MVC5应用程序(Oracle DB),并注意到视图中绑定的dropdownlist出现了一些奇怪的行为。当我选择一条记录进行编辑时,我的
GET Edit
控制器操作将从我的
TBL\u所有者
中加载一个名称列表,并按
[OWNER\u NAME]
排序到我的ViewData对象中:

ViewData["Owner_List"] = new SelectList(db.TBL_OWNERS.OrderBy(x => x.OWNER_NAME), "ID", "OWNER_NAME");
然后在我的视图中,我使用此ViewData列表填充一个SelectList,该列表填充DropDownList for:

@Html.DropDownListFor(model => model.OWNER, (SelectList)ViewData["Owner_List"], "NONE", htmlAttributes: new { @class = "form-control dropdown", @id = "selectOwner" })
现在,当我选择一条没有
[OWNER]
值的记录进行编辑时,我会在下拉列表中选择预期的默认值“NONE”。但是,如果我有
[OWNER]
(例如“SMITH,JOHN”)的值,则视图加载时仍在下拉列表中显示“无”

奇怪的是,如果我随后保存记录(从下拉列表中指定任何名称),那么下次我进入该记录的编辑视图时,下拉列表已经预选为已存储在Oracle DB中的正确值

任何有更多经验的人都能权衡一下这里发生了什么以及如何解决它吗


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

[StringLength(4000)]
public string OWNER { get; set; }
然后我还为这个主类定义了一个元数据类:

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;
    }
}
namespace Project.DAL
{
//此元数据分部类用于扩展[ENT_COLLECTIONS]DAL类的属性
//允许使用相关FK值显式填充新属性。
[元数据类型(类型(ENT_COLLECTIONSMD))]
公共部分类ENT_集合
{
//..其他元数据字段。。。
[显示(Name=“Owner”)]
公共字符串所有者名称
{
得到
{
//TBL_所有者不像其他子表(位置、类型等)那样链接到ENT_集合
//需要从[ENT\u OWNERS]检索[OWNER\u NAME]以指定[ENT\u COLLECTIONS]。[OWNER]而不是
//(例如)值为“47”。
//输出带帮助(所有者)(史米斯,约翰)不能转换为十进制。如果值为4(ID),则继续进行。
if(this.OWNER!=null&&this.OWNER.Length<4)
{
//将[ENT_COLLECTIONS].[OWNER]的值转换为十进制(“47”=>47)
var ownerID=Convert.ToDecimal(this.OWNER);
//将此ID与[TBL_OWNERS].[ID]匹配,以获得单数引用的[TBL_OWNERS]实体。
var ownerEntity=db.TBL_OWNERS.FirstOrDefault(model=>model.ID==ownerID);
//如果找到匹配项,请将[OWNER]从(例如)“47”更改为“SMTIH,JOHN”
if(ownerEntity!=null)
{
this.OWNER=ownerEntity.OWNER\u NAME;
}
}
归还此文件。所有者;
}
}
}
公共类ENT_集合MD
{
//……其他领域。。。
[长度(4000)]
公共字符串所有者;
}
}
您应该使用不同的构造函数,因为您没有在列表中指定所选项。 MVC帮助程序DropdownListFor不会自动选择该值,并希望您告诉SelectList所选的项目

初始化SelectList的正确方法是:

ViewData["Owner_List"] = new SelectList(db.TBL_OWNERS.OrderBy(x => x.OWNER_NAME), "ID", "OWNER_NAME", [OWNER_ID]);
当您返回视图时,您看到项目已被选中的奇怪行为,可能是您的web浏览器试图自动完成选择。您应该执行一项测试,将
autocomplete=“off”
指定为html属性

您可以在此处找到类似的问题:


注:作为补充说明,如果不强制使用ViewData,请尽量不要使用它。使用模型和强类型视图几乎总是更好。

当我尝试以下操作时,
“ID”,“OWNER\u NAME”
后面带有
标志的部分无法将lambda表达式转换为类型“object”,因为它不是委托类型
ENT\u COLLECTIONS ENT\u COLLECTIONS=wait db.ENT\u COLLECTIONS.FindAsync(id);ViewData[“Owner\u List”]=新的SelectList(db.TBL\u Owner.OrderBy(x=>x.Owner\u NAME),“ID”,“Owner\u NAME”,x=>x.Owner\u NAME==ent\u Collections.Owner)Visual Studio将您建议的添加标记为错误。是的,您是对的,我更正了代码。不知道为什么,但我真的认为我看到了一个Func签名,我希望它能起到作用,但我仍然得到了与以前完全相同的行为--“NONE”显示为第一次出现的有效“OWNER”值,然后在执行初始保存后,每次都进行更正<代码>视图数据[“所有者列表”]=新选择列表(db.INV\u OWNERS.OrderBy(x=>x.Owner\u NAME),“ID”,“所有者名称”,ent\u Collections.Owner)我应该更清楚,您必须使用I'd值来匹配您在构造函数第二位指定的“ID”参数。另外,尝试将autocomplete=“off”添加到HTML属性中,以查看奇怪的行为是否停止。为了清晰起见,我正在修改代码,但阿加尼特仍在做同样的事情。我在视图中添加了
,现在为您显示的新参数传递[OwnerID],而不是[OwnerID]:
decimal OwnerID=db.INV\u OWNERS.FirstOrDefault(x=>x.ownerName==ent\u Collections.Owner).ID--
ViewData[“所有者列表”]=新的选择列表(db.INV\u OWNERS.OrderBy(x=>x.Owner\u NAME),“ID”,“所有者名称”,ownerID)仍保持与以前相同的行为。
ViewData["Owner_List"] = new SelectList(db.TBL_OWNERS.OrderBy(x => x.OWNER_NAME), "ID", "OWNER_NAME", [OWNER_ID]);