【问题标题】:Replacing Model object by ViewModel object will raise an exception when trying to save a new record尝试保存新记录时,用 ViewModel 对象替换 Model 对象将引发异常
【发布时间】:2013-07-22 22:12:26
【问题描述】:

我有一个名为 Server 的模型类,并且我创建了一个新的 ServerToEdit viewModel 类,但是当我尝试提交 viewModel 时,我会在 repository.save() 方法上收到以下错误。

传入字典的模型项是类型 'TMS.Models.Server',但此字典需要类型的模型项 'TMS.ViewModels.ServerToEdit'。

viewModel 类是:-

public class ServerToEdit
    {
        public Server Server { get; set; }
       [Required]
        public String IPAddress { get; set; }
    }

创建视图的一部分是:-

model TMS.ViewModels.ServerToEdit

@* This partial view defines form fields that will appear when creating and editing entities *@
 @Html.AntiForgeryToken()
<div class="editor-label">
    @Html.LabelFor(model => model.Server.CustomerName)
</div>
<div class="editor-field">
    @Html.EditorFor(model =>model.Server.CustomerName)
    @Html.ValidationMessageFor(model =>model.Server.CustomerName)
</div>
<div class="editor-label">
   IP Address
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.IPAddress)
    @Html.ValidationMessageFor(model => model.IPAddress)
</div>


IPAddress
<div class="editor-label">
    @Html.LabelFor(model =>model.Server.ILOIP)
</div>
<div class="editor-field">
    @Html.EditorFor(model =>model.Server.ILOIP)
    @Html.ValidationMessageFor(model =>model.Server.ILOIP)
</div>

创建肌动蛋白的方法是:-

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Server server, TechnologyIP technologyIP)
        {
           try 
           { 
               if (ModelState.IsValid) 
           {
                repository.InsertOrUpdateServer(server,technologyIP);
                repository.Save();
                return RedirectToAction("Index");
            }

最后InsertOrUpdateServer存储库方法是:-

public void InsertOrUpdateServer(Server server, TechnologyIP technologyIP)
        {
            if (server.ServerID == default(int))
            {
                // New entity
                int technologyypeID = GetTechnologyTypeID("Server");
                Technology technology = new Technology
                {
                    IsDeleted = true,
                    TypeID = technologyypeID,
                    Tag = "S" + GetTagMaximumeNumber(technologyypeID).ToString()

                };

                InsertOrUpdateTechnology(technology);
                Save();



                var auditinfo = IntiateAudit(tms.AuditActions.SingleOrDefault(a => a.Name.ToUpper() == "ADD").ActionID,
                    tms.TechnologyTypes.SingleOrDefault(a => a.Name.ToUpper() == "Server").AssetTypeID,
                 "TDMGROUP\administrator", technology.TechnologyID);

                server.ServerID = technology.TechnologyID;
                technologyIP.TechnologyID = technology.TechnologyID;
                tms.Servers.Add(server);
                InsertOrUpdateTechnologyIP(technologyIP);
                technology.IsDeleted = false;
                InsertOrUpdateTechnology(technology);
                InsertOrUpdateAudit(auditinfo);
            }
            else
            {
                // Existing entity
                var auditinfo = IntiateAudit(tms.AuditActions.SingleOrDefault(a => a.Name.ToUpper() == "EDIT").ActionID,
                    tms.TechnologyTypes.SingleOrDefault(a => a.Name.ToUpper() == "Server").AssetTypeID,
                 "TDMGROUP\administrator", server.ServerID);
                tms.Entry(server).State = EntityState.Modified;
                tms.Entry(technologyIP).State = EntityState.Modified;
                InsertOrUpdateAudit(auditinfo);
            }
        }

提前感谢您的帮助?

【问题讨论】:

  • 您的 Action 中的 TechnologyIP 来自哪里?它既不在您的 ViewModel 中,也不在您的 View 中。
  • TechnologyIP 只是一个存储@Html.EditorFor(model => model.IPAddress) 和 TechnologyID.so 我只需要获取@Html.EditorFor(model => model.IPAddress ) 从视图中,然后在存储库方法中,我将为它填充 TechnologyID。

标签: asp.net asp.net-mvc


【解决方案1】:

首先,将您的 ViewModel 更改为:

public class ServerToEdit
{
    public Server Server { get; set; }
    public TechnologyIP TechnologyIP { get; set; }
}

并且,将您的操作更改为:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ServerToEdit serverToEdit)
{
   if (ModelState.IsValid)
   {
       try 
       { 
           repository.InsertOrUpdateServer(serverToEdit.Server, serverToEdit.TechnologyIP);
           repository.Save();
           return RedirectToAction("Index");
       }
       catch
       {
           // Some code... 
       }
   }
}

然后,在您的视图中,您将拥有:

@model TMS.ViewModels.ServerToEdit

@* This partial view defines form fields that will appear when creating and editing entities *@
 @Html.AntiForgeryToken()
<div class="editor-label">
    @Html.LabelFor(model => model.Server.CustomerName)
</div>
<div class="editor-field">
    @Html.EditorFor(model =>model.Server.CustomerName)
    @Html.ValidationMessageFor(model =>model.Server.CustomerName)
</div>

@Html.HiddenFor(model => model.TechnologyIP.TechnologyID)
<div class="editor-label">
   IP Address
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.TechnologyIP.IPAddress)
    @Html.ValidationMessageFor(model => model.TechnologyIP.IPAddress)
</div>    

<div class="editor-label">
    @Html.LabelFor(model =>model.Server.ILOIP)
</div>
<div class="editor-field">
    @Html.EditorFor(model =>model.Server.ILOIP)
    @Html.ValidationMessageFor(model =>model.Server.ILOIP)
</div>

【讨论】:

  • 非常感谢您的帮助,但会有什么不同?我认为模型活页夹应该为我做这件事。
  • 为什么模型绑定器应该将字符串值(IPAddress)绑定到 TechnoloyIP 对象?
  • 您还需要在您的视图中为 TechnologyID 隐藏输入。查看更新的答案。
  • 因为它会检查 TechnologyIP.IPAddress 和视图上的字段名称是否相同。那么它会将 IPAddress 字符串映射到 IPAddress 对象属性。?我虽然会这样?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-18
  • 2019-08-12
  • 2017-04-26
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
相关资源
最近更新 更多