绑定复杂模型和DropDownListFor

时间:2014-12-07 18:07:12

标签: c# asp.net-mvc-4

我的实体:

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

在MealController中查看MealList,显示来自datebase的膳食。并且有一个按钮"添加"它指的是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");
}

我正在创建对象EatenMeal并部分初始化此对象。然后我将此对象传递给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" />
}

现在我有一个问题。隐藏字段是否正确?我不知道如何以其他方式将数据从第一个控制器保存到第二个控制器。 这是第二个问题。如何在EatenMeal中为属性MealTye制作DropDownListFor?

1 个答案:

答案 0 :(得分:0)

不是通过网络发送和接收大量未使用的数据,而是打开过度发布攻击,创建一个代表您想要显示和编辑的视图模型。见What is a view model in MVC?

查看模型

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

控制器

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

查看

@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" />
}

发布方法

[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
}

还请注意使用[Display]属性和@Html.LabelFor()。目前你没有创造真正的&#39;标签(它们与相应的控件无关)