[英]ASP.NET Core WebAPI 6 cannot get value from configuration, how to fix?
[英]How to get int value from ASP.NET Core WebAPI?
I am using ASP.NET Core Blazor WebAssembly, .NET 5.0.1, Entity Framework Core 5.0.1, Microsoft SQL Server, DevExpress Blazor WebAssembly 20.2.4.
在服務器項目中(ASP.NET Core Web API 與 Identity Server 4)
using acc.Server.Models;
using acc.Server.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace acc.Server.Controllers
{
[Authorize]
[ApiController]
[Route("[controller]")]
public class OrganizationUnitController : ControllerBase
{
private readonly ApplicationDbContext db;
private readonly ILogger<OrganizationUnitController> _logger;
public OrganizationUnitController(ILogger<OrganizationUnitController> logger, ApplicationDbContext _db)
{
_logger = logger;
db = _db;
}
// https://localhost:5001/OrganizationUnit
[HttpGet]
public IEnumerable<OrganizationUnit> Get()
{
try
{
return db.OrganizationUnits.ToList();
}
catch
{
throw;
}
}
// POST: https://localhost:5001/OrganizationUnit
[HttpPost]
public async Task<ActionResult<OrganizationUnit>> PostItem(OrganizationUnit item)
{
db.OrganizationUnits.Add(item);
await db.SaveChangesAsync();
return CreatedAtAction(nameof(GetItem), new { id = item.Id }, item);
}
// GET: https://localhost:5001/OrganizationUnit/5
[HttpGet("{id}")]
public async Task<ActionResult<OrganizationUnit>> GetItem(int id)
{
var item = await db.OrganizationUnits.FindAsync(id);
if (item == null)
{
return NotFound();
}
return item;
}
// https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client
// https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-5.0&tabs=visual-studio
// DELETE
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteItem(int id)
{
var item = await db.OrganizationUnits.FindAsync(id);
if (item == null)
{
return NotFound();
}
db.OrganizationUnits.Remove(item);
await db.SaveChangesAsync();
return NoContent();
}
[HttpGet("GetGradeOfOrganizationUnit/{orgUnitId}")]
public async Task<int> GetGradeOfOrganizationUnit(int orgUnitId)
{
var item = await db.OrganizationUnits.FindAsync(orgUnitId);
int orgUnitGrade = 1;
if (item.Grade != null)
{
orgUnitGrade = (int)item.Grade;
}
return orgUnitGrade;
}
}
}
在客戶項目 (Blazor WebAssembly)
@page "/OrganizationUnitPage"
@inject HttpClient Http
<h3>Cơ cấu tổ chức</h3>
<DxDataGrid Data="@OrganizationUnits"
ShowPager="true"
RowRemoving="@((dataItem) => OnRowRemoving(dataItem))"
RowInserting="@((newValues) => OnRowInserting(newValues))"
RowUpdating="@((updatingDataItem, newValues) => OnRowUpdating(updatingDataItem, newValues))"
PagerPageSizeSelectorVisible="true"
PagerAllowedPageSizes=@(new int[] {10,30,50})
HorizontalScrollBarMode="ScrollBarMode.Visible"
T="OrganizationUnit"
ColumnResizeMode="@DataGridColumnResizeMode.Component"
ShowFilterRow="true"
CssClass="mw-1100"
EditMode="DataGridEditMode.PopupEditForm">
<HeaderTemplate>
<DxToolbar>
<DxDataGridColumnChooserToolbarItem Alignment="ToolbarItemAlignment.Right" Text="Chọn cột" Tooltip="Chọn cột" />
</DxToolbar>
</HeaderTemplate>
<Columns>
<DxDataGridCommandColumn Width="150px"></DxDataGridCommandColumn>
<DxDataGridColumn Field="@nameof(OrganizationUnit.OrganizationUnitCode)" Caption="Mã đơn vị"></DxDataGridColumn>
<DxDataGridColumn Field="@nameof(OrganizationUnit.OrganizationUnitName)" Caption="Tên đơn vị"></DxDataGridColumn>
<DxDataGridColumn Field="@nameof(OrganizationUnit.Address)" Caption="Địa chỉ"></DxDataGridColumn>
<DxDataGridComboBoxColumn T="ComboBoxItem"
Field="@nameof(OrganizationUnit.Grade)"
Caption="Cấp tổ chức"
Data="@ListOfAccountTypes"
ValueFieldName="@nameof(ComboBoxItem.ComboBoxItemValue)"
TextFieldName="@nameof(ComboBoxItem.ComboBoxItemLabel)"
Width="200px">
<DisplayTemplate>
@{
var foo = (context as OrganizationUnit).Grade;
int value = 0;
if (foo != null)
{
value = foo.Value;
}
string str = "";
switch (value)
{
case 1:
str = "Tổng công ty/Công ty";
break;
case 2:
str = "Phòng ban";
break;
default:
str = "";
break;
}
<div>@str</div>
}
</DisplayTemplate>
</DxDataGridComboBoxColumn>
<DxDataGridCheckBoxColumn Field="@nameof(OrganizationUnit.ActiveStatus)"
Caption="Theo dõi"
FilterTextChecked="Theo dõi"
FilterTextUnchecked="Ngừng theo dõi"
FilterTextIndeterminate="Không xác định"
ValueChecked="@ActiveStatus.Active"
ValueUnchecked="@ActiveStatus.NotActive"></DxDataGridCheckBoxColumn>
<DxDataGridColumn Field="@nameof(OrganizationUnit.Id)" Caption="Id" Visible="false"></DxDataGridColumn>
</Columns>
<TotalSummary>
<DxDataGridSummaryItem ShowInColumn=@nameof(OrganizationUnit.OrganizationUnitName) SummaryType=SummaryItemType.Count DisplayFormat="Số dòng: {0}" />
</TotalSummary>
</DxDataGrid>
@code{
IEnumerable<OrganizationUnit> OrganizationUnits;
IEnumerable<ComboBoxItem> ListOfAccountTypes;
public enum ActiveStatus
{
NotActive,
Active
}
// Khởi tạo
protected override async Task OnInitializedAsync()
{
OrganizationUnits = await Http.GetFromJsonAsync<OrganizationUnit[]>("OrganizationUnit");
ListOfAccountTypes = new List<ComboBoxItem>()
{
new ComboBoxItem(0,"Dư Nợ"),
new ComboBoxItem(1,"Dư Có"),
new ComboBoxItem(2,"Lưỡng tính")
};
}
public void OnRegionChanged()
{
InvokeAsync(StateHasChanged);
}
// Xóa
void OnRowRemoving(OrganizationUnit organizationUnit)
{
Http.DeleteAsync("OrganizationUnit/" + organizationUnit.Id);
InvokeAsync(StateHasChanged);
}
// Cập nhật
void OnRowUpdating(OrganizationUnit organizationUnit, Dictionary<string, object> newValue)
{
foreach (var field in newValue.Keys)
{
switch (field)
{
case "OrganizationUnitCode": // Mã đơn vị
organizationUnit.OrganizationUnitCode = (string)newValue[field];
break;
case "OrganizationUnitName": // Tên đơn vị
organizationUnit.OrganizationUnitName = (string)newValue[field];
break;
case "ParentId": // Thuộc đơn vị
organizationUnit.ParentId = (int)newValue[field];
break;
case "Grade": // Cấp tổ chức
organizationUnit.Grade = (int)newValue[field];
break;
case "CostAccount": // Tài khoản chi phí lương
organizationUnit.CostAccount = (string)newValue[field];
break;
}
}
organizationUnit.BranchId = 1;
organizationUnit.IsSystem = false;
if(organizationUnit.ParentId != null)
{
}
if(organizationUnit.ParentId == null)
{
}
// Lấy grade của parent
string endPoint = "OrganizationUnit/GetGradeOfOrganizationUnit/" + organizationUnit.ParentId;
int orgUnitParentGrade = await Http.GetFromJsonAsync<int>(endPoint);
//int parentGrade =
// Sau đó lấy grade của parent cộng thêm 1 để ra grade của Đơn vị hiện tại.
organizationUnit.Grade = 3;
// Lưu vào database.
Http.PutAsJsonAsync("OrganizationUnit", organizationUnit);
InvokeAsync(StateHasChanged);
}
// Thêm mới
void OnRowInserting(Dictionary<string, object> newValue)
{
var organizationUnit = new OrganizationUnit();
foreach (var field in newValue.Keys)
{
switch (field)
{
case "OrganizationUnitCode": // Mã đơn vị
organizationUnit.OrganizationUnitCode = (string)newValue[field];
break;
case "OrganizationUnitName": // Tên đơn vị
organizationUnit.OrganizationUnitName = (string)newValue[field];
break;
case "ParentId": // Thuộc đơn vị
organizationUnit.ParentId = (int)newValue[field];
break;
case "Grade": // Cấp tổ chức
organizationUnit.Grade = (int)newValue[field];
break;
case "CostAccount": // Tài khoản chi phí lương
organizationUnit.CostAccount = (string)newValue[field];
break;
}
}
organizationUnit.BranchId = 1;
organizationUnit.IsSystem = false;
if (organizationUnit.ParentId != null)
{
}
if (organizationUnit.ParentId == null)
{
}
// Lấy grade của parent
// Sau đó lấy grade của parent cộng thêm 1 để ra grade của Đơn vị hiện tại.
organizationUnit.Grade = 3;
// Lưu vào database.
Http.PostAsJsonAsync("OrganizationUnit", organizationUnit);
// Tạo ra sự thay đổi ở phía client mà không lấy lại dữ liệu từ phía database.
// OrganizationUnits = (new OrganizationUnit[] { newItem }).Concat(OrganizationUnits);
// Gọi lại dữ liệu từ database.
InvokeAsync(StateHasChanged);
}
[Parameter] public string Action { get; set; }
ElementReference input;
}
關注這些線 (1)
string endPoint = "OrganizationUnit/GetGradeOfOrganizationUnit/" + organizationUnit.ParentId;
int orgUnitParentGrade = await Http.GetFromJsonAsync<int>(endPoint);
但是(1)處的源代碼是語法錯誤。 如何解決?
你能改變:
int orgUnitParentGrade = await Http.GetFromJsonAsync<int>(endPoint);
至:
var response = await Http.GetAsync(endPoint);
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
var orgUnitParentGrade = JsonConvert.DeserializeObject<int>(data);
}
else....
我認為真正的問題是方法void OnRowUpdating(...)
未標記為異步。
這就是您提出的解決方案有效的原因 - 通過強制異步結果看起來像它是同步的(這就是.Result
所做的)。 但這不是您通常應該“解決”此類問題的方式 - 這樣您就可以混合異步和同步代碼。 這是一個非常流行的反模式(第 4 部分)。
更好的解決方案是讓您的方法OnRowUpdating
異步,同時將所有內容保持在最初的狀態:
async Task OnRowUpdating(...)
{
...
int orgUnitParentGrade = await Http.GetFromJsonAsync<int>(endPoint);
...
}
更新。 再次查看您的代碼后,我認為您應該仔細 go 通過OnRegionChanged
, OnRowInserting
, OnRowUpdating
, OnRowRemoving
,並為每一個尋找兩件事:
它們本質上是異步的,但它們每個都有同步簽名。 所以你應該讓它們異步,就像我對OnRowUpdating
所做的那樣。
它們包含諸如Http.DeleteAsync
、 InvokeAsync
等異步方法的調用,而無需等待它們的結果。 你確定這是故意的嗎? 如果沒有,等待應該等待的!
您還可以查看 .net 中的異步編程 model 的文檔,以加深您對它的理解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.