正确传递viewmodel - 更改未在POST上显示

时间:2013-10-06 20:31:41

标签: asp.net asp.net-mvc

我的应用程序遇到问题。当用户动态添加行(javascript)以向'声明'添加更多'声明行'时,不会显示已发布的值,而是仅首先将“虚拟”值设置为ViewModel。因此,基本上任何用户修改或确实添加(新行)的内容都不会在POST上记录。

据我所知,我在控制器和视图之间传递了ViewModel,但显然我遗漏了一些东西。我一直在努力解决这个问题,你的帮助将非常感激。我是ASP.NET MVC的新手,也是一般的编程。 我跟随史蒂文桑德森的博客。

视图模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ef_tut.Models;
using ef_tut.ViewModels;
namespace ef_tut.ViewModels
{
    public class ClaimViewModel
    {
        public int ClaimID { get; set; }
        public int SubmissionUserID { get; set; }
        public DateTime? DateSubmitted { get; set; }
        public bool ApprovedYN { get; set; }
        public DateTime? DateApproved { get; set; }

        public ICollection<claimline> claimlines { get; set; }

    }
}

控制器

  using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Entity;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using ef_tut.Models;
    using ef_tut.DAL;
    using ef_tut.ViewModels;
    using ef_tut.WebUI.Helpers;
    namespace ef_tut.Controllers
    {
        public class ClaimsController : Controller
        {
            private ClaimContext db = new ClaimContext();

            private static ClaimViewModel _currentclaim;
            private static ClaimViewModel Currentclaim
            {
                get
                {
                    _currentclaim = GetClaimViewModel();
                    return _currentclaim;
                }
                set
                {
                    _currentclaim = value;
                }
            }

            public static ClaimViewModel GetClaimViewModel()
            {
                return new ClaimViewModel()
            {
                ClaimID =101,
                claimlines = new List<claimline>() {
                        new claimline() {ClaimantUserID =1},
                        new claimline() {ClaimantUserID =2},
                        new claimline() {ClaimantUserID =3}
                    }
            };}

            public ActionResult Create()
            {
                return View(Currentclaim);
            }

            public PartialViewResult BlankEditorRow()
            {


                return PartialView("NewRow");
            }

            [HttpPost]
            public ActionResult Create(ClaimViewModel ClaimViewModel)
            {
                Currentclaim = ClaimViewModel;

                return View("View2", Currentclaim);
            }
        }
    }

创建视图

@model ef_tut.ViewModels.ClaimViewModel
@using ef_tut.Models
@using ef_tut.ViewModels
@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>claim</legend>
                      @Html.HiddenFor(model => model.ClaimID)

        <ul id="editorRows">


                            @foreach (claimline claimline in Model.claimlines)
                            {
                                Html.RenderPartial("NewRow", claimline);
                }

        </ul> 


        <p>
               @Html.ActionLink("Add another...", "BlankEditorRow", null, new { id = "addItem" }) 

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



@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}
}   

部分

@model ef_tut.Models.claimline

@using ef_tut.WebUI.Helpers
    @using (Html.BeginCollectionItem("claims"))
    {
        <table class="editorRow">
   <tr >

                                                     <td>
            ClaimID(claimlinetable)@Html.EditorFor(model => model.ClaimID)
            </td>

       <td>
          ClaimantUserID:  @Html.EditorFor(model => model.ClaimantUserID)
            </td>
                               <td>
           Hours: @Html.EditorFor(model => model.Hours)
            </td>
                                                          <td>
           <a href="#" class="deleteRow">delete</a>
            </td>
               </tr></table>
    }

输出视图

@model ef_tut.ViewModels.ClaimViewModel
@using ef_tut.Models

@{
    ViewBag.Title = "View2";
}

<h2>View1</h2>

@Html.HiddenFor(model=>model.ClaimID)
    <ul>
        @foreach (claimline claimline in Model.claimlines){ 
            @claimline.ClaimantUserID; }
    </ul>

1 个答案:

答案 0 :(得分:1)

您需要使用BeginCollectionItem帮助程序,其参数collectionName等于视图模型中的集合名称(claimlines)。这是因为这个助手替换了HtmlFieldPrefix,为html字段生成的名称是: specified_collection_name [generated_index] .claimline_property_name

因此,在您的情况下,生成的输入名称如下: 权利要求书[generated_index] .Hours

但是mvc model binder在ClaimViewModel中找不到属性声明。

如果用@using(Html.BeginCollectionItem(“claimlines”)替换@using(Html.BeginCollectionItem(“claim”)),生成的输入名称将如下:

claimlines [generated_index] .Hours

和模型绑定器将按预期生成ClaimViewModel