C# MVC 4回发空视图模型

C# MVC 4回发空视图模型,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,好的,关于这一点有很多问题,但我似乎无法让它发挥作用。这应该很简单,但让我挠头 控制器: [HttpPost] public ActionResult Edit(BookingIndexViewModel vm) // Also tried BookingViewModel { return View(); } public class BookingIndexViewModel { public int id { get; set; } public List<

好的,关于这一点有很多问题,但我似乎无法让它发挥作用。这应该很简单,但让我挠头

控制器:

[HttpPost]
public ActionResult Edit(BookingIndexViewModel vm) // Also tried BookingViewModel
{
    return View();
}
public class BookingIndexViewModel
{
    public int id { get; set; }

    public List<BookingViewModel> bookings { get; set; }
    public List<SelectListItem> allAttendances { get; set; }
}
容器视图模型:

[HttpPost]
public ActionResult Edit(BookingIndexViewModel vm) // Also tried BookingViewModel
{
    return View();
}
public class BookingIndexViewModel
{
    public int id { get; set; }

    public List<BookingViewModel> bookings { get; set; }
    public List<SelectListItem> allAttendances { get; set; }
}
视图

@model Project.ViewModels.BookingIndexViewModel
@using Project.ViewModels

<fieldset>
    <legend>Registered patients</legend>
    @if (Model.bookings.Count < 1)
    {
        <div>None currently registered</div>
    }
    else
    {
    <table>
        <tr>
            <th>
                <span class="display-label">@Html.LabelFor(model => model.bookings[0].forenames)</span>
            </th>
            <th>
                <span class="display-label">@Html.LabelFor(model => model.bookings[0].surname)</span>
            </th>
            <th>
                <span class="display-label">@Html.LabelFor(model => model.bookings[0].dob)</span>
            </th>
            <th>
                <span class="display-label">@Html.LabelFor(model => model.bookings[0].attendance</span>
            </th>
        </tr>

        @{
            foreach (BookingViewModel b in Model.bookings)
            {
                using (Html.BeginForm("Edit", "Booking"))
                {
                    @Html.HiddenFor(x => x.id)
                    <tr>
                        <td>
                            <span class="display-field">@b.forenames</span>
                        </td>
                        <td>
                            <span class="display-field">@b.surname</span>
                        </td>
                        <td>
                            <span class="display-field">@String.Format("{0:dd/MM/yyyy}", b.dob)</span>
                        </td>
                        <td>
                            @Html.DropDownListFor(model => b.attendanceStatusId, Model.allAttendances)
                        </td>
                        <td>
                            <input type="submit" value="Save" />
                        </td>
                    </tr>
                }
            }
        }
    </table>
    }
</fieldset>
foreach (BookingViewModel b in Model.bookings)
{
    using (Html.BeginForm("Edit", "Booking"))
    {
        @Html.HiddenFor(b => b.id);
        @Html.HiddenFor(b => b.referralId);
        @Html.DropDownListFor(b => b.attendanceId, Model.allAttendances)
    }
}
@model Project.ViewModels.BookingIndexViewModel
@使用Project.ViewModels
登记病人
@if(Model.bookings.Count<1)
{
目前没有注册
}
其他的
{
@Html.LabelFor(model=>model.bookings[0].名字)
@Html.LabelFor(model=>model.bookings[0]。姓氏)
@Html.LabelFor(model=>model.bookings[0].dob)
@Html.LabelFor(model=>model.bookings[0]。出勤率
@{
foreach(模型.预订中的预订视图模型b)
{
使用(Html.BeginForm(“编辑”、“预订”))
{
@Html.HiddenFor(x=>x.id)
@b、 名字
@b、 姓
@String.Format(“{0:dd/MM/yyyy}”,b.dob)
@Html.DropDownListFor(model=>b.attendanceStatusId,model.allAttendances)
}
}
}
}
因此,视图接受容器视图模型
BookingIndexViewModel
,并为每个持有的
BookingViewModel
创建一个表单。提交时,我希望它将带有修改的
BookingViewModel
的容器视图模型传回,但它总是空的。我还尝试了使用单个
BookingViewModel
MVC提交的水合视图模型是否与给定给视图的类型或从表单块中推断的类型相同

我从视图中检索到的唯一重要值是修改后的attendanceId(应该由下拉助手填写)和预订id。

ASP.NET MVC中没有“回发”。它与HTTP一样是无状态的。 如果要向服务器提交某些内容,则必须将其包含在表单中

我认为将整个对象列表从视图模型传递回服务器不是一个好主意。
您有一个
Edit
操作。将其参数类型更改为
BookingViewModel
。这将允许您编辑单个预订项目。然后在表单中添加类似
@Html.HiddenFor(x=>x.referralId)
的内容。

在查看了我使用
for(){}
而不是
foreach(){}给出的类似问题之后
现在它可以工作了。我希望它与每种类型循环中元素的易变性有关。

MVC实际上没有提交任何特定内容,也不知道您希望提交给某个操作的
ViewModel
。它不会像“viewstate”一样重新发布您的
ViewModel

最终,它只会在表单中发布html中的任何输入元素,而Action方法在被调用时,会尝试(使用绑定器)从包含在POST中的值中提取(声明为参数的)任何内容

在您的情况下,您似乎只会提交一个隐藏的IdattendanceStatusId。如果查看浏览器的实际网络流量,您会注意到正在发布的内容

因此,您的操作应该需要一个不同的ViewModel,它有两个与这些输入字段名匹配的属性。

您应该知道模型绑定在asp.mvc中是如何工作的,这里有一个很好的链接,提供了有关asp.mvc模型绑定的详细信息 虽然这篇文章很长,但它将帮助您了解模型绑定是如何工作的

此外,您还应该查看html页面,了解html控件是如何命名的
通过razor helpers,您可以在razor页面中查看模型

,问题几乎肯定与您如何渲染该模型有关

foreach (BookingViewModel b in Model.bookings)
{
    @Html.HiddenFor(x => x.id);
    ...
    @Html.DropDownListFor(model => b.attendanceStatusId, Model.allAttendances)
}
上面的HTML看起来像

<form ... >
<input type="hidden" name="BookingIndexViewModel.id" ... />
<select name="BookingViewModel.attendanceStatusId" ... />
</form>
...
<form ... >
<input type="hidden" name="BookingIndexViewModel.id" ... />
<select name="BookingViewModel.attendanceStatusId" ... />
</form>
...
查看

@model Project.ViewModels.BookingIndexViewModel
@using Project.ViewModels

<fieldset>
    <legend>Registered patients</legend>
    @if (Model.bookings.Count < 1)
    {
        <div>None currently registered</div>
    }
    else
    {
    <table>
        <tr>
            <th>
                <span class="display-label">@Html.LabelFor(model => model.bookings[0].forenames)</span>
            </th>
            <th>
                <span class="display-label">@Html.LabelFor(model => model.bookings[0].surname)</span>
            </th>
            <th>
                <span class="display-label">@Html.LabelFor(model => model.bookings[0].dob)</span>
            </th>
            <th>
                <span class="display-label">@Html.LabelFor(model => model.bookings[0].attendance</span>
            </th>
        </tr>

        @{
            foreach (BookingViewModel b in Model.bookings)
            {
                using (Html.BeginForm("Edit", "Booking"))
                {
                    @Html.HiddenFor(x => x.id)
                    <tr>
                        <td>
                            <span class="display-field">@b.forenames</span>
                        </td>
                        <td>
                            <span class="display-field">@b.surname</span>
                        </td>
                        <td>
                            <span class="display-field">@String.Format("{0:dd/MM/yyyy}", b.dob)</span>
                        </td>
                        <td>
                            @Html.DropDownListFor(model => b.attendanceStatusId, Model.allAttendances)
                        </td>
                        <td>
                            <input type="submit" value="Save" />
                        </td>
                    </tr>
                }
            }
        }
    </table>
    }
</fieldset>
foreach (BookingViewModel b in Model.bookings)
{
    using (Html.BeginForm("Edit", "Booking"))
    {
        @Html.HiddenFor(b => b.id);
        @Html.HiddenFor(b => b.referralId);
        @Html.DropDownListFor(b => b.attendanceId, Model.allAttendances)
    }
}

我知道MVC是无状态的,可能我使用了不正确的术语,但我已经在表单中包含了我想要的所有内容。此外,鉴于每个
BookingViewModel
都有自己的表单,我不会将整个列表发送回服务器-检查视图。明白。当您提交表单时,缺少哪个字段?缺少所有内容,将不会不要从提交的数据中绑定任何属性-直到我用一个普通的for循环替换了foreach!感谢您提供的大量信息。为什么使用负号?至少请礼貌地留下一个原因。小问题,如果在foreach中已经定义了HiddenFor标记,您如何使用“b”变量?