如何制作相关对象?

时间:2014-02-07 08:59:52

标签: c# asp.net-mvc entity-framework

我正在使用带有EntityFramework的MVC 5,我似乎无法使用数据注释将相关对象选择为必填字段。

我的模型非常简单。这是我的Movement.cs模型:

public class Movement
{
    [Key]
    public int MovementID { get; set; }

    [Required(ErrorMessage = "Type is required.")]
    [MaxLength(50, ErrorMessage = "Type cannot be longer than 50 characters.")]
    public string Type { get; set; }

    [Required(ErrorMessage = "Persons name is required.")]
    public virtual Person Name { get; set; }

    [Required(ErrorMessage = "Location is required.")]
    public virtual Location Location { get; set; }

}

运动有两个相关的实体,人物和位置,这是非常简单的流氓。在我的创建运动表单中,我使用以下ViewModel:

public class MovementFormViewModel
{
    public Movement Movement { get; set; }
    public IEnumerable<SelectListItem> Types { get; set; }

    public int? SelectedLocation { get; set; }
    public int? SelectedPerson { get; set; }

}

这是我的控制器:

   private MovementFormViewModel createViewModel(Movement movement)
   {
       var types = new[]
            {
                new SelectListItem{ Text="Transfer", Value = "Transfer" },
                new SelectListItem{ Text="Promotion", Value = "Promotion" },
                new SelectListItem{ Text="N/A", Value = "N/A" }
            };

        var locations = db.Locations.ToArray().Select(x => new SelectListItem
        {
            Value = x.LocationID.ToString(),
            Text = x.Name
        });

        var people = db.People.ToArray().Select(x => new SelectListItem
        {
            Value = x.PersonID.ToString(),
            Text = x.FullName
        });

        MovementFormViewModel viewModel = new MovementFormViewModel
        {
            Movement = movement,
            Types = types,
            Locations = locations,
            People = people

        };

        return viewModel;

    }


    public ActionResult Create()
    {
        return View(createViewModel(new Movement()));
    }

最后,我的创建视图为我的相关实体提供了以下内容:

            @Html.DropDownListFor(
                x => x.SelectedPerson,
                Model.People,
                "-- Select a Person --")

            <p class="text-error">
                @Html.ValidationMessageFor(model => model.MarketMovement.Name)
            </p>

如果我提交表单,那么我得到验证错误,我的人员和位置字段是必需的......但是当我从下拉列表中选择一个条目并尝试重新提交时,表单仍然会提示验证条目是必需的,我无法继续。

我做错了什么?

2 个答案:

答案 0 :(得分:1)

首先,不建议在非原始类型上设置DataAnnotations,如下所示:

[Required(ErrorMessage = "Persons name is required.")]
public virtual Person Name { get; set; }

[Required(ErrorMessage = "Location is required.")]
public virtual Location Location { get; set; }

实际上,您的Name属性不是Name,而是整个Person对象。

一般来说,主要问题在于,当您选择一个项目时,它不会绑定到您的MovementFormViewModel.Movement.Person,而只会设置MovementFormViewModel.SelectedPerson。因此MovementFormViewModel.Movement.Person保持为空并且发生验证错误。

因此我建议从Movement类中删除Required属性,因为无论如何似乎都没有使用它。您应该将验证移到视图模型类中:

public class MovementFormViewModel
{
    public Movement Movement { get; set; }
    public IEnumerable<SelectListItem> Types { get; set; }

    [Required(ErrorMessage = "Location is required.")]
    public int SelectedLocation { get; set; }
    [Required(ErrorMessage = "Persons name is required.")]
    public int SelectedPerson { get; set; }

}

如上所述,您无法使用Nullable<int>int?),您应该使用不可为空的整数(int)来正确地进行验证工作。

答案 1 :(得分:0)

当您提交时,Selectedperson实际上是否已在您的模型中设置? 对于相同的任务,我创建了SelectedPersonID并将其标记为必需。

如此处所述http://odetocode.com/blogs/scott/archive/2013/03/11/dropdownlistfor-with-asp-net-mvc.aspx