[英]ASP.Net Core 3.1 Razor Pages and CRUD operation with Dapper
[英]ASP.NET Core 3.1 Razor pages - adding different child objects to header
我是网络应用程序开发的新手,我想知道是否有人可以指出我正确的方向? 我想我知道问题是什么,但我不知道如何解决它。
我拥有的是一个复杂的模型,其中一个标题可以包含一个子项,并且每个子项本身都可以有自己的子项(不同类型)。
我这里显示的演示代码有一个标题和两个列表。 如果我单击按钮将子项添加到第一个列表或第二个列表,我遇到的最初问题是这些项目没有出现。 另一个问题是我似乎无法继续向任一列表添加项目。
为了尝试查看发生了什么,我添加了一个部分来显示 innerHTML 以查看数据是什么 - 这说明如果我点击添加到第一个列表,第一个列表会出现一些数据,但是如果我点击要添加到第二个列表,新数据将从第一个列表中消失,而新项目按预期出现在第二个列表中。
我认为问题在于模型没有更新以反映新项目 - 但我知道我们无论如何都不应该使用 Javascript 来做到这一点。 所以,我想我需要把我所有的局部视图分开,所以我有一个包含很多局部视图的主局部视图,当我的 Ajax 调用成功时,刷新主局部视图。
我的 PageModel 类
namespace ParentChildDemo.Pages
{
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
[BindProperty]
public Header MyHeader { get; set; } = new Header();
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
MyHeader.Id = 1;
MyHeader.MyHeaderProperty = "HeaderTest1";
MyHeader.ChildOfHeader.Add(new ChildOfHeader());
for (int i = 1; i <= 3; i++)
{
var childOfChild = new ChildOfChild()
{
Id = i,
HeaderId = MyHeader.Id,
MyChildProperty = $"FirstChildTest{i}"
};
MyHeader.ChildOfHeader[0].MyFirstChildList.Add(childOfChild);
}
for (int i = 1; i <= 2; i++)
{
var childOfChild = new ChildOfChild()
{
Id = i,
HeaderId = MyHeader.Id,
MyChildProperty = $"SecondChildTest{i}"
};
MyHeader.ChildOfHeader[0].MySecondChildList.Add(childOfChild);
}
}
public PartialViewResult OnPostAddNewFirstListChildItem([FromBody] Header myHeader)
{
if (myHeader.ChildOfHeader[0].MyFirstChildList == null)
myHeader.ChildOfHeader[0].MyFirstChildList = new List<ChildOfChild>();
var childId = myHeader.ChildOfHeader[0].MyFirstChildList.Count + 1;
myHeader.ChildOfHeader[0].MyFirstChildList.Add(new ChildOfChild
{
Id = childId,
HeaderId = myHeader.Id,
MyChildProperty = $"FirstChildTest{childId}"
});
var partialView = "_ListPartialView";
//var partialView = "_FirstListItemPartial";
var data = new IndexModel(_logger);
data.MyHeader = myHeader;
var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader } };
//var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader.ChildOfHeader[0].MyFirstChildList } };
myViewData.Model = data;
var partialViewResult = new PartialViewResult()
{
ViewName = partialView,
ViewData = myViewData,
};
return partialViewResult;
}
public PartialViewResult OnPostAddNewSecondListChildItem([FromBody] Header myHeader)
{
if (myHeader.ChildOfHeader[0].MySecondChildList == null)
myHeader.ChildOfHeader[0].MySecondChildList = new List<ChildOfChild>();
var childId = myHeader.ChildOfHeader[0].MySecondChildList.Count + 1;
myHeader.ChildOfHeader[0].MySecondChildList.Add(new ChildOfChild
{
Id = childId,
HeaderId = myHeader.Id,
MyChildProperty = $"SecondChildTest{childId}"
});
var partialView = "_ListPartialView";
//var partialView = "_SecondListItemPartial";
var data = new IndexModel(_logger);
data.MyHeader = myHeader;
var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader } };
//var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader.ChildOfHeader[0].MySecondChildList } };
myViewData.Model = data;
var partialViewResult = new PartialViewResult()
{
ViewName = partialView,
ViewData = myViewData,
};
return partialViewResult;
}
}
public class Header
{
public int Id { get; set; }
public string MyHeaderProperty { get; set; }
public List<ChildOfHeader> ChildOfHeader { get; set; } = new List<ChildOfHeader>();
}
public class ChildOfHeader
{
public List<ChildOfChild> MyFirstChildList { get; set; } = new List<ChildOfChild>();
public List<ChildOfChild> MySecondChildList { get; set; } = new List<ChildOfChild>();
}
public class ChildOfChild
{
public int Id { get; set; }
public int HeaderId { get; set; }
public string MyChildProperty { get; set; }
}
}
我的索引页面
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
<div>
<a class="btn btn-sm btn-info text-white" onclick="AddListItem(1)">Add Child to First list</a>
<a class="btn btn-sm btn-info text-white" onclick="AddListItem(2)">Add Child to Second list</a>
</div>
<br />
<div>
<div><b>MyHeaderProperty value:</b> @Model.MyHeader.MyHeaderProperty</div>
<br />
<div class="container">
<div class="row">
<div class="col-6 font-weight-bold">First List</div>
<div class="col-6 font-weight-bold">Second List</div>
</div>
<div class="ListPartialView">
<partial name="_ListPartialView" model="@Model" />
</div>
</div>
<br />
<div class="bg-warning" id="HtmlContent"></div>
@Html.AntiForgeryToken()
</div>
<script type="text/javascript">
function AddListItem(listNumber) {
var model = @Json.Serialize(Model.MyHeader);
var handler;
var partialView;
if (listNumber == 1) {
handler = "?handler=AddNewFirstListChildItem";
partialView = "#ListPartialView";//"#FirstListPartial";
}
else {
handler = "?handler=AddNewSecondListChildItem";
partialView = "#ListPartialView";//"#SecondListPartial";
}
$.ajax({
type: "POST",
url: handler,
data: JSON.stringify(model),
dataType: "html",
contentType: "application/json",
headers: {
RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (result) {
document.getElementById("HtmlContent").innerHTML = result.toString();
$(partialView).html(result);
},
failure: function (result) {
alert("Failed");
}
});
}
</script>
我的主要部分视图(_ListPartialView)
@model IndexModel
@for (int i = 0; i < Model.MyHeader.ChildOfHeader.Count; i++)
{
ViewData["ChildIndex"] = i;
<div class="row">
<div id="FirstListPartial" class="col-6">
<partial name="_FirstListItemPartial" model="@Model" view-data="ViewData" />
</div>
<div id="SecondListPartial" class="col-6">
<partial name="_SecondListItemPartial" model="@Model" view-data="ViewData" />
</div>
</div>
}
我的第一个列表部分视图 (_FirstListItemPartial)
@model IndexModel
@{
var indexId = (int)ViewData["ChildIndex"];
}
<table>
@foreach (var myChildItem in Model.MyHeader.ChildOfHeader[indexId].MyFirstChildList)
{
<tr>
<td>@myChildItem.Id</td>
<td>@myChildItem.MyChildProperty</td>
</tr>
}
</table>
我的第二个列表部分视图 (_SecondListItemPartial)
@model IndexModel
@{
var indexId = (int)ViewData["ChildIndex"];
}
<table>
@foreach (var myChildItem in Model.MyHeader.ChildOfHeader[indexId].MySecondChildList)
{
<tr>
<td>@myChildItem.Id</td>
<td>@myChildItem.MyChildProperty</td>
</tr>
}
</table>
任何帮助,将不胜感激。
如果我点击添加到第一个列表,第一个列表会出现一些数据,但是如果我点击添加到第二个列表,新数据会从第一个列表中消失,而新项目按预期出现在第二个列表中。
如果在 AddListItem() 函数或 OnPostAddNewSecondListChildItem() 方法中设置断点,您会发现 myHeader 对象是原始对象,它不包含新项。 我认为这个问题与您使用 JQuery ajax 加载局部视图有关,索引页面不会刷新并且模型不会更新,因此,在使用此脚本时( var model = @Json.Serialize(Model.MyHeader);
) 要获取模型数据,它将始终获取原始值。
为了解决这个问题,你可以尝试使用 session 来存储最新的数据,在添加新项目之前,你可以先获取最新的数据,然后再添加新项目。
更改您的代码如下(更新):
<script type="text/javascript">
function AddListItem(listNumber) {
//var model = @Json.Serialize(Model.MyHeader);
var model;
//get the latest daa
$.ajax({
type: "get",
url: "?handler=GetLatestData",
async: false,
contentType: "application/json",
success: function (data) {
model = data;
}
});
var handler;
var partialView;
if (listNumber == 1) {
handler = "?handler=AddNewFirstListChildItem";
partialView = "#FirstListPartial";//"#ListPartialView";
}
else {
handler = "?handler=AddNewSecondListChildItem";
partialView = "#SecondListPartial";//"#SecondListPartial";
}
$.ajax({
type: "POST",
url: handler,
data: JSON.stringify(model),
dataType: "html",
contentType: "application/json",
headers: {
RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (result) {
//document.getElementById("HtmlContent").innerHTML = result.toString();
$(partialView).html("");
$(partialView).html(result);
},
failure: function (result) {
alert("Failed");
}
});
}
</script>
和 :
public void OnGet()
{
MyHeader.Id = 1;
MyHeader.MyHeaderProperty = "HeaderTest1";
MyHeader.ChildOfHeader.Add(new ChildOfHeader());
for (int i = 1; i <= 3; i++)
{
var childOfChild = new ChildOfChild()
{
Id = i,
HeaderId = MyHeader.Id,
MyChildProperty = $"FirstChildTest{i}"
};
MyHeader.ChildOfHeader[0].MyFirstChildList.Add(childOfChild);
}
for (int i = 1; i <= 2; i++)
{
var childOfChild = new ChildOfChild()
{
Id = i,
HeaderId = MyHeader.Id,
MyChildProperty = $"SecondChildTest{i}"
};
MyHeader.ChildOfHeader[0].MySecondChildList.Add(childOfChild);
}
if (HttpContext.Session.Get<Header>("HeaderData") == null)
{
HttpContext.Session.Set<Header>("HeaderData", MyHeader);
}
}
public PartialViewResult OnPostAddNewFirstListChildItem([FromBody] Header myHeader)
{
if (myHeader.ChildOfHeader[0].MyFirstChildList == null)
myHeader.ChildOfHeader[0].MyFirstChildList = new List<ChildOfChild>();
var childId = myHeader.ChildOfHeader[0].MyFirstChildList.Count + 1;
myHeader.ChildOfHeader[0].MyFirstChildList.Add(new ChildOfChild
{
Id = childId,
HeaderId = myHeader.Id,
MyChildProperty = $"FirstChildTest{childId}"
});
//var partialView = "_ListPartialView";
var partialView = "_FirstListItemPartial";
var data = new IndexModel(_logger);
data.MyHeader = myHeader;
var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader } };
//var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader.ChildOfHeader[0].MyFirstChildList } };
myViewData.Model = data;
var partialViewResult = new PartialViewResult()
{
ViewName = partialView,
ViewData = myViewData,
};
HttpContext.Session.Set<Header>("HeaderData", myHeader);
return partialViewResult;
}
public PartialViewResult OnPostAddNewSecondListChildItem([FromBody] Header myHeader)
{
if (myHeader.ChildOfHeader[0].MySecondChildList == null)
myHeader.ChildOfHeader[0].MySecondChildList = new List<ChildOfChild>();
var childId = myHeader.ChildOfHeader[0].MySecondChildList.Count + 1;
myHeader.ChildOfHeader[0].MySecondChildList.Add(new ChildOfChild
{
Id = childId,
HeaderId = myHeader.Id,
MyChildProperty = $"SecondChildTest{childId}"
});
//var partialView = "_ListPartialView";
var partialView = "_SecondListItemPartial";
var data = new IndexModel(_logger);
data.MyHeader = myHeader;
var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader } };
//var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader.ChildOfHeader[0].MySecondChildList } };
myViewData.Model = data;
var partialViewResult = new PartialViewResult()
{
ViewName = partialView,
ViewData = myViewData,
};
HttpContext.Session.Set<Header>("HeaderData", myHeader);
return partialViewResult;
}
public JsonResult OnGetGetLatestData()
{
var result = new Header();
if (HttpContext.Session.Get<Header>("HeaderData") != null)
{
result = HttpContext.Session.Get<Header>("HeaderData");
};
return new JsonResult(result);
}
屏幕截图(更新):
要在 ASP.NET Core应用程序中使用会话,请参阅ASP.NET Core 中的会话和状态管理
【注意】如果要使用session来存储复杂的对象,必须添加SessionExtensions。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.