C# 在@html.Editorfor Razor中组合多个属性

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

我们必须在Razor视图中将多个属性合并到一个EditorFor字段中

我们有数量、计量单位和成分的属性。这些信息需要组合在一起,以便用户只需键入他或她需要的内容,即10公斤土豆,而不是将信息输入多个字段

完成后,我们还需要自动完成计量单位和成分属性

我已经为这段代码创建了一个局部视图

@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);
    }