C# ViewModel DropDownList和HTTP Post控制器
我的创建操作与Post Controller有一些问题。下面是我的模型,圆形,材质,材质形状,原材料。我的主要目标是向数据库中添加Round对象C# ViewModel DropDownList和HTTP Post控制器,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,我的创建操作与Post Controller有一些问题。下面是我的模型,圆形,材质,材质形状,原材料。我的主要目标是向数据库中添加Round对象 public class Material { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; } [Required] [Display(Name="Material")] pu
public class Material
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
[Display(Name="Material")]
public string MaterialName { get; set; }
}
材料形状抽象类
public abstract class MaterialShape
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public virtual Material Material { get; set; }
}
从MaterialShape继承的圆形类
[Table("Rounds")]
public class Round : MaterialShape
{
[Required]
[Display(Name="Outside Diameter")]
public double OuterDiameter { get; set; }
}
下面是我创建的视图模型,用于将所有材质添加到视图中。我使用IEnumerable从数据库中获取所有不同的资料。我还包括了一个用于保存我所选项目的MaterialId
public class VMRoundMaterial
{
public Round Round { get; set; }
[Display(Name="Material")]
public IEnumerable<SelectListItem> Materials { get; set; }
public int MaterialId { get; set; }
}
创建视图
@model SetupSheet.Models.ViewModel.VMRoundMaterial
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Round</h4>
<hr />
@Html.ValidationSummary(true)
<div class="form-group">
@Html.LabelFor(model => model.Round.OuterDiameter, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Round.OuterDiameter)
@Html.ValidationMessageFor(model => model.Round.OuterDiameter)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Materials, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(m => m.MaterialId, Model.Materials)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
我的[HttpPost]工作不正常。我设置正确了吗?DropDownListFor参数设置是否正确?我是否正确地将selecteditem转换为圆形对象?由于某种原因,ModelState.IsValid返回false。这可能是什么原因造成的?
代码在上失败
roundmaterial.Material.ID = viewmodel.MaterialId;
数据库连接正在工作,但我没有收到结果。我对其他策略持开放态度,以找到一种有效的策略
jstadnicki提出的解决方案
[HttpPost]
public ActionResult Create(ModelDTO viewmodel)
{
try
{
if (ModelState.IsValid)
{
Round roundmaterial = new Round();
roundmaterial.OuterDiameter = viewmodel.Round.OuterDiameter;
roundmaterial.Material.ID = viewmodel.MaterialId;
db.Rounds.Add(roundmaterial);
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
我明白你为什么要用ModelDTO,但我还是有问题
ModelState仍然为false。我认为我们仍然缺少一些东西。如果我正确理解您的问题:尝试将VMRoundMaterial in post方法更改为ModelDTO,其中ModelDTO的定义如下:
public class ModelDTO
{
public Round Round {get;set;}
public int MaterialId { get; set; }
}
现在检查您是否将获得适当的水合模型。
ModelState
无效,因为您在视图模型(Round
)中使用了数据模型,并且没有为所需的材质
属性回传值
通常,用于编辑数据的视图模型不应包括作为数据模型的属性,并且您的视图应为
public class VMRoundMaterial
{
[Required]
[Display(Name="Outside Diameter")]
public double OuterDiameter { get; set; }
[Display(Name="Material")]
public int MaterialId { get; set; }
public IEnumerable<SelectListItem> Materials { get; set; }
}
旁注:您使用的
roundmaterial.Material.ID=viewmodel.MaterialId可能会抛出一个NullReferenceException
,因为您尚未初始化属性Material
ModelDTO在此实例中是圆形的。圆形是从材质形状继承而来的。MaterialShape具有材质类型的材质属性。见上文。您是否建议我使用MaterialID作为数据模型中的键,而不是材质类型/对象。也许是我的物品出了问题,你不会得到收集的材料。视图模型!=DTO模型。请注意,在HTML中,您只找到一个带有MaterialD的,并且您正在获得它,如屏幕截图所示。为了得到材料清单,你需要自己重新生成。代码正确。那么从数据库中重新生成列表,然后将其另存为物料类型?为什么ModelState.IsValid=“false”?ModelState对我来说是个惊喜。但是,请将控制器中的输入模型更改为我在回答中提出并更新的模型。请注意,is仅包含将通过页面上显示的表单发送的数据。检查它是否有效。请记住,在大多数情况下,用于显示数据的模型(aka:ViewModel)和在控制器中发送给您的模型(aka:data Transfers Objects~DTO~)是不同的。
public class ModelDTO
{
public Round Round {get;set;}
public int MaterialId { get; set; }
}
public class VMRoundMaterial
{
[Required]
[Display(Name="Outside Diameter")]
public double OuterDiameter { get; set; }
[Display(Name="Material")]
public int MaterialId { get; set; }
public IEnumerable<SelectListItem> Materials { get; set; }
}
@Html.LabelFor(m => m.OuterDiameter)
@Html.EditorFor(m => m.OuterDiameter)
@Html.ValidationMessageFor(m => m.OuterDiameter)
@Html.LabelFor(m => m.MaterialId)
@Html.DropDownListFor(m => m.MaterialId, Model.Materials)
@Html.ValidationMessageFor(m => m.MaterialId)