简体   繁体   English

绑定复杂模型和DropDownListFor

[英]Binding complex model and DropDownListFor

My entities: 我的实体:

public class Meal
{
    [HiddenInput(DisplayValue = false)]
    public int Id { get; set; }
    [Required(ErrorMessage = "Proszę podać nazwę posiłku")]
    public string Name { get; set; }
    [Required(ErrorMessage = "Proszę podać ilość białka")]
    [Range(0.00, double.MaxValue, ErrorMessage = "Proszę podać dodatnią ilość.")]
    public double Protein { get; set; }
    [Required(ErrorMessage = "Proszę podać ilość węglowodanów")]
    [Range(0.00, double.MaxValue, ErrorMessage = "Proszę podać dodatnią ilość.")]
    public double Carbohydrates { get; set; }
    [Required(ErrorMessage = "Proszę podać ilość tłuszczy")]
    [Range(0.00, double.MaxValue, ErrorMessage = "Proszę podać dodatnią ilość.")]
    public double Fat { get; set; }
    [Required(ErrorMessage = "Proszę podać ilość kalorii")]
    [Range(0.00, double.MaxValue, ErrorMessage = "Proszę podać dodatnią ilość.")]
    public double Calories { get; set; }
}

public class EatenMeal
{
    public int Id { get; set; }
    public virtual Meal Meal { get; set; }
    public virtual MealType MealType { get; set; }
    public double Serving { get; set; }
    public string Username { get; set; }
    public DateTime Date { get; set; }
}

public class MealType
{
    public int Id { get; set; }
    public string Name { get; set; }
}

In MealController's view MealList which displays meals from datebase. 在MealController的视图MealList中,该视图显示日期数据库中的膳食。 And there is a button "Add" which refers to action AddEatenMeal in EatenMealController. 并且有一个“添加”按钮,它引用EatenMealController中的操作AddEatenMeal。

public ActionResult AddEatenMeal(int id)
{
    var meal = mealRepository.GetMeal(id);
    EatenMeal eatenMeal = new EatenMeal() { Meal = meal, Username = User.Identity.Name };
    return View(eatenMeal);
}

[HttpPost]
public ActionResult AddEatenMeal(EatenMeal eatenMeal)
{
    if(ModelState.IsValid)
    {
        eatenMealRepository.AddEatenMeal(eatenMeal);
        RedirectToAction("Index", "Home");
    }
    return RedirectToAction("Index", "Home");
}

I am creating there object EatenMeal and partially initializing this object. 我在那里创建对象EatenMeal并部分初始化此对象。 Then I am passing this object to View to further initializing. 然后,我将此对象传递给View进行进一步的初始化。

@model Domain.Entities.EatenMeal

@{
    ViewBag.Title = "Dodawanie posiłku do dziennika";
}

@using (Html.BeginForm("AddEatenMeal","EatenMeal", FormMethod.Post, new {@class = "form"}))
{
    @Html.HiddenFor(x => x.Meal.Name)
    @Html.HiddenFor(x => x.Username)
    @Html.HiddenFor(x => x.Meal.Calories)
    @Html.HiddenFor(x => x.Meal.Carbohydrates)
    @Html.HiddenFor(x => x.Meal.Fat)
    @Html.HiddenFor(x => x..Meal.Protein)
    @Html.HiddenFor(x => x.Meal.Id)
    @Html.HiddenFor(x=>x.Username)
    <div class="form-group">
        @Html.Label("Nazwa posiłku")
        @Html.Label(Model.Meal.Name, new { @class = "form-control" })
    </div>
    <div class="form-group">
        @Html.Label("Porcja (g)")
        @Html.TextBoxFor(x => x.Serving, new { @class = "form-control" })
    </div>
    <div class="form-group">
        @Html.Label("Typ posiłku")
        @Html.DropDownListFor(x=>x.MealType)????
    </div>
    <div class="form-group">
        @Html.Label("Data spożycia")
        @Html.TextBoxFor(x => x.Date, new { @class = "form-control", @id="date-eaten", @Value=DateTime.Today.ToShortDateString()})
    </div>
    <input type="submit" class="btn btn-info" value="Dodaj" />
}

Now I have a question. 现在我有一个问题。 Is it correct to hiding fields? 隐藏字段是否正确? I don't know how I can save data from first controller to second in other way. 我不知道如何以其他方式将数据从第一个控制器保存到第二个控制器。 And is a second question. 这是第二个问题。 How I can make DropDownListFor for property MealTye in EatenMeal? 如何在EatenMeal中为属性MealTye制作DropDownListFor?

Rather than sending and receiving a whole lot of unused data across the wire and opening yourself to over posting attack, create a view model that represents what you want to display and edit. 创建一个表示您要显示和编辑的内容的视图模型,而不是通过网络发送和接收大量未使用的数据,并使自己免受过度发布攻击。 See What is a view model in MVC? 请参阅什么是MVC中的视图模型?

View model 查看模型

public class EatenMealVM
{
  public int MealID { get; set; }
  [Display(Name="Nazwa posiłku")]
  public string MealName { get; set; }
  [Display(Name = "Typ posiłku")]
  [Required(ErrorMessage = "Please select a meal")]
  public int? MealTypeID { get; set; }
  [Display(Name = "Porcja (g)")]
  public double Serving { get; set; } // is this really double?
  [Display(Name = "Data spożycia")]
  [DataType(DataType.Date)]
  public DateTime Date { get; set; }
  public SelectList MealTypeList { get; set; }
}

Controller 控制者

public ActionResult AddEatenMeal(int id)
{
  var meal = mealRepository.GetMeal(id);
  var mealTypes = // get the list of meal types from the database
  EatenMealVM model = new EatenMealVM()
  {
    MealID = meal.Id,
    MealName = meal.Name,
    MealTypeList = new SelectList(mealTypes, "ID", "Name")
  };
  return View(model);
}

View 视图

@model EatenMealVM
....
@using (Html.BeginForm())
{
  @Html.HiddenFor(m => m.MealID)

  @Html.DisplayNameFor(m => m.MealName)
  @Html.DisplayFor(m => m.MealName)

  @Html.LabelFor(m => m.MealTypeID)
  @Html.DropDownListFor(m => m.MealTypeID, Model.MealTypeList, "--Please select--")
  @Html.ValidationMessageFor(m => m.MealTypeID)

  @Html.LabelFor(m => m.Serving)
  @Html.TextBoxFor(m => m.Serving, new { @class = "form-control")
  @Html.ValidationMessageFor(m => m.Serving)

  @Html.LabelFor(m => m.Date)
  @Html.TextBoxFor(m => m.Date)
  @Html.ValidationMessageFor(m => m.Date, new { @class = "form-control" })

  <input type="submit" class="btn btn-info" value="Dodaj" />
}

Post method 发布方式

[HttpPost]
public ActionResult AddEatenMeal(EatenMealVM model)
{
  if (!ModelState.IsValid)
  {
    var mealTypes = // get the list of meal types from the database
    model.MealTypeList = new SelectList(mealTypes, "ID", "Name");
    return View(model);
  }
  // Initialize new EatenMeal class
  // Map properties from view model (including setting user name) 
  // Save and redirect
}

Note also the use of [Display] attribute and @Html.LabelFor() . 另请注意[Display]属性和@Html.LabelFor() Currently you not creating 'real' labels (they are not associated with the corresponding control) 当前,您尚未创建“真实”标签(它们未与相应的控件关联)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM