MVC 4中的模型为空。

3
我第一次使用Razor的ListBoxFor,但我的Model始终为空。阅读了类似的帖子和尝试后,它仍然无法正常工作。
Person.cshtml
@model SampleApp.Web.ViewModel.PersonViewModel

@{
     ViewBag.Title = "Welcome";
}

<article>
   <p>
      Welcome to example page. 
   </p>

   <p>
     <div class="container">

 //Post data works as expected, controllers create method write to db successfully 
 @using (Html.BeginForm("Create", "Person", FormMethod.Post, new { enctype =   "multipart/form-data" }))
 {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Personen</legend>

        <div class="editor-label">
           @* @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Age)
            @Html.ValidationMessageFor(model => model.Age)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Surrname)
        </div>
</fielset>
 </div>

 <p>
    <input type="submit" value="Create" />
 </p>
}

//binding to Model fails, Model is null. Not be able to debug anything in    controller action, it stops when "loading" the page
@using (Html.BeginForm("GetListBoxData", "Person"))
{
   @Html.AntiForgeryToken()
   @Html.ValidationSummary(true)
   @Html.ListBoxFor(model => model.ListboxData, Model.ListboxData);
}

</div>

PersonController.cs

[AcceptVerbs(HttpVerbs.Get)]
    [ValidateAntiForgeryToken]
    public ActionResult GetListBoxData()
    {
        var data = new List<PersonViewModel>();
        data.Add(new PersonViewModel{Name = "Test", Surrname="testsurrname", Age=30});

        var viewModel = new PersonViewModel()
        {
            ListboxData = data.AsEnumerable().Select(s=> new SelectListItem{Value=s.Name ,Text = s.Surrname}),
        };

        return View(viewModel);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    [ValidateAntiForgeryToken]
    public ActionResult GetListBoxData(PersonViewModel persondata)
    {
        //TODO: handle values from View
        return View(this);
    }

    [ValidateAntiForgeryToken]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create([Bind(Include = "Name, Surrname, Age")]  PersonViewModel persondata)
    {
        try
        {
            PersonService personDataProvider = new PersonService();
            personDataProvider.SavePerson(persondata);

            return new RedirectResult("SomewhereToGo");
        }
        catch (DataException ex)
        {
            //TODO: Log
        }

        return View(this);
    }

人员视图模型
public class PersonViewModel
{
    public int PersonId{ get; set; }
    public int Age { get; set; }
    public string Name { get; set; }
    public string Surrname { get; set; }
    public IEnumerable<SelectListItem> ListboxData { get; set; }
}

从editFor向db写入值正常,但没有为listboxfor编写代码。 在将其添加到我的HTML后,应该在页面加载时从数据库中填充它,但我在页面加载时收到了一个ReferenceNotSet异常。 在调用GetListBoxData操作之前,Model.ListboxData为空。
非常感谢您的帮助!

在您的视图文件中,为什么在模型声明后面有一个“<p>”? - Element
抱歉,之前有一些HTML代码,是从cshtml中复制粘贴过来的。 - nukleos
2
Person.cshtml?你的控制器是Index...你有一个Person操作吗?因为默认情况下它会通过那个路由。通常你会有index.cshtml。 - Keith Nicholas
1个回答

0
  1. 你的表单应该通过POST方式提交数据,而不是GET方式。除非你想通过表单上传文件,否则不需要使用enctype="multipart/form-data"
  2. 在你的控制器中需要两个Index Actions,一个用于将数据从控制器发送到视图,另一个用于在表单提交(POST)到服务器时从视图获取数据。
  3. 你传递给ListBox的第一个参数(表达式)是指你的模型中所选项存储的属性,这里是PersonId。

因此,你的视图应该像这样:

@model MVCApplication.Web.ViewModel.PersonViewModel 

@using (Html.BeginForm("Index", "Person"))
{
    @Html.ListBoxFor(model => model.PersonId, Model.ListBoxData)

    <input type="submit" value="Save" />
} 

然后,在您的控制器中,您将有两个像这样的操作:

public ActionResult Index()
{
    var viewModel = new PersonViewModel()
    {
        ListboxData = data.Select(s => new SelectListItem { Value = s.PersonId.ToString(), Text = s.PersonId.ToString() }).AsEnumerable();
    };

    return View(viewModel);
}

[HttpPost]
public ActionResult Index(PersonViewModel viewModel)
{
  // code to save the data in the database or whatever you want to do with the data coming from the View
}

顺便说一下,在ViewModel中,您不必像那样定义ListBoxData属性,只需这样做:

public class PersonViewModel
{
    public int PersonId{ get; set; }
    public IEnumerable<SelectListItem> ListBoxData { get; set; }
}

它在我的cshtml中停止,并引发了一个未设置引用的异常(因为Model为空)。 - nukleos
你的操作和我的答案完全一样吗?在你的操作中,你能从数据库中获取正确的数据吗? - ataravati
我需要知道的是您想要对ListBox做什么?当您从ListBox中选择一个选项时,您希望发生什么?您的视图中不应该有两个这样的表单。 - ataravati
另外,请完整地发布您的PersonViewModel。您只是发布了其一个端口。 - ataravati
我的视图模型中只有两个属性,目前对我的HTML来说已经足够了。 - nukleos
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接