提前致谢。请原谅我的语法。我尽力解释我的问题在我寻求解决下面的问题时,我开始首先开发POC。
C# MVC No submit pass object between views
我在使用TempData对象时遇到问题,并在我的父弹出窗口和子弹出窗口之间传递我的模型。我的问题是我正在做TempData [“StudentViewModel”] 2次。 第一次插入和第一次阅读是好的,但第二次阅读,即使我确保我在读取之前第二次插入不工作。
我会尽力解释清楚。
我有一个名为Class.cshtml的ASP.NET页面。它将具有所有类的网格。用户将选择一个ClassName列,它将Students.cshtml打开为一个新的弹出窗口,其中包含一个带有StudentName和Address列的网格。用户将选择StudentName,然后打开另一个名为StudentDetails.cshtml的弹出窗口。
我们有一个ClassController.cs,它被所有弹出窗口使用,并且有C#方法。 ClassController.js包含所有javscript代码。
public ActionResult GetStudentsDetails()
{
// this will create students for each class.
//Inside student for each class it will also create Student Details.
// First Insert
TempData["StudentViewModel"] = studentViewModel;
return View("Students", studentViewModel);
}
Students.cshtml是一个现有的弹出窗口,如下所示
<div>
//this is in for loop
string anchorElementId = string.Format("AnchorElementId_{0}", i);
string selectedIndex = i.ToString();
string name = Model.Students[i].Name;
<input class="ButtonLikeHyperLink"
id="myBtnId"
onclick="ShowStudentDetails(@selectedIndex, '@name', '@anchorElementId')"
value="@Model.Students[i].Name"
type="button"/>
//for loop ends here
//First read
<span id="lblHDNStudentViewModel">
@Newtonsoft.Json.JsonConvert.SerializeObject(TempData["StudentViewModel"] as StudentViewModel)
</span>
</div>
一旦用户在Students.cshtml弹出窗口中选择任何StudentName,就会调用以下js方法,该方法将打开一个具有特定学生详细信息的子窗口弹出窗口。
ClassController.js
function ShowStudentDetails(selectedIndex, name, anchorElementId)
{
var inputParam = {};
var hiddenField = document.getElementById("lblHDNStudentViewModel");
if (hiddenField != null)
{
inputParam.StudentVM = JSON.parse(hiddenField.innerText);
inputParam.selectedIndex = selectedIndex;
inputParam.name = name;
inputParam.anchorElementId = anchorElementId;
// __callback is our custom method to call controller action method
var retVal = __callback("OnNameSelected", inputParam);
var postedData = JSON.parse(retVal.return_value);
if (postedData.Success == true)
{
// i need to do like below since Model to my popup is dynamic
multipleMatchPopup = window.open('', '', properties);
multipleMatchPopup.document.write(postedData.PartialViewHtml);
}
}
}
ClassController.cs
public JsonResult OnNameSelected(StudentViewModel StudentVM, int selectedIndex, string name, string anchorElementId)
{
// this will create student name details viewmodel for selected name and modify StudentViewModel object.
// for example
StudentDetailsViewModel vm = StudentVM[selectedIndex].DetailsVM;
//since user made selection update few properties in vm
StudentVM[selectedIndex].DetailsVM = vm;
//Second insert
// make sure to set tempdata before RenderPartialViewToString
TempData["StudentViewModel"] = StudentVM;
string sHtml = this.RenderPartialViewToString("~/Views/_PartialStudentDetailsPopup.cshtml", vm);
return Json(new
{
Success = true,
data = StudentVM,
PartialViewHtml = sHtml,
JsonRequestBehavior.AllowGet
});
}
在StudentDetails.cshtml弹出窗口中,我喜欢这个
<div>
.....
<input class="ButtonLikeHyperLink"
id="@buttonId"
onclick="OnUserSelectStudentDetails()"
value="[Select]"
type="button" />
//Second read
//in fiddler innertext is show as null
<span id="lblHDNStudentDetailsViewModel">
@Newtonsoft.Json.JsonConvert.SerializeObject(TempData["StudentViewModel"] as StudentViewModel)
</span>
</div>
ClassController.js
function OnUserSelectStudentDetails()
{
var inputParam = {};
var hiddenField = document.getElementById("lblHDNStudentDetailsViewModel");
if (hiddenField != null)
{
//hiddenField.innerText is null
inputParam.StudentVM = JSON.parse(hiddenField.innerText);
var retVal = __FAFdoCallback("OnUserSelectLenderMatchingFee", inputParam);
...
}
}
ClassController.cs
public JsonResult OnUserSelectLenderMatchingFee(StudentViewModel StudentVM)
{
//StudentVM is null here
}
更新
解
我对这个问题感到很愚蠢。作为伟大的侦探, Hercule Poirot 说,“伟大的灰色细胞不起作用”,我的也没有工作 在这种情况下。有时我们认为我们监督基础知识的方框离我们这么远。我觉得这件事不能这么简单,所以我在考虑TempData等等,忘记了我的父弹出已经有一个隐藏字段的基本点,我可以从中读取并在我的javascript方法中写入它父窗口和子窗口弹出窗口,并将其传递给控制器操作方法,并返回更新和一致的模型。
采用这种基本解决方案,这就是我所做的
Students.cshtml
<span id="lblHDNStudentViewModel">
@Newtonsoft.Json.JsonConvert.SerializeObject(Model)
</span>
在ClassController.js
中的父窗口javascript方法中读取此内容function ShowStudentDetails(selectedIndex, name, anchorElementId)
{
var inputParam = {};
//read
var hiddenField = document.getElementById("lblHDNStudentViewModel");
}
从ClassController.js
中的子窗口javascript方法中读取此内容function OnUserSelectStudentDetails()
{
var inputParam = {};
// read in child window and access parent window element
var hiddenField = window.opener.document.getElementById("lblHDNStudentViewModel");
}
从父窗口javascript方法写回父窗口元素,如下所示
document.getElementById("lblHdnCDLenderViewModel").innerText = JSON.stringify(postedData.data);
从子窗口javascript方法写回父窗口元素,如下所示
window.opener.document.getElementById("lblHdnCDLenderViewModel").innerText = JSON.stringify(postedData.data);