ASP.NET Core 3.1 - 将子项添加到剃刀局部视图
Posted
技术标签:
【中文标题】ASP.NET Core 3.1 - 将子项添加到剃刀局部视图【英文标题】:ASP.NET Core 3.1 - adding child item to razor partial view 【发布时间】:2021-01-22 17:44:20 【问题描述】:我是新手,我已经为此苦苦挣扎了好几天!
我想要做的只是将一个子项添加到父项,并刷新部分视图。 我的问题是当代码进入 OnGetAddNewChildItem 方法时,PageModel 类上的绑定属性为空(它不是 null,它只是没有数据)所以我无法添加孩子到这个。为了尝试解决这个问题,我尝试将数据传递到方法中,但这是 null。
奇怪的是,在我正在研究的实际解决方案中,我什至无法将它放入 PageModel 类,除非它是 PUT 或 POST - 但如果我能让这个演示工作,我敢肯定我将能够使主要解决方案正常工作。
我的 PageModel 类
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】:从您的代码设计来看,您有以下一些错误:
1.在get方法中使用FromBody
不是一个好方法。如果你想通过get请求向后端发送数据,你需要通过url中的查询字符串发送模型。你应该做的是一种 Post 请求方式。
参考:
https://***.com/a/983458/11398810
2.局部视图结果的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>
索引.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;
结果:
【讨论】:
完美。非常感谢。正是我需要的。以上是关于ASP.NET Core 3.1 - 将子项添加到剃刀局部视图的主要内容,如果未能解决你的问题,请参考以下文章
使用 ADFS 的 JWT Bearer 身份验证将 ASP.NET Framework 迁移到 ASP.NET Core 3.1
将 Asp.Net Core 2.2 App 迁移到 3.1 时的整数序列化 [关闭]
ASP.NET Core 3.1 和 Angular:将 api 调用重定向到登录页面
将 JWT 自动加载到 User.Identity (ASP.NET Core 3.1)