[英]Asp.net mvc ModelState validity when using dropdownlist
[英]ModelState validity using ViewModel
我有一个表Product,一个表ProductType,最后一个表ProductCompanies。 这是他们的关系:
我有一个ProductViewModel像这样:
public class ProductViewModel
{
public Product Product { get; set; }
public List<SelectListItem> ProductTypes { get; set; }
public List<SelectListItem> ProductCompanies { get; set; }
[RegularExpression(@"^[a-zA-Zàéèêçñ\s][a-zA-Zàéèêçñ\s-]+$", ErrorMessage = "Invalid name !")]
public string ModelName { get; set; }
[RegularExpression(@"^[a-zA-Zàéèêçñ\s][a-zA-Zàéèêçñ\s-]+$", ErrorMessage = "Invalid name !")]
public string CompanyName { get; set; }
}
我有一个个性化的Create View ,其工作方式如下:有一个包含所有现有产品类型的下拉列表。 如果用户想创建一个新的,可以通过单击一个使隐藏部分出现的链接来实现。 在此部分中,您可以添加新的型号名称并精确描述公司:
@model BuSIMaterial.Models.ProductViewModel
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Create a material</legend>
<div class="editor-label">
Product type : <a class="product_type" id="product_type_link">Using a new model</a>
</div>
<div id= "existing_product_type" class="editor-field">
@Html.DropDownListFor(p => p.Product.ProductType.Id_ProductType, Model.ProductTypes)
@Html.ValidationMessageFor(model => model.Product.Id_ProductType)
</div>
<div id="new_product_type">
<div class="editor-label">
Model :
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.ModelName, new { maxlength = 50, id = "model"})
@Html.ValidationMessageFor(model => model.ModelName)
</div>
<div class="editor-label">
Company : <a class="company" id="company_link">Using a new company name</a>
</div>
<div id="existing_company" class="editor-field">
@Html.DropDownListFor(p => p.Product.ProductType.Id_ProductCompany, Model.ProductCompanies)
@Html.ValidationMessageFor(model => model.Product.ProductType.Id_ProductCompany)
</div>
<div id="new_company">
<div class="editor-label">
Name :
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.CompanyName, new { id = "company_name"})
@Html.ValidationMessageFor(model => model.CompanyName)
</div>
</div>
</div>
<div class="editor-label">
Catalog price :
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Product.CatalogPrice)
@Html.ValidationMessageFor(model => model.Product.CatalogPrice)
</div>
<div class="editor-label">
Serial number :
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Product.SerialNumber)
@Html.ValidationMessageFor(model => model.Product.SerialNumber)
</div>
<div class="editor-label">
Purchase date :
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Product.PurchaseDate, new { id = "datepicker"})
@Html.ValidationMessageFor(model => model.Product.PurchaseDate)
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Create</button>
</div>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/jqueryui")
@Styles.Render("~/Content/themes/base/css")
<script type="text/javascript">
$(document).ready(function () {
$("#product_type_link").click(function () {
if ($("#new_product_type").css("display") == "block") {
$("#new_product_type").css("display", "none");
$("#existing_product_type").css("display", "block");
$("#product_type_link").text("Using a new model");
$("#model").val("");
$("#company_name").val("");
}
else {
$("#new_product_type").css("display", "block");
$("#existing_product_type").css("display", "none");
$("#product_type_link").text("Using an existing model")
}
});
$("#company_link").click(function () {
if ($("#new_company").css("display") == "block") {
$("#new_company").css("display", "none");
$("#existing_company").css("display", "block");
$("#company_link").text("Using a new company name");
$("#company_name").val("");
}
else {
$("#new_company").css("display", "block");
$("#existing_company").css("display", "none");
$("#company_link").text("Using an existing company name")
}
});
});
</script>
}
在我的发布操作中,我只是检查用户是否在隐藏字段中输入了内容。 如果完成,我会做一些工作,但是没有什么真正复杂的:
[HttpPost]
public ActionResult Create(ProductViewModel pvm)
{
var productTypeList = from obj in db.ProductTypes orderby obj.ProductCompany.Name ascending where !((from element in db.VehicleTypes select element.Id_ProductType).Contains(obj.Id_ProductType)) select obj;
ViewBag.Id_ProductType = new SelectList(productTypeList, "Id_ProductType", "Information", pvm.Product.Id_ProductType);
pvm.ProductTypes = productTypeList.ToList().Select(p => new SelectListItem { Text = p.Information, Value = p.Id_ProductType.ToString() }).ToList();
ViewBag.Id_ProductCompany = new SelectList(db.ProductCompanies, "Id_ProductCompany", "Name", pvm.Product.ProductType.Id_ProductCompany);
pvm.ProductCompanies = db.ProductCompanies.ToList().Select(c => new SelectListItem { Text = c.Name, Value = c.Id_ProductCompany.ToString() }).ToList();
Product product = new Product()
{
PurchaseDate = pvm.Product.PurchaseDate,
SerialNumber = pvm.Product.SerialNumber,
CatalogPrice = pvm.Product.CatalogPrice
};
ProductType productType = null;
if (ModelState.IsValid)
{
ModelStateDictionary errors = Validator.isValid(pvm.Product);
if (errors.Count > 0)
{
ModelState.Merge(errors);
return View(pvm);
}
if (!string.IsNullOrWhiteSpace(pvm.ModelName))
{
if (!string.IsNullOrWhiteSpace(pvm.CompanyName))
{
ProductCompany productCompany = new ProductCompany()
{
Name = pvm.CompanyName
};
productType = new ProductType()
{
Model = pvm.ModelName,
ProductCompany = productCompany
};
}
else
{
productType = new ProductType()
{
Model = pvm.ModelName,
Id_ProductCompany = pvm.Product.ProductType.Id_ProductCompany
};
}
}
else
{
productType = new ProductType()
{
Id_ProductType = pvm.Product.Id_ProductType,
Id_ProductCompany = pvm.Product.ProductType.Id_ProductCompany
};
}
product.ProductType = productType;
db.Products.AddObject(product);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(pvm);
}
我的问题是我从来没有到达过if(ModelState.isValid)
内部的代码,因为我的ModelState无效...而且我也不知道为什么! 经过多次调试,我发现ViewModel的Product.ProducType.Model为null(并且不应该这样做,因为如果用户在下拉列表中选择了某些内容就可以了,并且如果他输入新的模型名称也可以了)。
关于发生了什么的任何想法?
编辑 :创建操作的HttpGet:
public ActionResult Create()
{
ProductViewModel pvm = new ProductViewModel();
var productTypeList = from obj in db.ProductTypes orderby obj.ProductCompany.Name ascending where !((from element in db.VehicleTypes select element.Id_ProductType).Contains(obj.Id_ProductType)) select obj;
ViewBag.Id_ProductType = new SelectList(productTypeList, "Id_ProductType", "Information");
pvm.ProductTypes = productTypeList.ToList().Select(p => new SelectListItem { Text = p.Information, Value = p.Id_ProductType.ToString() }).ToList();
ViewBag.Id_ProductCompany = new SelectList(db.ProductCompanies, "Id_ProductCompany", "Name");
pvm.ProductCompanies = db.ProductCompanies.ToList().Select(c => new SelectListItem { Text = c.Name, Value = c.Id_ProductCompany.ToString() }).ToList();
return View(pvm);
}
由于从注释:更改@Html.DropDownListFor(p => p.Product.ProductType.Id_ProductType, Model.ProductTypes)
在视图中@Html.DropDownListFor(p => p.Product.Id_ProductType, Model.ProductTypes)
即只将产品的ID_ProductType设置为选定的值,而不创建具有该ID的(新)ProductType对象。
然后,在Create方法中,更改
else
{
productType = new ProductType()
{
Id_ProductType = pvm.Product.Id_ProductType,
Id_ProductCompany = pvm.Product.ProductType.Id_ProductCompany
};
}
product.ProductType = productType;
db.Products.AddObject(product);
db.SaveChanges();
至
else
{
product.Id_ProductType = pvm.Product.Id_ProductType,
}
product.ProductType = productType;
db.Products.AddObject(product);
db.SaveChanges();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.