繁体   English   中英

如何从 ASP.NET Core WebAPI 获取 int 值?

[英]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 通过OnRegionChangedOnRowInsertingOnRowUpdatingOnRowRemoving ,并为每一个寻找两件事:

  1. 它们本质上是异步的,但它们每个都有同步签名。 所以你应该让它们异步,就像我对OnRowUpdating所做的那样。

  2. 它们包含诸如Http.DeleteAsyncInvokeAsync等异步方法的调用,而无需等待它们的结果。 你确定这是故意的吗? 如果没有,等待应该等待的!

您还可以查看 .net 中的异步编程 model 的文档,以加深您对它的理解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM