Html.BeginForm() 未通过模型
Html.BeginForm() not passing the model
我有以下 cshtml 表单:
model Scraper.Facade.PlayerRow
@using (Html.BeginForm("Calculate", "Home", FormMethod.Post))
{
<table class="table table-striped table-bordered table-condensed table-responsive table-hover">
@foreach (var player in Model.AttribsPlayerLine)
{
<thead>
<tr class="success">
@foreach (var attrib in player.AttribsPlayerList)
{
//@Html.DisplayNameFor(x => Model.tytul)
<th data-field="@attrib.attribName">@Html.DisplayFor(x => attrib.attribName) </th>
}
</tr>
<tr class="active">
@foreach (var attrib in player.AttribsPlayerList)
{
<td data-field="@attrib.attribValue">@Html.TextBoxFor(x => attrib.attribValue)</td>
}
</tr>
</thead>
}
</table>
<input class="btn-danger" type="submit" name="Next >>" value="Next >>" />
}
显示正确,然后我尝试在以下控制器 ActionResult 中获取模型
[HttpPost]
public ActionResult Calculate(PlayerRow model)
{
GenericHelper _genericHelper = new GenericHelper();
return View();
}
但是 PlayerRow 模型始终为空。
我做错了什么?
这是我的模型定义
public PlayerRow LoadHtmlDoc(string fileLocation)
{
List<Attrib> attribsHeaderList = new List<Attrib>();
var playerRow = new PlayerRow();
playerRow.AttribsPlayerLine = new List<AttribLine>();
var htmlDoc = new HtmlDocument { OptionFixNestedTags = true };
// There are various options, set as needed
// filePath is a path to a file containing the html
htmlDoc.Load(fileLocation);
}
public class PlayerRow
{
public List<AttribLine> AttribsPlayerLine;
}
更新
大家好,我稍微改变了我的应用程序的逻辑,基本上有 2 个具有 Header 属性的列表,以及所有玩家的属性,所以现在只有 2 个 类,我像这样更改了 cshtml,现在可以使用了:-
@using (Html.BeginForm("Calculate", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<table class="table table-striped table-bordered table-condensed table-responsive table-hover">
<tr>
@for (int k = 0; k < Model.HeaderAttributes.Count; k++)
{
<td>
@Html.DisplayFor(x => x.HeaderAttributes[k].AttributeName)
@Html.HiddenFor(x => x.HeaderAttributes[k].AttributeName)
</td>
}
</tr>
@for (int i = 0; i < Model.PlayerList.Count; i++)
{
<tr>
<td>
@Html.DisplayFor(x => x.PlayerList[i].PlayerName)
@Html.HiddenFor(x => x.PlayerList[i].PlayerName)
</td>
@for (int j = 0; j < Model.PlayerList[i].AttributesList.Count; j++)
{
<td>
@Html.DisplayFor(x => x.PlayerList[i].AttributesList[j].AttributeValue)
@Html.HiddenFor(x => x.PlayerList[i].AttributesList[j].AttributeValue)
</td>
}
</tr>
}
</table>
<input class="btn-danger" type="submit" name="Next >>" value="Next >>" />
}
现在我的问题是,谁来授予答案,因为我可以说大多数答案对我的解决方案都非常有帮助
您正确地将模型传递给了视图,但是一旦它到达视图,模型数据将基本上是 'cleared',除非您编辑它或将它传递给下一个控制器,在这种情况下"Calculate".
我不确定您要将视图模型的哪些部分传递给控制器,但您始终可以使用它:
@Html.HiddenFor(model => model.DataYouWantPassedToController)
现在,如果您想 edit/change:
,您也可以随时使用这些项目来传递数据
@Html.EditorFor(model => model.DataYouWantToEditAndPass)... and so on.
如果您只是循环遍历数据而不更改或传递数据,就像您在@foreach 中所做的那样,数据将在您的 'Post' 方法执行期间丢失。
这是您正在尝试执行的操作的示例。这是我能给你的最接近的结果了。
让我们从简化模型开始:
public class PlayerRow
{
public List<AttribLine> AttribsPlayerLine { get; set; }
}
public class AttribLine
{
public string attribName { get; set; }
public string attribValue { get; set; }
}
请注意,重要的是要包含 { get;放; } 在每个模型上 属性 所以模型绑定器知道它在绑定块上。
接下来是仅查看 form() 部分的简化视图:
@using (Html.BeginForm("Calculate", "PlayerRow", FormMethod.Post))
{
<table>
@*/*Build out header*/*@
<tr>
@foreach (AttribLine a in Model.AttribsPlayerLine)
{
<th>@Html.Label("title", a.attribName)</th>
}
</tr>
@*/* Add row of our player attributes */*@
<tr>
@foreach (AttribLine a in Model.AttribsPlayerLine)
{
using (Html.BeginCollectionItem("AttribsPlayerLine"))
{
<td>
@Html.TextBox("attribValue", a.attribValue)
@Html.Hidden("attribName", a.attribName)
@*
/* Add any more [AttribLine] properties as hidden here */
*@
</td>
}
}
</tr>
</table>
<input class="btn-danger" type="submit" name="Next >>" value="Next >>" />
}
请注意,重要的是要确保即使 属性 用户不可编辑,它也需要作为隐藏元素包含在我们的 CollectionItem 中,以便模型绑定器可以将其设置为[POST]
希望对您有所帮助。
尝试像这样使用 @Html.EditorForModel()
:
@model Scraper.Facade.PlayerRow
@using (Html.BeginForm("Calculate", "Home", FormMethod.Post))
{
@Html.EditorForModel()
<input class="btn-danger" type="submit" name="Next >>" value="Next >>" />
}
在文件夹 Views/Shared/EditorTemplates 上创建一个名为 PlayerRow.cshtml
的文件作为 PartialView 并添加以下代码:
@model Scraper.Facade.PlayerRow
<table class="table table-striped table-bordered table-condensed table-responsive table-hover">
@foreach (var player in Model.AttribsPlayerLine)
{
<thead>
<tr class="success">
@foreach (var attrib in player.AttribsPlayerList)
{
//@Html.DisplayNameFor(x => Model.tytul)
<th data-field="@attrib.attribName">@Html.DisplayFor(x => attrib.attribName) </th>
}
</tr>
<tr class="active">
@foreach (var attrib in player.AttribsPlayerList)
{
<td data-field="@attrib.attribValue">@Html.TextBoxFor(x => attrib.attribValue)</td>
}
</tr>
</thead>
}
</table>
我想这会对你有所帮助。
我有以下 cshtml 表单:
model Scraper.Facade.PlayerRow
@using (Html.BeginForm("Calculate", "Home", FormMethod.Post))
{
<table class="table table-striped table-bordered table-condensed table-responsive table-hover">
@foreach (var player in Model.AttribsPlayerLine)
{
<thead>
<tr class="success">
@foreach (var attrib in player.AttribsPlayerList)
{
//@Html.DisplayNameFor(x => Model.tytul)
<th data-field="@attrib.attribName">@Html.DisplayFor(x => attrib.attribName) </th>
}
</tr>
<tr class="active">
@foreach (var attrib in player.AttribsPlayerList)
{
<td data-field="@attrib.attribValue">@Html.TextBoxFor(x => attrib.attribValue)</td>
}
</tr>
</thead>
}
</table>
<input class="btn-danger" type="submit" name="Next >>" value="Next >>" />
}
显示正确,然后我尝试在以下控制器 ActionResult 中获取模型
[HttpPost]
public ActionResult Calculate(PlayerRow model)
{
GenericHelper _genericHelper = new GenericHelper();
return View();
}
但是 PlayerRow 模型始终为空。
我做错了什么?
这是我的模型定义
public PlayerRow LoadHtmlDoc(string fileLocation)
{
List<Attrib> attribsHeaderList = new List<Attrib>();
var playerRow = new PlayerRow();
playerRow.AttribsPlayerLine = new List<AttribLine>();
var htmlDoc = new HtmlDocument { OptionFixNestedTags = true };
// There are various options, set as needed
// filePath is a path to a file containing the html
htmlDoc.Load(fileLocation);
}
public class PlayerRow
{
public List<AttribLine> AttribsPlayerLine;
}
更新
大家好,我稍微改变了我的应用程序的逻辑,基本上有 2 个具有 Header 属性的列表,以及所有玩家的属性,所以现在只有 2 个 类,我像这样更改了 cshtml,现在可以使用了:-
@using (Html.BeginForm("Calculate", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<table class="table table-striped table-bordered table-condensed table-responsive table-hover">
<tr>
@for (int k = 0; k < Model.HeaderAttributes.Count; k++)
{
<td>
@Html.DisplayFor(x => x.HeaderAttributes[k].AttributeName)
@Html.HiddenFor(x => x.HeaderAttributes[k].AttributeName)
</td>
}
</tr>
@for (int i = 0; i < Model.PlayerList.Count; i++)
{
<tr>
<td>
@Html.DisplayFor(x => x.PlayerList[i].PlayerName)
@Html.HiddenFor(x => x.PlayerList[i].PlayerName)
</td>
@for (int j = 0; j < Model.PlayerList[i].AttributesList.Count; j++)
{
<td>
@Html.DisplayFor(x => x.PlayerList[i].AttributesList[j].AttributeValue)
@Html.HiddenFor(x => x.PlayerList[i].AttributesList[j].AttributeValue)
</td>
}
</tr>
}
</table>
<input class="btn-danger" type="submit" name="Next >>" value="Next >>" />
}
现在我的问题是,谁来授予答案,因为我可以说大多数答案对我的解决方案都非常有帮助
您正确地将模型传递给了视图,但是一旦它到达视图,模型数据将基本上是 'cleared',除非您编辑它或将它传递给下一个控制器,在这种情况下"Calculate".
我不确定您要将视图模型的哪些部分传递给控制器,但您始终可以使用它:
@Html.HiddenFor(model => model.DataYouWantPassedToController)
现在,如果您想 edit/change:
,您也可以随时使用这些项目来传递数据 @Html.EditorFor(model => model.DataYouWantToEditAndPass)... and so on.
如果您只是循环遍历数据而不更改或传递数据,就像您在@foreach 中所做的那样,数据将在您的 'Post' 方法执行期间丢失。
这是您正在尝试执行的操作的示例。这是我能给你的最接近的结果了。
让我们从简化模型开始:
public class PlayerRow
{
public List<AttribLine> AttribsPlayerLine { get; set; }
}
public class AttribLine
{
public string attribName { get; set; }
public string attribValue { get; set; }
}
请注意,重要的是要包含 { get;放; } 在每个模型上 属性 所以模型绑定器知道它在绑定块上。
接下来是仅查看 form() 部分的简化视图:
@using (Html.BeginForm("Calculate", "PlayerRow", FormMethod.Post))
{
<table>
@*/*Build out header*/*@
<tr>
@foreach (AttribLine a in Model.AttribsPlayerLine)
{
<th>@Html.Label("title", a.attribName)</th>
}
</tr>
@*/* Add row of our player attributes */*@
<tr>
@foreach (AttribLine a in Model.AttribsPlayerLine)
{
using (Html.BeginCollectionItem("AttribsPlayerLine"))
{
<td>
@Html.TextBox("attribValue", a.attribValue)
@Html.Hidden("attribName", a.attribName)
@*
/* Add any more [AttribLine] properties as hidden here */
*@
</td>
}
}
</tr>
</table>
<input class="btn-danger" type="submit" name="Next >>" value="Next >>" />
}
请注意,重要的是要确保即使 属性 用户不可编辑,它也需要作为隐藏元素包含在我们的 CollectionItem 中,以便模型绑定器可以将其设置为[POST]
希望对您有所帮助。
尝试像这样使用 @Html.EditorForModel()
:
@model Scraper.Facade.PlayerRow
@using (Html.BeginForm("Calculate", "Home", FormMethod.Post))
{
@Html.EditorForModel()
<input class="btn-danger" type="submit" name="Next >>" value="Next >>" />
}
在文件夹 Views/Shared/EditorTemplates 上创建一个名为 PlayerRow.cshtml
的文件作为 PartialView 并添加以下代码:
@model Scraper.Facade.PlayerRow
<table class="table table-striped table-bordered table-condensed table-responsive table-hover">
@foreach (var player in Model.AttribsPlayerLine)
{
<thead>
<tr class="success">
@foreach (var attrib in player.AttribsPlayerList)
{
//@Html.DisplayNameFor(x => Model.tytul)
<th data-field="@attrib.attribName">@Html.DisplayFor(x => attrib.attribName) </th>
}
</tr>
<tr class="active">
@foreach (var attrib in player.AttribsPlayerList)
{
<td data-field="@attrib.attribValue">@Html.TextBoxFor(x => attrib.attribValue)</td>
}
</tr>
</thead>
}
</table>
我想这会对你有所帮助。