【发布时间】:2020-04-07 02:59:19
【问题描述】:
我目前正在努力获取数据以绑定到发布事件。
我正在使用 EF 核心将数据加载到用于加载和显示数据列表的对象。
<div class="container">
<form method="post">
@if (Model.HeadersHasData)
{
// unnessary codes
@foreach (var item in Model.DisplayDataHeaders)
{
<div class="container mb-2">
<div class="row border-dark border-top">
<div class="col-sm-1">@Html.DisplayFor(c => item.ServiceAbbr)</div>
<div class="col-sm-4">@Html.DisplayFor(c => item.ServiceName)</div>
<div class="col-sm-3">@Html.DisplayFor(c => item.Qty) Hours/IPs/Locations</div>
<div class="col-sm-2">@Html.DisplayFor(c => item.Description) Duration</div>
</div>
@if (Model.DetailsHasData)
{
@foreach (var details in Model.DisplayDataDetails)
{
@if (details.ServiceId == item.ServicesId)
{
<div class="row">
<input type="hidden"
name="DisplayDataDetails.Index"
value="@details.TaskAssignedId" />
<input type="hidden"
name="DisplayDataDetails[@details.TaskAssignedId].TaskAssignedId"
value="@details.TaskAssignedId" />
<div class="col-sm-1">
<input type="checkbox"
name="DisplayDataDetails[@details.TaskAssignedId].TaskComplete"
value="@details.TaskComplete"
checked=@details.TaskComplete
disabled="@details.AccessGranted" />
</div>
<div class="col-sm-2">@details.TaskName</div>
<div class="col-sm-1">@details.TaskStartDate.ToShortDateString()</div>
<div class="col-sm-1">@details.TaskEndDate.ToShortDateString()</div>
<div class="col-sm-2">@details.TechLead</div>
<div class="col-sm-2">@details.Tech2</div>
<div class="col-sm">@details.Tech3</div>
</div>
}
}
}
</div>
}
}
<button type="submit">Test</button>
</form>
</div>
这会正确显示数据和所有内容。
我现在正在处理用户更改当前使用的复选框时的交互(最终将尝试计算复选框的更改事件)。
我已经应用了 [bindProperty],但是每次通过 DisplayDataDetails 对象进行调试时,我都会得到一个计数为 13 的对象,这是预期的正确行数,但所有行都是空的。
我对自己错过的内容感到非常困惑,因为我在 https://www.learnrazorpages.com/razor-pages/forms/checkboxes 上阅读的所有内容 和 https://www.learnrazorpages.com/razor-pages/model-binding
表明这应该是一个非常直接的操作。
[BindProperty]
public List<Detail> DisplayDataDetails { get; set; }
public async Task OnPostAsync(int? saleId)
{
var test = DisplayDataDetails;
//await LoadDataAsync(saleId);
var pause= "pause";
}
任何助手或建议将不胜感激。
更新 1
只是想添加和更新,创建了一个单独的测试项目,并且能够通过 https://www.learnrazorpages.com/razor-pages/model-binding 中的绑定复杂集合示例我修改了视图以匹配我的用例,即使使用复选框也能够取回数据使用数据绑定回发的值。
这行得通 .cs
namespace RazorPages
{
public class ModeContactTestModel : PageModel
{
[BindProperty]
public List<Contact> Contacts { get; set; } = new List<Contact>();
public string stubFirstName { get; private set; }
public string stubLastName { get; private set; }
public void OnGet()
{
LoadTestData();
}
private void LoadTestData()
{
//Contacts =
stubFirstName = "john";
stubLastName = "Doe";
for (var i = 0; i < 5; i++)
{
Contacts.Add(new Contact
{
ContactId = i,
FirstName = stubFirstName,
LastName = stubLastName,
Email = stubFirstName + "." + stubLastName + i + "Test@email.com",
Enabled = (i % 2 == 0) ? true : false
});
}
}
public void OnPost()
{
// process the contacts
}
}
public class Contact
{
public int ContactId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public bool Enabled { get; set; }
}
}
.cshtml
@page
@model RazorPages.ModeContactTestModel
@{
ViewData["Title"] = "ModelContactTest";
}
<h1>ModelContactTest</h1>
<form method="post">
<table class="table">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Enabled</th>
</tr>
@foreach (var contact in Model.Contacts)
{
<tr>
<td>
<input type="hidden" name="Contacts.Index" value="@contact.ContactId" />
<input type="hidden" name="Contacts[@contact.ContactId].ContactId" value="@contact.ContactId" />
@*@contact.ContactId*@
</td>
<td><input name="Contacts[@contact.ContactId].FirstName" value="@contact.FirstName" /></td>
<td><input name="Contacts[@contact.ContactId].LastName" value="@contact.LastName" /></td>
<td><input name="Contacts[@contact.ContactId].Email" value="@contact.Email" /></td>
<td>
<input type="checkbox"
name="Contacts[@contact.ContactId].Enabled"
value="true"
checked="@contact.Enabled"/></td>
</tr>
}
</table>
<button>Update</button>
</form>
我创建了一个新的演示 razorPage 来开始重写我的页面我从苹果开始应用到我的工作项目中......数据绑定似乎仍然不起作用
这没有任何作用,因为我没有看到任何不同之处。
.cs
namespace Project.Web.Razor
{
public class ################: PageModel
{
[BindProperty]
public List<Detail> Details { get; set; }// = new List<Detail>(); //
public void OnGet()
{
LoadData();
}
private void LoadData()
{
Details = new List<Detail>();
for (var i = 0; i < 5; i++)
{
Details.Add(new Detail
{
AssignedId = i,
Name = "Dev Testing Task " + i,
Complete = (i % 2 == 0) ? true : false,
StartDate = Convert.ToDateTime("01/01/2019"),
EndDate = Convert.ToDateTime("01/01/2019"),
Lead = "John Doe",
//SaleId = i+1,
//ServiceId = i + 2,
AccessGranted = (i % 2 == 0) ? true : false,
});
}
}
public void OnPost()
{
// process the TaskDetails
}
}
public class Detail
{
public int AssignedId { get; internal set; }
public string Name { get; internal set; }
public bool Complete { get; internal set; }
public DateTime StartDate { get; internal set; }
public DateTime EndDate { get; internal set; }
public string Lead { get; internal set; }
public bool AccessGranted { get; internal set; }
}
}
.cshtml
@page
@model ##########################
@{
ViewData["Title"] = "#####################";
}
<h1>EngagementingDetails</h1>
<form method="post">
<table class="table">
@foreach (var Detail in Model.Details)
{
<tr class="row">
<td>
<input type="hidden" name="Details.Index" value="@Detail.AssignedId" />
<input type="hidden" name="Details[@Detail.AssignedId].AssignedId" value="@Detail.AssignedId" />
</td>
<td class="col">
<input type="checkbox" name="Details[@Detail.AssignedId].Complete" value="true" checked="@Detail.Complete" disabled="@Detail.AccessGranted" />
</td>
<td class="col">
<input type="hidden" name="Details[@Detail.AssignedId].Name" value="@Detail.Name" />
@Detail.Name
</td>
<td class="col">
<input type="hidden"
name="Details[@Detail.AssignedId].StartDate"
value="@Detail.StartDate" />
@Detail.StartDate.ToShortDateString()
</td>
<td class="col">
<input type="hidden"
name="Details[@Detail.AssignedId].EndDate"
value="@Detail.EndDate" />
@Detail.EndDate.ToShortDateString()
</td>
<td class="col">
<input type="hidden"
name="Details[@Detail.AssignedId].TechLead"
value="@Detail.TechLead" />
@Detail.TechLead
</td>
</tr>
}
</table>
<button>Update</button>
</form>
这真的让我很困惑,为什么我可以让它在一个项目中工作但不能在单击更新和调试 OnPost 事件时得到它返回一个计数为 5 的列表,但每个项目在我的工作项目中为空测试合同项目它返回列表计数 5,每个对象中的数据都符合预期。不知道我在两者之间做了什么不同。
更新 2
关于最后一条评论,我为测试做了以下更改
.CSHTML
<form method="post">
<table class="table">
<tr class="row">
<th></th>
<th class="col">Complete</th>
<th class="col">Name</th>
@*<th class="col">StartDate</th>
<th class="col">EndDate</th>
<th class="col">Lead</th>*@
</tr>
@foreach (var detail in Model.Details)
{
<tr class="form-group row">
<td >
<input type="hidden"
name="Details.Index"
value="@detail.AssignedId" />
<input type="hidden"
name="Details[@detail.AssignedId].AssignedId"
value="@detail.AssignedId" />
</td>
<td class="col">
<input class="form-check-input"
type="checkbox"
name="Details[@detail.AssignedId].Complete"
value="true"
checked="@detail.Complete"
/>
</td>
<td class="col">
<input class="form-control form-control-sm"
name="Details[@detail.AssignedId].Name"
value="@detail.Name" readonly />
</td>
</tr>
}
</table>
<button>Update</button>
</form>
.cs
[BindProperty]
public List<Detail> Details { get; set; } = new List<Detail>(); //
public void OnGet()
{
LoadData();
}
private void LoadData()
{
//Details = new List<Detail>();
for (var i = 0; i < 5; i++)
{
Details.Add(new Detail
{
AssignedId = i,
Name = "Dev Testing Task " + i,
Complete = (i % 2 == 0) ? true : false,
//StartDate = Convert.ToDateTime("01/01/2019").AddDays(i + 1).AddMonths((i)+1),
//EndDate = Convert.ToDateTime("01/01/2019").AddDays((i + 1) + 15).AddMonths((i) + 1),
//Lead = "John Doe",
//SaleId = i+1,
//ServiceId = i + 2,
//AccessGranted = (i % 2 == 0) ? false : true,
});
}
}
public void OnPost()
{
// process the TaskDetails
if(Details is null)
{
LoadData();
}else if( Details[0] == null)
{
Details = new List<Detail>();
LoadData();
}
else
{
Details = new List<Detail>();
LoadData();
}
}
}
public class Detail
{
public int AssignedId { get; internal set; }
public string Name { get; internal set; }
public bool Complete { get; internal set; }
//public DateTime StartDate { get; internal set; }
//public DateTime EndDate { get; internal set; }
//public string Lead { get; internal set; }
//public bool AccessGranted { get; internal set; }
}
在调试时,我仍然返回 onPost 列表详细信息,计数为 5,但其中的每个项目都是空的。 IE。 Details[0] = null、Details1 = null 等。
刚刚跑了提琴手,它似乎正在发送对象
现在我想知道绑定属性是否无法获取发布事件的数据。
【问题讨论】:
-
首先简化您返回的数据。 . .如果您只有一个 Id、一个名称和完整的字段,它会返回值吗?
-
@PaulGibson 我将反对简化为三个字段 Id、Complete 和 Name 甚至删除了 accessGranted,即如果不是登录用户则禁用复选框。我仍然得到一个 ListDetails 返回,计数为 5,这表明它是绑定对象,但每个项目都返回 null Details = count = 5 details[0] = null ,details[1] = null 等等。不确定这在我的测试项目中有效,而不是在这个项目中
标签: c# entity-framework data-binding .net-core razor-pages