我已经尝试了几个星期来关注如何创建动态表单的几个教程,使其能够在表单中添加另一个“成分”.这是我试图遵循的文章.
http://www.joe-stevens.com/2011/07/24/asp-net-mvc-2-client-side-validation-for-dynamic-fields-added-with-ajax/
现在我正在使用添加链接添加多个recipeIngredients,但是我需要在单击链接时同时添加“ingredientName”和“recipeIngredient”数量.
我的问题是,当我运行应用程序时,recipeingredient的表单有0而不是实际的文本框.当我点击添加新成分时,我可以添加一个文本框,但是当我输入金额并单击保存时,模型数据不会传递给控制器.
我甚至不知道从哪里开始修复这个,我不确定我是否应该使用viewmodel或者我是否会完全错误.这是我的数据库图http://i44.tinypic.com/xp1tog.jpg.
这是我的CreateView:
@model viewmodels.Recipeviewmodel @using Helpers; <h2>CreateFullRecipe</h2> <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> <script type="text/javascript"> $().ready(function () { $("#add-recipeingredient").click(function () { $.ajax({ url: '@Url.Action("GetNewRecipeIngredient")',success: function (data) { $(".new-recipeingredients").append(data); Sys.Mvc.FormContext._Application_Load(); } }); }); }); </script> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Recipe</legend> <div class="editor-label"> @Html.LabelFor(model => model.Recipe.RecipeName) </div> <div class="editor-field"> @Html.EditorFor(model => model.Recipe.RecipeName) @Html.ValidationMessageFor(model => model.Recipe.RecipeName) </div> </fieldset> <fieldset> <legend>RecipeIngredients</legend> <div class="new-recipeingredients"> @Html.EditorFor(model => model.RecipeIngredients) </div> <div style="padding: 10px 0px 10px 0px"> <a id="add-recipeingredient" href="javascript:void(0);">Add another</a> </div> </fieldset> <div> <input type="submit" value="CreateFullRecipe" /> </div> } <div> @Html.ActionLink("Back to List","Index") </div>
我对recipeingredient的editortemplateview:
@model Models.RecipeIngredient @using Helpers; @using (Html.BeginAjaxContentValidation("form0")) { using (Html.BeginCollectionItem("RecipeIngedients")) { <div style="padding: 5px 0px 5px 0px"> @Html.LabelFor(model => model.Amount) @Html.EditorFor(model => model.Amount) @Html.ValidationMessageFor(model => Model.Amount) </div> } }
我的控制器相关方法:
[HttpGet] public ActionResult CreateFullRecipe() { var recipeviewmodel = new Recipeviewmodel(); return View(recipeviewmodel); } // // POST: /Recipe/Create [HttpPost] public ActionResult CreateFullRecipe(Recipeviewmodel recipeviewmodel) { if (ModelState.IsValid) { db.Recipes.Add(recipeviewmodel.Recipe); db.SaveChanges(); int recipeID = recipeviewmodel.Recipe.RecipeID; for (int n = 0; n < recipeviewmodel.RecipeIngredients.Count(); n++) { db.Ingredients.Add(recipeviewmodel.Ingredients[n]); int ingredientID = recipeviewmodel.Ingredients[n].IngredientID; recipeviewmodel.RecipeIngredients[n].RecipeID = recipeID; recipeviewmodel.RecipeIngredients[n].IngredientID = ingredientID; db.RecipeIngredients.Add(recipeviewmodel.RecipeIngredients[n]); db.SaveChanges(); } return RedirectToAction("Index"); } return View(recipeviewmodel); } public ActionResult GetNewIngredient() { return PartialView("~/Views/Shared/IngredientEditorRow.cshtml",new Ingredient()); } public ActionResult GetNewRecipeIngredient() { return PartialView("~/Views/Shared/_RecipeIngredientEditRow.cshtml",new RecipeIngredient()); }
我的视图模型:
public class Recipeviewmodel { public Recipeviewmodel() { RecipeIngredients = new List<RecipeIngredient>() { new RecipeIngredient() }; Ingredients = new List<Ingredient>() { new Ingredient() }; Recipe = new Recipe(); } public Recipe Recipe { get; set; } public IList<Ingredient> Ingredients { get; set; } public IList<RecipeIngredient> RecipeIngredients { get; set; } } }
如果有任何其他信息需要帮助解决我的问题,请告诉我.这真的让我发疯,所以我期待着能得到任何帮助
谢谢!
我还想提一下,控制器发布方法createfullrecipe是用于预定义的列表,当我不担心给用户添加另一种成分的能力时它起作用,而我只是默认表单有2种成分而我的观点有这注释掉了创建它们的代码.我真正想做的就是让viewmodel将表单数据传递给控制器,我可以像我的createfullrecipe控制器方法那样处理数据.
@* @for (int n = 0; n < Model.Ingredients.Count(); n++) { <div class="editor-label"> @Html.LabelFor(model => model.Ingredients[n].IngredientName) </div> <div class="editor-field"> @Html.EditorFor(model => model.Ingredients[n].IngredientName) @Html.ValidationMessageFor(model => model.Ingredients[n].IngredientName) </div> <div class="editor-label"> @Html.LabelFor(model => model.RecipeIngredients[n].Amount) </div> <div class="editor-field"> @Html.EditorFor(model => model.RecipeIngredients[n].Amount) @Html.ValidationMessageFor(model => model.RecipeIngredients[n].Amount) </div> }*@
这是我的模型类:
public class Recipe { public int RecipeID { get; set; } public string RecipeName { get; set; } public string Description { get; set; } public int? PrepTime { get; set; } public int? CookTime { get; set; } public string ImageURL { get; set; } public virtual IList<RecipeTag> RecipeTags { get; set; } public virtual IList<Rating> Ratings { get; set; } public virtual IList<RecipeStep> RecipeSteps { get; set; } public virtual IList<RecipeIngredient> RecipeIngredients { get; set; } } public class RecipeIngredient { public int RecipeIngredientID { get; set; } public string IngredientDesc { get; set; } public string Amount { get; set; } public int RecipeID { get; set; } public int? IngredientID { get; set; } public virtual Recipe Recipe { get; set; } public virtual Ingredient Ingredient { get; set; } } public class Ingredient { public int IngredientID { get; set; } public string IngredientName { get; set; } public virtual ICollection<RecipeIngredient> RecipeIngredients { get; set; } }@H_502_34@
解决方法
您的代码存在很多问题.我更喜欢一步一步地说明一个简化的例子,你可以适应你的需要.
楷模:
public class Recipeviewmodel { public Recipe Recipe { get; set; } public IList<RecipeIngredient> RecipeIngredients { get; set; } } public class Recipe { public string RecipeName { get; set; } } public class RecipeIngredient { public int Amount { get; set; } [required] public string IngredientDesc { get; set; } }
控制器:
public class HomeController : Controller { public ActionResult Index() { var recipeviewmodel = new Recipeviewmodel(); return View(recipeviewmodel); } [HttpPost] public ActionResult Index(Recipeviewmodel recipeviewmodel) { if (!ModelState.IsValid) { // there wre validation errors => redisplay the view return View(recipeviewmodel); } // TODO: the model is valid => you could pass it to your // service layer for processing return RedirectToAction("Index"); } public ActionResult GetNewRecipeIngredient() { return PartialView("~/Views/Shared/EditorTemplates/RecipeIngredient.cshtml",new RecipeIngredient()); } }
查看(〜/ Views / Home / Index.cshtml):
@model Recipeviewmodel <script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> <script type="text/javascript"> $(function() { $('#add-recipeingredient').click(function () { $.ajax({ url: '@Url.Action("GetNewRecipeIngredient")',type: 'POST',success: function (data) { $('.new-recipeingredients').append(data); } }); return false; }); }); </script> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <div> @Html.LabelFor(model => model.Recipe.RecipeName) @Html.EditorFor(model => model.Recipe.RecipeName) @Html.ValidationMessageFor(model => model.Recipe.RecipeName) </div> <fieldset> <legend>RecipeIngredients</legend> <div class="new-recipeingredients"> @Html.EditorFor(model => model.RecipeIngredients) </div> <div style="padding: 10px 0px 10px 0px"> <a id="add-recipeingredient" href="javascript:void(0);">Add another</a> </div> </fieldset> <div> <input type="submit" value="CreateFullRecipe" /> </div> }
编辑模板(〜/ Views / Shared / EditorTemplates / RecipeIngredient.cshtml):
@model RecipeIngredient @using (Html.BeginCollectionItem("RecipeIngredients")) { <div> @Html.LabelFor(model => model.Amount) @Html.EditorFor(model => model.Amount) @Html.ValidationMessageFor(model => model.Amount) </div> <div> @Html.LabelFor(model => model.IngredientDesc) @Html.EditorFor(model => model.IngredientDesc) @Html.ValidationMessageFor(model => model.IngredientDesc) </div> }@H_502_34@ @H_502_34@ 原文链接:https://www.f2er.com/aspnet/251556.html