我的情景: 我的模型是“项目”,其中包含0或多个税(模型“税”)
“项目” - >有0或n - > “税”
我有一个名为“VMItem”的MVC视图模型,它有一个“Item”对象,所有税(“TaxDic”)和选定的税(“Taxes”)。 MVC页面绑定到此视图模型(“ViewItem”)。
要求: 我希望MVC显示所有税款的列表框,并允许用户在创建项目时为每个项目选择相关税。
以下是我的代码,
参考以下代码,ListBox for Taxes不是必填字段。但是当我在ListBox上提交了一些选择的表单时,它会在ListBox周围显示红色框,如果我在ListBox上没有选择任何内容并提交,则看起来没有错误。
请看下面的场景..如果有更好的方法来实现这一点,请有人指导我。
模型
public class Item
{
[Display(Name="Item ID")]
public virtual Guid ItemID { get; set; }
[Required]
[Display(Name = "Name")]
public virtual string Name { get; set; }
[Required]
[Display(Name="Price")]
public virtual decimal Price { get; set; }
public virtual IEnumerable<Tax> Taxes { get; set; }
}
查看模型
public class VMItem
{
public Item Item { get; set; }
public IEnumerable<Tax> Taxes { get; set; }
public IEnumerable<SelectListItem> TaxDic { get; set; }
}
生成控制器类中的选择列表项的功能
private VMItem GenerateViewModel(Item Item)
{
IEnumerable<Tax> Taxes = TaxServices.FindAll();
IList<SelectListItem> taxDic = new List<SelectListItem>();
// Generating Taxes and taxDic here..
VMItem VmItem = new VMItem
{
Item = Item,
Taxes = Taxes,
TaxDic = taxDic
};
return VmItem;
}
Contorller行动
// GET: /Product/Add
public ActionResult Add()
{
return View(GenerateViewModel(new Item()));
}
[HttpPost]
public ActionResult Add(VMItem collection)
{
Item item = new Item();
try
{
if(ModelState.IsValid)
{
item = collection.Item;
var taxes = collection.Taxes;
return View(GenerateViewModel(collection.Item));
}
// else..
}
// catch...
}
浏览
<% using (Html.BeginForm()) { %>
<!-- more codes for other fields -->
<%: Html.ListBoxFor(model => model.Taxes, Model.TaxDic) %>
<!-- submit button goes below -->
<% } %>
答案 0 :(得分:1)
这看起来像是多对多的关系,所以首先检查您的税级是否如下所示:
public class Tax
{
public Guid TaxId { get; set;}
public virtual ICollection<Item> Items { get; set;}
}
然后在上下文类中的OnModelCreating函数内添加:
modelBuilder.Entity<Item>()
.HasMany(i => i.Taxes).WithMany(t => t.Items)
.Map(t => t.MapLeftKey("ItemId")
.MapRightKey("TaxId")
.ToTable("ItemsTaxes"));
视图模型
public class ItemTaxViewModel
{
public Item item { get; set; }
public virtual ICollection<AssignedTaxes> Taxes { get; set; }
}
public class AssignedTaxes
{
public int TaxId { get; set; }
public bool Assigned { get; set; }
}
控制器操作
public ActionResult Create()
{
var newItemVM = new ItemTaxViewModel
{
Item = new Item(),
Taxes = PopulateTaxes()
};
return View(newItemVM);
}
[HttpPost]
public ActionResult Create(ItemTaxViewModel itemTaxViewModel)
{
if(ModelState.IsValid)
{
var item = new Item();
item = itemTaxViewModel.Item;
AddOrUpdateTaxes(item, itemTaxViewModel.Taxes);
context.Items.Add(item);
context.SaveChanges();
return RedirectToAction("Index");
}
return View(itemTaxViewModel);
}
帮助方法
private List<AssignedTaxes> PopulateTaxes()
{
var taxes = context.Taxes;
var assignedTaxes = new List<AssignedTaxes>();
foreach(var tax in taxes)
{
assignedTaxes.Add(new AssignedTaxes
{
TaxId = tax.TaxId,
Assigned = false
});
}
return assignedTaxes;
}
private void AddOrUpdateTaxes(Item item, ICollection<AssignedTaxes> assignedTaxes)
{
foreach(var assignedTax in assignedTaxes)
{
if(assignedTax.Assigned)
{
item.Taxes.Add(context.Taxes.Single(t => t.TaxId == assignedTax.TaxId));
}
}
}
> / Views / Shared / EditorTemplates 下的EditorTemplate
@model AssignedTaxes
@using projectName.ViewModels
<fieldset>
@Html.HiddenFor(model => model.TaxId)
@Html.CheckBoxFor(model => model.Assigned)
</fieldset>
查看
<div class="editor-field">
@Html.EditorFor(model => model.Taxes)
<div class="editor-field">
似乎喜欢很多工作,但它是实现多对多复选框的最干净方法之一,我在完成了许多教程之后想出了这些复选框。
答案 1 :(得分:0)
@Luis,你的方式看起来不错但是太复杂了,最后你用复选框结束了它。可能是更好的方式。我提出了一个解决方案,这对我来说很简单。我在下面发布。请给我一个反馈意见,我是否应继续使用或需要改进。
控制器
IEnumerable<Tax> Taxes = _TaxServices.FindTax();
IList<SelectListItem> taxDic = new List<SelectListItem>();
foreach (Tax tax in Taxes)
{
SelectListItem item = new SelectListItem();
item.Value = tax.TaxID.ToString();
item.Text = tax.Name;
taxDic.Add(item);
}
VMItem VmItem = new VMItem
{
Item = Item,
TaxDic = taxDic,
};
// Adding selected taxes to the list
IList<int> SelectedTaxes = new List<int>();
if (Item.Taxes != null && Item.Taxes.Count > 0)
{
foreach (Tax tax in Item.Taxes)
{
SelectedTaxes.Add(tax.TaxID);
}
}
VmItem.SelectedTax = SelectedTaxes;
return view(VmItem);
查看
<%: Html.ListBoxFor(model => model.SelectedTax, Model.TaxDic) %>
控制器[HttpPost]
item.Taxes = new Iesi.Collections.Generic.HashedSet<Tax>();
if (vmItem.SelectedTax.Count() > 0)
{
IEnumerable<int> SelectedTaxesIDs = vmItem.SelectedTax.ToList();
foreach (int n in SelectedTaxesIDs)
{
item.Taxes.Add(_TaxServices.FindTax(n));
}
}
请以这种方式提供反馈。 感谢。