ASP.NET 核心 3.1 - 将 child 项目添加到剃须刀局部视图
ASP.NET Core 3.1 - adding child item to razor partial view
我是新手,我已经为此苦苦挣扎了好几天!
我想做的只是将一个 child 项目添加到 parent,然后刷新局部视图。
我的问题是当代码放入 OnGetAddNewChildItem 方法时,PageModel class 上的绑定 属性 为空(它不是空的,它只是没有中的数据)所以我不能添加 child 到这个。为了尝试解决这个问题,我尝试将数据传递到方法中,但这是空的。
奇怪的是,在我正在处理的实际解决方案中,我什至无法将其放入 PageModel class 除非它是 PUT 或 POST - 但如果我可以让这个演示工作,我相信我能够让主要解决方案工作。
我的页面模型class
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.MyChildPropertiesList.AddRange(
new List<Child> {
new Child() { Id = 1, HeaderId = MyHeader.Id, MyChildProperty = "ChildTest1" },
new Child() { Id = 2, HeaderId = MyHeader.Id, MyChildProperty = "ChildTest2" },
new Child() { Id = 3, HeaderId = MyHeader.Id, MyChildProperty = "ChildTest3" }
});
}
public PartialViewResult OnGetAddNewChildItem([FromBody] Header myHeader)
{
if (myHeader.MyChildPropertiesList == null)
myHeader.MyChildPropertiesList = new List<Child>();
myHeader.MyChildPropertiesList.Add(new Child
{
Id = 4,
HeaderId = myHeader.Id,
MyChildProperty = "ChildTest4"
});
var partialView = "_ListItemPartial";
var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader.MyChildPropertiesList } };
myViewData.Model = myHeader;
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<Child> MyChildPropertiesList { get; set; } = new List<Child>();
}
public class Child
{
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="AddItem()">Add Child Item</a>
</div>
<br />
<div>
<div><b>MyHeaderProperty value:</b> @Model.MyHeader.MyHeaderProperty</div>
<br />
<div class="font-weight-bold">Child Items</div>
<br />
<div id="LineItemsPartial">
<partial name="_ListItemPartial" model="@Model" />
</div>
</div>
<script type="text/javascript">
function AddItem() {
var model = @Json.Serialize(Model.MyHeader);
alert(JSON.stringify(model));
$.ajax({
type: "GET",
url: "?handler=AddNewChildItem",
data: JSON.stringify(model),
dataType: "json",
success: function (result) {
alert("Success");
$('#LineItemsPartial').html(result);
},
failure: function (result) {
alert("Failed");
}
});
}
</script>
我的部分观点
@model IndexModel
<table>
@foreach (var myChildItem in Model.MyHeader.MyChildPropertiesList)
{
<tr>
<td>@myChildItem.HeaderId</td>
<td>@myChildItem.MyChildProperty</td>
</tr>
}
</table>
非常感谢任何帮助。
从你的代码设计来看,你有以下错误:
1.It在get中使用FromBody
不是一个好方法method.If你想通过get请求向后端发送数据,你需要通过查询字符串发送模型您所做的 url.What 应该是 Post 请求方式。
参考:
2.The局部视图结果的ViewData是Header
的类型。但是你的局部视图需要IndexModel
的类型
这是一个工作演示:
Index.cshtml:
@page
@model IndexModel
<div>
<a class="btn btn-sm btn-info text-white" onclick="AddItem()">Add Child Item</a>
</div>
<br />
<div>
<div><b>MyHeaderProperty value:</b> @Model.MyHeader.MyHeaderProperty</div>
<br />
<div class="font-weight-bold">Child Items</div>
<br />
<div id="LineItemsPartial">
<partial name="_ListItemPartial" model="@Model" />
</div>
@Html.AntiForgeryToken() @*add this*@
</div>
<script type="text/javascript">
function AddItem() {
var model = @Json.Serialize(Model.MyHeader);
$.ajax({
type: "Post", //change this...
url: "?handler=AddNewChildItem",
data: JSON.stringify(model),
//add the following contentType and headers..
contentType: "application/json",
headers: {
RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
},
dataType: "html", //midify this..
success: function (result) {
$('#LineItemsPartial').html(result);
},
failure: function (result) {
alert("Failed");
}
});
}
</script>
Index.cshtml.cs:
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 PartialViewResult OnPostAddNewChildItem([FromBody] Header myHeader)
{
if (myHeader.MyChildPropertiesList == null)
myHeader.MyChildPropertiesList = new List<Child>();
myHeader.MyChildPropertiesList.Add(new Child
{
Id = 4,
HeaderId = myHeader.Id,
MyChildProperty = "ChildTest4"
});
//add this line....
var data = new IndexModel(_logger);
data.MyHeader = myHeader;
var partialView = "_ListItemPartial";
var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader.MyChildPropertiesList } };
myViewData.Model = data; //change here..
var partialViewResult = new PartialViewResult()
{
ViewName = partialView,
ViewData = myViewData,
};
return partialViewResult;
}
}
结果:
我是新手,我已经为此苦苦挣扎了好几天!
我想做的只是将一个 child 项目添加到 parent,然后刷新局部视图。 我的问题是当代码放入 OnGetAddNewChildItem 方法时,PageModel class 上的绑定 属性 为空(它不是空的,它只是没有中的数据)所以我不能添加 child 到这个。为了尝试解决这个问题,我尝试将数据传递到方法中,但这是空的。
奇怪的是,在我正在处理的实际解决方案中,我什至无法将其放入 PageModel class 除非它是 PUT 或 POST - 但如果我可以让这个演示工作,我相信我能够让主要解决方案工作。
我的页面模型class
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.MyChildPropertiesList.AddRange(
new List<Child> {
new Child() { Id = 1, HeaderId = MyHeader.Id, MyChildProperty = "ChildTest1" },
new Child() { Id = 2, HeaderId = MyHeader.Id, MyChildProperty = "ChildTest2" },
new Child() { Id = 3, HeaderId = MyHeader.Id, MyChildProperty = "ChildTest3" }
});
}
public PartialViewResult OnGetAddNewChildItem([FromBody] Header myHeader)
{
if (myHeader.MyChildPropertiesList == null)
myHeader.MyChildPropertiesList = new List<Child>();
myHeader.MyChildPropertiesList.Add(new Child
{
Id = 4,
HeaderId = myHeader.Id,
MyChildProperty = "ChildTest4"
});
var partialView = "_ListItemPartial";
var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader.MyChildPropertiesList } };
myViewData.Model = myHeader;
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<Child> MyChildPropertiesList { get; set; } = new List<Child>();
}
public class Child
{
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="AddItem()">Add Child Item</a>
</div>
<br />
<div>
<div><b>MyHeaderProperty value:</b> @Model.MyHeader.MyHeaderProperty</div>
<br />
<div class="font-weight-bold">Child Items</div>
<br />
<div id="LineItemsPartial">
<partial name="_ListItemPartial" model="@Model" />
</div>
</div>
<script type="text/javascript">
function AddItem() {
var model = @Json.Serialize(Model.MyHeader);
alert(JSON.stringify(model));
$.ajax({
type: "GET",
url: "?handler=AddNewChildItem",
data: JSON.stringify(model),
dataType: "json",
success: function (result) {
alert("Success");
$('#LineItemsPartial').html(result);
},
failure: function (result) {
alert("Failed");
}
});
}
</script>
我的部分观点
@model IndexModel
<table>
@foreach (var myChildItem in Model.MyHeader.MyChildPropertiesList)
{
<tr>
<td>@myChildItem.HeaderId</td>
<td>@myChildItem.MyChildProperty</td>
</tr>
}
</table>
非常感谢任何帮助。
从你的代码设计来看,你有以下错误:
1.It在get中使用FromBody
不是一个好方法method.If你想通过get请求向后端发送数据,你需要通过查询字符串发送模型您所做的 url.What 应该是 Post 请求方式。
参考:
2.The局部视图结果的ViewData是Header
的类型。但是你的局部视图需要IndexModel
这是一个工作演示:
Index.cshtml:
@page
@model IndexModel
<div>
<a class="btn btn-sm btn-info text-white" onclick="AddItem()">Add Child Item</a>
</div>
<br />
<div>
<div><b>MyHeaderProperty value:</b> @Model.MyHeader.MyHeaderProperty</div>
<br />
<div class="font-weight-bold">Child Items</div>
<br />
<div id="LineItemsPartial">
<partial name="_ListItemPartial" model="@Model" />
</div>
@Html.AntiForgeryToken() @*add this*@
</div>
<script type="text/javascript">
function AddItem() {
var model = @Json.Serialize(Model.MyHeader);
$.ajax({
type: "Post", //change this...
url: "?handler=AddNewChildItem",
data: JSON.stringify(model),
//add the following contentType and headers..
contentType: "application/json",
headers: {
RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
},
dataType: "html", //midify this..
success: function (result) {
$('#LineItemsPartial').html(result);
},
failure: function (result) {
alert("Failed");
}
});
}
</script>
Index.cshtml.cs:
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 PartialViewResult OnPostAddNewChildItem([FromBody] Header myHeader)
{
if (myHeader.MyChildPropertiesList == null)
myHeader.MyChildPropertiesList = new List<Child>();
myHeader.MyChildPropertiesList.Add(new Child
{
Id = 4,
HeaderId = myHeader.Id,
MyChildProperty = "ChildTest4"
});
//add this line....
var data = new IndexModel(_logger);
data.MyHeader = myHeader;
var partialView = "_ListItemPartial";
var myViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { { partialView, myHeader.MyChildPropertiesList } };
myViewData.Model = data; //change here..
var partialViewResult = new PartialViewResult()
{
ViewName = partialView,
ViewData = myViewData,
};
return partialViewResult;
}
}
结果: