【发布时间】:2021-10-16 07:35:33
【问题描述】:
我最近开始在我的 ASP.Net 核心 Web 应用程序中包含 Blazor 组件。我决定使用模式 [ComponentName].razor 和 [ComponentName].razor.cs 将我的组件拆分为多个文件,用于所有 C# 编码。
令人讨厌的是,我所有的状态更改通知调用都显示为错误。现在,当我构建和运行应用程序时,这些错误消失了,但它们仍然阻塞了我的错误列表窗口。如果我关闭然后打开 Visual Studio 2019,这些将消失,但它们会在几分钟后恢复。发生了什么?如何解决这些错误?
干杯!
InvokeAsync highlighted as an error
编辑:根据要求,这是一些代码。违规行位于 TransactionTableView.razor.cs 中。 'await InvokeAsync(StateHasChanged)' 显示为错误。
TransactionTableView.razor
<table class="table data-table" id="taskstable">
<thead>
<tr>
@if (ShowSelect)
{
<th>
<input type="checkbox" @bind="SelectAllTransactions" @bind:event="oninput" @onclick="() => CheckAllTransactions(!SelectAllTransactions)"/>
Select all
</th>
}
@if (ShowParent)
{
<th>
Parent
</th>
}
<th>
Task
</th>
<th>
Status
</th>
<th>
Due Date
</th>
<th>
Completion Date
</th>
<th>
Amount Due
</th>
<th>
Amount Paid
</th>
<th>
Comments
</th>
</tr>
</thead>
<tbody class="tasks-body">
@if (Transactions != null)
{
@foreach (var transaction in DisplayTransactions)
{
<tr class="@transaction.AlertClassDisplay()">
@if (ShowSelect)
{
<td>
<input @bind="transaction.Select" type="checkbox" @oninput="() => SelectSingleTask(transaction.TransactionId)"/>
</td>
}
@if (ShowParent)
{
<td>
@transaction.TenementKey
</td>
}
<td>
@transaction.Description
</td>
<td class="task-status">
<a asp-action="Details" asp-controller="Alerts" method="get" asp-route-transactionId="@transaction.TransactionId">
@transaction.TransactionStatus
</a>
</td>
<td>
@transaction.DueDateDisplay()
</td>
<td>
@($"{transaction.CompletionDate:dd MMM yyyy}")
</td>
<td>
@transaction.AmountDue
</td>
<td>
@transaction.AmountPaid
</td>
<td>
@transaction.Comments
</td>
</tr>
}
}
</tbody>
</table>
TransactionTableView.razor.cs
partial class TransactionTableView
{
// Injected services
[Inject]
private ApplicationDbContext _context { get; set; }
// Data
public List<int> TenementIds { get; set; }
public List<TransactionViewModel> Transactions { get; set; }
public List<TransactionViewModel> DisplayTransactions { get; set; }
public List<Filter> Filters { get; set; } = new List<Filter>();
private bool ShowParent { get; set; } = true;
private bool ShowSelect { get; set; } = true;
private bool SelectAllTransactions { get; set; } = false;
public async Task Refresh()
{
var transactions = new List<Transaction>(_context.Transactions.Where(x => x.TenementId != null && TenementIds.Contains((int)x.TenementId)));
transactions = transactions.OrderBy(x => x.DueDate).ToList();
var models = new List<TransactionViewModel>();
transactions.ForEach(x =>
{
models.Add(x.GetViewModel(_context));
});
Transactions = models;
await RefreshFilters();
}
public async Task RefreshFilters()
{
var holder = Transactions;
if (Filters != null)
{
foreach (var filter in Filters)
{
if(filter.FilteringProperty.PropertyType == typeof(string))
{
holder = holder.Where(x => ((string)filter.FilteringProperty.GetValue(x)).ToLower().Contains(filter.Values.First().ToString().ToLower())).ToList();
}
if(filter.FilteringProperty.PropertyType == typeof(DateTime) || filter.FilteringProperty.PropertyType == (typeof(DateTime?)))
{
var dFilter = (DateFilter)filter;
if (dFilter.SelectedAfterDate)
{
holder = holder.Where(x => (DateTime)dFilter.FilteringProperty.GetValue(x) > dFilter.TargetDate).ToList();
}
else if (dFilter.SelectBeforeDate)
{
holder = holder.Where(x => (DateTime)dFilter.FilteringProperty.GetValue(x) < dFilter.TargetDate).ToList();
}
else if (dFilter.SelectBetweenDates)
{
holder = holder.Where(x =>
{
var targetDate = (DateTime)dFilter.FilteringProperty.GetValue(x);
return targetDate < dFilter.TargetDate && targetDate > (DateTime)dFilter.FirstTargetDate;
}).ToList();
}
}
if(filter.FilteringProperty.PropertyType == typeof(TransactionStatus))
{
var targetStatuses = filter.Values.Select(x => (TransactionStatus)x);
holder = holder.Where(x => targetStatuses.Contains(x.TransactionStatus)).ToList();
}
}
}
DisplayTransactions = holder;
await RefreshAllTaskSelector();
await InvokeAsync(StateHasChanged);
}
private async Task CheckAllTransactions(bool checkAll)
{
foreach(var displayTask in DisplayTransactions)
{
displayTask.Select = checkAll;
}
await InvokeAsync(StateHasChanged);
}
private async Task SelectSingleTask(int transactionId)
{
var task = DisplayTransactions.SingleOrDefault(x => x.TransactionId == transactionId);
task.Select = !task.Select;
if (DisplayTransactions.Any() && DisplayTransactions.Where(x => !x.Select).Count() == 0)
{
SelectAllTransactions = true;
}
else
{
SelectAllTransactions = false;
}
await InvokeAsync(StateHasChanged);
}
private async Task RefreshAllTaskSelector()
{
if (DisplayTransactions.Any() && DisplayTransactions.Where(x => !x.Select).Count() == 0)
{
SelectAllTransactions = true;
}
else
{
SelectAllTransactions = false;
}
}
private async Task DeleteSelected()
{
if (_context.ChangeTracker.HasChanges())
{
throw new ApplicationException("DB already has changes");
}
var targets = new List<TransactionViewModel>(DisplayTransactions.Where(x => x.Select));
foreach(var target in targets)
{
Transactions.Remove(target);
DisplayTransactions.Remove(target);
var transaction = _context.Transactions.SingleOrDefault(x => x.TransactionId == target.TransactionId);
_context.Transactions.Remove(transaction);
}
await _context.SaveChangesAsync();
await InvokeAsync(StateHasChanged);
}
private async Task CompleteSelected()
{
if (_context.ChangeTracker.HasChanges())
{
throw new ApplicationException("DB already has changes");
}
var targets = new List<TransactionViewModel>(DisplayTransactions.Where(x => x.Select));
foreach (var target in targets)
{
var dbTask = _context.Transactions.SingleOrDefault(x => x.TransactionId == target.TransactionId);
dbTask.CompletionDate = DateTime.Now;
dbTask.TransactionStatus = TransactionStatus.Completed;
target.CompletionDate = dbTask.CompletionDate;
target.TransactionStatus = dbTask.TransactionStatus;
var orig = Transactions.SingleOrDefault(x => x.TransactionId == target.TransactionId);
orig.CompletionDate = dbTask.CompletionDate;
orig.TransactionStatus = dbTask.TransactionStatus;
}
await _context.SaveChangesAsync();
await RefreshFilters();
await InvokeAsync(StateHasChanged);
}
private async Task ArchiveSelected()
{
if (_context.ChangeTracker.HasChanges())
{
throw new ApplicationException("DB already has changes");
}
var targets = new List<TransactionViewModel>(DisplayTransactions.Where(x => x.Select));
foreach (var target in targets)
{
var dbTask = _context.Transactions.SingleOrDefault(x => x.TransactionId == target.TransactionId);
dbTask.CompletionDate = DateTime.Now;
dbTask.TransactionStatus = TransactionStatus.Archived;
target.CompletionDate = dbTask.CompletionDate;
target.TransactionStatus = dbTask.TransactionStatus;
var orig = Transactions.SingleOrDefault(x => x.TransactionId == target.TransactionId);
orig.CompletionDate = dbTask.CompletionDate;
orig.TransactionStatus = dbTask.TransactionStatus;
}
await _context.SaveChangesAsync();
await RefreshFilters();
await InvokeAsync(StateHasChanged);
}
}
【问题讨论】:
-
能否分享您的代码?
-
你的应用是客户端(WASM)还是服务器端?
-
编译器好像找不到
InvokeAsync方法,但是这个方法在ComponentBase类里面。您是否尝试将: ComponentBase添加到类定义中?像这样:public partial class TransactionTableView : ComponentBase现在检查调试器在哪里找到 'InvokeAsync` 方法 -
嗨,克里斯,如果我的回复或 Henk 的回复满足您的需求,请在此处标记答案:stackoverflow.com/help/someone-answers。
标签: c# components blazor