ASP.NET MVC After Post Back List包含ViewModel中的List属性为null

时间:2014-08-22 20:05:49

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

正如我在ViewModel中的Post Back List(MySalonTreatments)属性后的标题中提到的那样。

我是MVC的新手,但我认为它应该可行。模型绑定器知道如何处理复杂类型。 我搜索了很多,但我没有得到任何解决方案。也许你可以指出我的错误。

视图模型:

public class CreateSalonViewModel
{
    public string Name { get; set; }

    [DataType(DataType.EmailAddress)]
    public string EmailAddress { get; set; }

    //it shouldn't be facebook adress
    public string Website { get; set; }

    public string MobilePhone { get; set; }

    public string LandlinePhone { get; set; }

    public int CityId { get; set; }

    public int ProvinceId { get; set; }

    public List<SalonTreatments> MySalonTreatments;
}

public class SalonTreatments
{
    public List<Treatment> SpecTypeTreaments { get; set; }
    public TreatmentType TreatmentType { get; set; }
}

控制器:

public class SalonController : Controller
{
    private CrsDatabase db = new CrsDatabase();

    //
    // GET: /Salon/Create
    [Authorize]
    [HttpGet]
    public ActionResult Create()
    {
        return View(GetCreateSalonViewModel());
    }

    [Authorize]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(CreateSalonViewModel createSalonViewModel)
    {
        return View(createSalonViewModel);
    }

    #region service methods

    private CreateSalonViewModel GetCreateSalonViewModel()
    {
        CreateSalonViewModel createSalonViewModel = new CreateSalonViewModel();
        createSalonViewModel.MySalonTreatments = new List<SalonTreatments>();

        foreach (var treatmentType in db.TreatmentType)
        {
            var treatmentOfSpecType = db.Treatment.Where(t => t.TreatmentType.Id == treatmentType.Id).ToList();
            if (treatmentOfSpecType.Count > 0)
            {
                SalonTreatments salonTreatments = new SalonTreatments();
                salonTreatments.TreatmentType = treatmentType;
                salonTreatments.SpecTypeTreaments = treatmentOfSpecType;

                createSalonViewModel.MySalonTreatments.Add(salonTreatments);
            }
        }

        return createSalonViewModel;
    }

    #endregion
}

查看:

@model CRSWebsite.ViewModels.CreateSalonViewModel

@using (Html.BeginForm("Create", "Salon", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>CreateSalonViewModel</h4>
        <hr />
        @Html.ValidationSummary(true)
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name)
                @Html.ValidationMessageFor(model => model.Name)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.EmailAddress, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.EmailAddress)
                @Html.ValidationMessageFor(model => model.EmailAddress)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Website, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Website)
                @Html.ValidationMessageFor(model => model.Website)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.MobilePhone, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.MobilePhone)
                @Html.ValidationMessageFor(model => model.MobilePhone)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.LandlinePhone, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.LandlinePhone)
                @Html.ValidationMessageFor(model => model.LandlinePhone)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.CityId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.CityId)
                @Html.ValidationMessageFor(model => model.CityId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ProvinceId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ProvinceId)
                @Html.ValidationMessageFor(model => model.ProvinceId)
            </div>
        </div>

        @for (int i = 0; i < Model.MySalonTreatments.Count; i++)
        {
            <label>Zabiegi @Model.MySalonTreatments[i].TreatmentType.Name:</label>
            <div class="form-group">
                <div class="col-md-10">
                    @for (int j = 0; j < Model.MySalonTreatments[i].SpecTypeTreaments.Count; j++)
                    {
                        @Html.CheckBoxFor(m => m.MySalonTreatments[i].SpecTypeTreaments[j].IsSelected)
                        @Html.DisplayFor(m => m.MySalonTreatments[i].SpecTypeTreaments[j].Name)
                    }
                </div>
            </div>
        }
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

此致 彼得

2 个答案:

答案 0 :(得分:3)

最后我解决了我的问题!

这是一个微不足道的问题,在我的viewmodel类CreateSalonViewModel中,我创建了治疗集合:

public List<SalonTreatments> MySalonTreatments;

但由于某些未知原因,模型绑定器无法解决此问题。正确的方法是:

public List<SalonTreatments> MySalonTreatments { get; set; }

感谢您的帮助!

答案 1 :(得分:1)

public ActionResult Create()似乎是用于显示表单的GET方法。您需要另一种方法来接受POST,并确保将HttpGet添加到第一个以确保MVC可以区分这两者。同时验证您的表单是否使用POSt方法提交表单:

[Authorize][HttpGet]
public ActionResult Create()
{
    return View(GetCreateSalonViewModel());
}

[HttpPost]
public ActionResult Create(CreateSalonViewModel model) 
{  // MVC will try to bind your POSTed form to parameters
...
}