MVC Html.DropDownListFor返回具有null值的复杂类型



我的控制器中有以下控制器创建操作。它注意选择列表中的显示名称将是"StoreName-StoreAddress"。Store complexType存储在Store中。

// GET: Purchases/Create
public ActionResult Create()
{
ViewBag.Stores = db.Stores.Select(s => new { DisplayName = s.StoreName.ToString() + " - " + s.Address.ToString(), Store = s});
return View();
}

在"创建视图"中,以下代码会确保其正确显示。

<div class="form-group">
@Html.LabelFor(model => model.Store.StoreName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.Store.StoreName, new SelectList(ViewBag.Stores, "Store", "DisplayName"), new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Store.StoreName, "", new { @class = "text-danger" })
</div>
</div>

它将转到控制器的post方法(如果我是正确的(。

// POST: Purchases/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Store,Price,Date")] Purchase purchase)
{
if (ModelState.IsValid)
{
Store store = purchase.Store;
db.Purchases.Add(purchase);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(purchase);
}

然而,商店=购买。Store现在将提供一个复杂的Store类型,其中StoreName以外的任何值都设置为null。StoreName将是一个字符串。

如何返回与所选Store对象相等的复杂类型?


编辑1:

public class Purchase
{
public int Id { get; set; }
public Store Store { get; set; }
public string Type { get; set; }
[DataType(DataType.Currency)]
[Column(TypeName = "money")]
public decimal Price { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime Date { get; set; }
}
public class PurchaseDBContext : DbContext
{
public DbSet<Purchase> Purchases { get; set; }
public DbSet<Store> Stores { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
public class Store
{
public int StoreId { get; set; }
public string StoreName { get; set; }
public string Address { get; set; }
public string City { get; set; }
[DataType(DataType.PhoneNumber)]
[RegularExpression(@"^((+|00(s|s?-s?)?)31(s|s?-s?)?((0)[-s]?)?|0)[1-9]((s|s?-s?)?[0-9])((s|s?-s?)?[0-9])((s|s?-s?)?[0-9])s?[0-9]s?[0-9]s?[0-9]s?[0-9]s?[0-9]$", ErrorMessage = "This is not a valid phonenumber")]
public string PhoneNumber { get; set; }
}

是否需要使用其他注释来设置导航属性?

您的示例中有很多内容,但如果您使用导航属性并且您的模型是以某种方式设置的,则不需要传递复杂的对象。如果您为Store/StoreId设置了导航属性,实体框架应该会为您推断出一些事情,这样它会简化您的视图。

public class Purchase 
{
public int StoreId { get; set; }
[ForeignKey("StoreId")]
public Store Store { get; set;}
}

我会将一个模型传递到类似于下面的视图。IMO,它比使用ViewBag更干净。

public class CreatePurchaseModel
{
//To populate a list
public List<Store> AvailableStores { get; set; }
//The actual object to be created
public Purchase Purchase { get; set; }
}

控制器方法:

// GET: Purchases/Create
public ActionResult Create()
{
var vm = new CreatePurchaseModel() 
{
AvailableStores = db.Stores.ToList(),
Purchase = new Purchase()
};
return View(vm);     
}

使用AvailableStores属性填充下拉列表以设置Purchase.StoreId

@Html.DropDownListFor(m => m.Purchase.StoreId, Model.AvailableStores.Select(x => new SelectListItem { Text = x.StoreName.ToString(), Value = x.StoreId.ToString() }))

如果设置正确,你只需要在后方法参数中购买

[ValidateAntiForgeryToken, HttpPost]
public ActionResult Create(Purchase purchase) 
{
//purchase.StoreId should have a non zero value
db.Purchases.Add(purchase);
db.SaveChanges();
}

最新更新