Return 一个 ViewBag ViewModel 回到 Controller 中的 BeginForm Post 方法中的 View
Return a ViewBag ViewModel back to Controller in BeginForm Post method in the View
我有一个在页面上显示 ViewModel 的视图。我想让用户按下一个按钮来创建一个 CSV 文件,然后通过电子邮件将其发送给他们。我有 POSt 工作,但是被发回的 ViewModel 总是空的,即使页面清楚地显示了很多行。
这是相关视图的一部分:
<table style="width:99%" cellpadding="3" class="ContentTable" border="1" align="center">
@using (Html.BeginForm("SubmitExcel", "AllRecognition", new { AllRecognitions = ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel }, FormMethod.Post, new { id = "submitExcel" }))
{
<tr>
<td style="padding:3px;">
<input type="submit" name="BtnSubmitExcel" id="BtnSubmitExcel" value="Export to Excel" />
</td>
</tr>
}
<tr style="background-color:#5D7B9D;color:white;">
<th style="width:4%;padding:3px;font-size:12px;">Date</th>
<th style="width:8%;padding:3px;font-size:12px;">Employee</th>
<th style="width:8%;padding:3px;font-size:12px;">Recognized By</th>
<th style="width:6%;padding:3px;font-size:12px;">5-Star Standard</th>
<th style="width:70%;padding:3px;font-size:12px;">Description</th>
<th style="width:4%;padding:3px;font-size:12px;">Points</th>
</tr>
@{
if (ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel != null)
{
foreach (Recognition.ViewModels.AllRecognitionViewModel item in ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel)
{
@:<tr>
@:<td style="width:4%;padding:3px;font-size:12px;">@item.Date</td>
@:<td style="width:8%;padding:3px;font-size:12px;">@item.Employee</td>
@:<td style="width:8%;padding:3px;font-size:12px;">@item.RecognizedBy</td>
@:<td style="width:6%;padding:3px;font-size:12px;">@item.FiveStarStandard</td>
@:<td style="width:70%;padding:3px;font-size:12px;">@item.Description</td>
@:<td style="width:4%;padding:3px;font-size:12px;">@item.Points</td>
@:</tr>
}
}
}
</table>
这是控制器端接收POST方法:
public ActionResult SubmitExcel(List<ViewModels.AllRecognitionViewModel> AllRecognitions)
{
ViewBag.NoSearch = "block";
ViewBag.SupervisorSearch = "none";
ViewBag.DepartmentSearch = "none";
ViewBag.EmployeeSearch = "none";
DataTable dtAllRecognitions = Base.SQLHelper.ConvertListToDataTable(AllRecognitions.ToList());
DataSet dsAllRecognitions = new DataSet();
dsAllRecognitions.Tables.Add(dtAllRecognitions);
FHSBase.FHS.DataHelper.SendMeExcelFile(dsAllRecognitions, "Recognitions", CurrentUser);
ViewModels.AllRecognitionBigViewModel AllRecognitionBigViewModel = new ViewModels.AllRecognitionBigViewModel();
AllRecognitionBigViewModel.AllRecognitionViewModel = null;
Models.DateRange DateRange = new Models.DateRange();
DateRange.fromDate = DateTime.Today.Date;
DateRange.toDate = DateTime.Today.Date;
AllRecognitionBigViewModel.DateRange = DateRange;
ViewBag.AllRecognitionBigViewModel = AllRecognitionBigViewModel;
List<SelectListItem> empList = new List<SelectListItem>();
string VPath = "Index";
return View(VPath, empList);
}
"AllRecognitions" 视图模型在 ActionResult 中为空,但在视图本身中不为空。如何使用视图中显示的当前值将当前视图模型返回到 ActionResult (SubmitExcel)?
您的表格是空的。所以没有数据被post发送到服务器。
当您提交表单时,它不会将整个页面发送到服务器。 (服务器如何知道如何处理 HTML 以从中获取您想要的值?)它从表单元素发送 key/value 对。而你只有一个表单元素:
<input type="submit" name="BtnSubmitExcel" id="BtnSubmitExcel" value="Export to Excel" />
所以只有那个 key/value 被发送到服务器。
您需要做的第一件事是将您的表单包裹在您想要 post 到服务器的数据周围。所以基本上围绕着你的整个 table.
接下来,您需要发出实际的表单元素。页面上的文本不是可用数据,它只是页面内容。由于模型是 List<ViewModels.AllRecognitionViewModel>
那么您应该能够通过对循环进行简单修改来完成它。所以不是这个:
foreach (Recognition.ViewModels.AllRecognitionViewModel item in ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel)
你会想要这个:
for (var i = 0; i < ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel.Count(); i++)
表单元素可以是 hidden
,因此您不会更改页面中的当前用户体验。 也许是这样的:
@Html.HiddenFor(x => x[i].Date)
或者也许:
@Html.HiddenFor(x => x.AllRecognitionViewModel[i].Date)
实际上我在这里有点猜测,因为我更习惯于为此使用模型而不是 ViewBag。 (您可能想尝试使用它,它可能会让事情变得更简单。)您可能需要进行一些调试,以确定此处服务器端代码中到底发生了什么。
最终,您希望在 客户端 代码中看到的元素与此类似:
<input type="hidden" name="AllRecognitionViewModel.Date[0]" value="..." />
因此,如果上述 @Html.EditorFor
建议不起作用,您始终可以手动进行。在循环中它可能看起来像这样:
<input type="hidden" name="AllRecognitionViewModel.Date[@i]" value="@ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel[i].Date" />
要注意的关键是 name
属性。通过将 key/value 对中的 "arrays" 对发送到服务器,模型绑定器应该能够构建 List<ViewModels.AllRecognitionViewModel>
.
这对你有用吗?这是一种不同的方法。既然您没有在视图中操作任何东西,而只想导出到 Excel,为什么不将结果放在 TempData 而不是 ViewBag 中,然后在 POST 上检索它呢? TempData 对那一趟回程记忆犹新。
因此,在您的初始控制器渲染中,执行:
TempData["AllRecognition"] = ThisIsMyAllRecognitionViewModelData;
然后当他们提交给 excel 时,该数据仍处于临时状态。
public ActionResult SubmitExcel()
{
var MyDataMadeIt = TempData["AllRecognition"];
// do some stuff
}
我有一个在页面上显示 ViewModel 的视图。我想让用户按下一个按钮来创建一个 CSV 文件,然后通过电子邮件将其发送给他们。我有 POSt 工作,但是被发回的 ViewModel 总是空的,即使页面清楚地显示了很多行。
这是相关视图的一部分:
<table style="width:99%" cellpadding="3" class="ContentTable" border="1" align="center">
@using (Html.BeginForm("SubmitExcel", "AllRecognition", new { AllRecognitions = ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel }, FormMethod.Post, new { id = "submitExcel" }))
{
<tr>
<td style="padding:3px;">
<input type="submit" name="BtnSubmitExcel" id="BtnSubmitExcel" value="Export to Excel" />
</td>
</tr>
}
<tr style="background-color:#5D7B9D;color:white;">
<th style="width:4%;padding:3px;font-size:12px;">Date</th>
<th style="width:8%;padding:3px;font-size:12px;">Employee</th>
<th style="width:8%;padding:3px;font-size:12px;">Recognized By</th>
<th style="width:6%;padding:3px;font-size:12px;">5-Star Standard</th>
<th style="width:70%;padding:3px;font-size:12px;">Description</th>
<th style="width:4%;padding:3px;font-size:12px;">Points</th>
</tr>
@{
if (ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel != null)
{
foreach (Recognition.ViewModels.AllRecognitionViewModel item in ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel)
{
@:<tr>
@:<td style="width:4%;padding:3px;font-size:12px;">@item.Date</td>
@:<td style="width:8%;padding:3px;font-size:12px;">@item.Employee</td>
@:<td style="width:8%;padding:3px;font-size:12px;">@item.RecognizedBy</td>
@:<td style="width:6%;padding:3px;font-size:12px;">@item.FiveStarStandard</td>
@:<td style="width:70%;padding:3px;font-size:12px;">@item.Description</td>
@:<td style="width:4%;padding:3px;font-size:12px;">@item.Points</td>
@:</tr>
}
}
}
</table>
这是控制器端接收POST方法:
public ActionResult SubmitExcel(List<ViewModels.AllRecognitionViewModel> AllRecognitions)
{
ViewBag.NoSearch = "block";
ViewBag.SupervisorSearch = "none";
ViewBag.DepartmentSearch = "none";
ViewBag.EmployeeSearch = "none";
DataTable dtAllRecognitions = Base.SQLHelper.ConvertListToDataTable(AllRecognitions.ToList());
DataSet dsAllRecognitions = new DataSet();
dsAllRecognitions.Tables.Add(dtAllRecognitions);
FHSBase.FHS.DataHelper.SendMeExcelFile(dsAllRecognitions, "Recognitions", CurrentUser);
ViewModels.AllRecognitionBigViewModel AllRecognitionBigViewModel = new ViewModels.AllRecognitionBigViewModel();
AllRecognitionBigViewModel.AllRecognitionViewModel = null;
Models.DateRange DateRange = new Models.DateRange();
DateRange.fromDate = DateTime.Today.Date;
DateRange.toDate = DateTime.Today.Date;
AllRecognitionBigViewModel.DateRange = DateRange;
ViewBag.AllRecognitionBigViewModel = AllRecognitionBigViewModel;
List<SelectListItem> empList = new List<SelectListItem>();
string VPath = "Index";
return View(VPath, empList);
}
"AllRecognitions" 视图模型在 ActionResult 中为空,但在视图本身中不为空。如何使用视图中显示的当前值将当前视图模型返回到 ActionResult (SubmitExcel)?
您的表格是空的。所以没有数据被post发送到服务器。
当您提交表单时,它不会将整个页面发送到服务器。 (服务器如何知道如何处理 HTML 以从中获取您想要的值?)它从表单元素发送 key/value 对。而你只有一个表单元素:
<input type="submit" name="BtnSubmitExcel" id="BtnSubmitExcel" value="Export to Excel" />
所以只有那个 key/value 被发送到服务器。
您需要做的第一件事是将您的表单包裹在您想要 post 到服务器的数据周围。所以基本上围绕着你的整个 table.
接下来,您需要发出实际的表单元素。页面上的文本不是可用数据,它只是页面内容。由于模型是 List<ViewModels.AllRecognitionViewModel>
那么您应该能够通过对循环进行简单修改来完成它。所以不是这个:
foreach (Recognition.ViewModels.AllRecognitionViewModel item in ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel)
你会想要这个:
for (var i = 0; i < ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel.Count(); i++)
表单元素可以是 hidden
,因此您不会更改页面中的当前用户体验。 也许是这样的:
@Html.HiddenFor(x => x[i].Date)
或者也许:
@Html.HiddenFor(x => x.AllRecognitionViewModel[i].Date)
实际上我在这里有点猜测,因为我更习惯于为此使用模型而不是 ViewBag。 (您可能想尝试使用它,它可能会让事情变得更简单。)您可能需要进行一些调试,以确定此处服务器端代码中到底发生了什么。
最终,您希望在 客户端 代码中看到的元素与此类似:
<input type="hidden" name="AllRecognitionViewModel.Date[0]" value="..." />
因此,如果上述 @Html.EditorFor
建议不起作用,您始终可以手动进行。在循环中它可能看起来像这样:
<input type="hidden" name="AllRecognitionViewModel.Date[@i]" value="@ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel[i].Date" />
要注意的关键是 name
属性。通过将 key/value 对中的 "arrays" 对发送到服务器,模型绑定器应该能够构建 List<ViewModels.AllRecognitionViewModel>
.
这对你有用吗?这是一种不同的方法。既然您没有在视图中操作任何东西,而只想导出到 Excel,为什么不将结果放在 TempData 而不是 ViewBag 中,然后在 POST 上检索它呢? TempData 对那一趟回程记忆犹新。
因此,在您的初始控制器渲染中,执行:
TempData["AllRecognition"] = ThisIsMyAllRecognitionViewModelData;
然后当他们提交给 excel 时,该数据仍处于临时状态。
public ActionResult SubmitExcel()
{
var MyDataMadeIt = TempData["AllRecognition"];
// do some stuff
}