C# 在@html.Editorfor Razor中组合多个属性
我们必须在Razor视图中将多个属性合并到一个EditorFor字段中 我们有数量、计量单位和成分的属性。这些信息需要组合在一起,以便用户只需键入他或她需要的内容,即10公斤土豆,而不是将信息输入多个字段 完成后,我们还需要自动完成计量单位和成分属性 我已经为这段代码创建了一个局部视图C# 在@html.Editorfor Razor中组合多个属性,c#,asp.net-mvc,asp.net-mvc-4,razor,properties,C#,Asp.net Mvc,Asp.net Mvc 4,Razor,Properties,我们必须在Razor视图中将多个属性合并到一个EditorFor字段中 我们有数量、计量单位和成分的属性。这些信息需要组合在一起,以便用户只需键入他或她需要的内容,即10公斤土豆,而不是将信息输入多个字段 完成后,我们还需要自动完成计量单位和成分属性 我已经为这段代码创建了一个局部视图 @model IEnumerable<RecipeApplication.Models.RecipeLine> <div class="form-group"> @Html.Lab
@model IEnumerable<RecipeApplication.Models.RecipeLine>
<div class="form-group">
@Html.Label("Ingrediënten", htmlAttributes: new { @class = "control-label col-md-2" })
<div>
@foreach (var item in Model)
{
<p>
@Html.EditorFor(modelItem => item.Quantity, new { htmlAttributes = new { @class = "form-control-inline" } })
@Html.EditorFor(modelItem => item.UnitOfMeasure.Abbreviation, new { htmlAttributes = new { @class = "form-control-inline" } })
@Html.EditorFor(modelItem => item.Ingredient.Name, new { htmlAttributes = new { @class = "form-control-inline" } })
</p>
}
</div>
</div>
我看过谷歌和StackOverflow,但我找不到一个合适的答案来完成这项工作
就我个人而言,此刻我甚至不知道从哪里开始
我希望有人能帮我弄清楚这件事
谢谢 在ReceipLine上添加新的getter属性 C#6.0语法:
public string QuantityUomIngredient =>
$"{Quantity} {UnitOfMeasure?.Abbreviation ?? ""} {Ingredient?.Name ?? ""}";
那么你的观点应该是这样的
@Html.EditorFor(modelItem => item.QuantityUomIngredient ...
然后构建一个自定义模型绑定器,将QuantityUomingCredition解析为其相应的属性(这一部分的实现应该很有趣)。但是一定要对输入进行良好的验证,这样您就有了好的数据来解析。感谢anwer Leo Nix,它肯定让我找到了正确的方向 这是我到目前为止写的代码,它看起来很有魅力。(我还没有包括错误处理。) 还有我写的定制活页夹。这一次需要额外的研究
class RecipeLineCustomBinder : DefaultModelBinder
{
private RecipeApplicationDb db = new RecipeApplicationDb();
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
HttpRequestBase request = controllerContext.HttpContext.Request;
// Get the QuantityCustomIngredient from the webform.
string quantityUomIngredient = request.Form.Get("QuantityUomIngredient");
// Get the IngredientID from the webform.
int recipeID = int.Parse(request.Form.Get("RecipeId"));
// Split the QuantityCustomIngredient into seperate strings.
string[] quantityUomIngredientArray = quantityUomIngredient.Split();
//string[] quantityUomIngredientArray = quantityUomIngredient.Split(new string[] { " " }, 2, StringSplitOptions.RemoveEmptyEntries);
if (quantityUomIngredientArray.Length >= 3)
{
// Get the quantity value
double quantityValue;
bool quantity = double.TryParse(quantityUomIngredientArray[0], out quantityValue);
// Get the UOM value.
string uom = quantityUomIngredientArray[1];
UnitOfMeasureModel unitOfMeasure = null;
bool checkUOM = (from x in db.UnitOfMeasures
where x.Abbreviation == uom
select x).Count() > 0;
if (checkUOM)
{
unitOfMeasure = (from x in db.UnitOfMeasures
where x.Abbreviation == uom
select x).FirstOrDefault();
}
// Get the ingredient out of the array.
string ingredient = "";
for (int i = 2; i < quantityUomIngredientArray.Length; i++)
{
ingredient += quantityUomIngredientArray[i];
if (i != quantityUomIngredientArray.Length - 1)
{
ingredient += " ";
}
}
bool checkIngredient = (from x in db.Ingredients where x.Name == ingredient select x).Count() > 0;
IngredientModel Ingredient = null;
if (checkIngredient)
{
Ingredient = (from x in db.Ingredients
where x.Name == ingredient
select x).FirstOrDefault();
}
// Return the values.
return new RecipeLine
{
Quantity = quantityValue,
UnitOfMeasure = unitOfMeasure,
Ingredient = Ingredient,
RecipeId = recipeID
};
}
else
{
return null;
}
}
}
最后将自定义绑定器添加到控制器
[HttpPost]
public ActionResult Create([ModelBinder(typeof(RecipeLineCustomBinder))] RecipeLine recipeLine)
{
if (ModelState.IsValid)
{
db.RecipeLines.Add(recipeLine);
db.SaveChanges();
return RedirectToAction("Index", new { id = recipeLine.RecipeId });
}
return View(recipeLine);
}
我希望这也能帮助其他开发者 向接受输入的模型添加一个字符串字段,并在控制器中对其进行解析。没有一个标准控件可以在一个字符串中输入多个模型值。@D Stanley我会使用自定义模型绑定器来实现类似的功能,而不是向模型中添加一个只需解析的字段,在绑定器中提取它,在那里解析它,然后按预期填充模型。回答得好!我不知道getter在做什么,但定制的模型绑定器是这里的关键,如果你有VS 2015,那就太棒了!看看:这听起来真的很好@LeoNix。我将开始工作,并张贴它回来,一旦我得到这个工作。
class RecipeLineCustomBinder : DefaultModelBinder
{
private RecipeApplicationDb db = new RecipeApplicationDb();
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
HttpRequestBase request = controllerContext.HttpContext.Request;
// Get the QuantityCustomIngredient from the webform.
string quantityUomIngredient = request.Form.Get("QuantityUomIngredient");
// Get the IngredientID from the webform.
int recipeID = int.Parse(request.Form.Get("RecipeId"));
// Split the QuantityCustomIngredient into seperate strings.
string[] quantityUomIngredientArray = quantityUomIngredient.Split();
//string[] quantityUomIngredientArray = quantityUomIngredient.Split(new string[] { " " }, 2, StringSplitOptions.RemoveEmptyEntries);
if (quantityUomIngredientArray.Length >= 3)
{
// Get the quantity value
double quantityValue;
bool quantity = double.TryParse(quantityUomIngredientArray[0], out quantityValue);
// Get the UOM value.
string uom = quantityUomIngredientArray[1];
UnitOfMeasureModel unitOfMeasure = null;
bool checkUOM = (from x in db.UnitOfMeasures
where x.Abbreviation == uom
select x).Count() > 0;
if (checkUOM)
{
unitOfMeasure = (from x in db.UnitOfMeasures
where x.Abbreviation == uom
select x).FirstOrDefault();
}
// Get the ingredient out of the array.
string ingredient = "";
for (int i = 2; i < quantityUomIngredientArray.Length; i++)
{
ingredient += quantityUomIngredientArray[i];
if (i != quantityUomIngredientArray.Length - 1)
{
ingredient += " ";
}
}
bool checkIngredient = (from x in db.Ingredients where x.Name == ingredient select x).Count() > 0;
IngredientModel Ingredient = null;
if (checkIngredient)
{
Ingredient = (from x in db.Ingredients
where x.Name == ingredient
select x).FirstOrDefault();
}
// Return the values.
return new RecipeLine
{
Quantity = quantityValue,
UnitOfMeasure = unitOfMeasure,
Ingredient = Ingredient,
RecipeId = recipeID
};
}
else
{
return null;
}
}
}
<div class="form-group">
@Html.LabelFor(model => model.QuantityUomIngredient, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.QuantityUomIngredient, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuantityUomIngredient, "", new { @class = "text-danger" })
</div>
</div>
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ModelBinders.Binders.Add(typeof(RecipeLine), new RecipeLineCustomBinder());
}
}
[HttpPost]
public ActionResult Create([ModelBinder(typeof(RecipeLineCustomBinder))] RecipeLine recipeLine)
{
if (ModelState.IsValid)
{
db.RecipeLines.Add(recipeLine);
db.SaveChanges();
return RedirectToAction("Index", new { id = recipeLine.RecipeId });
}
return View(recipeLine);
}