简体   繁体   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. 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.

At Server project (ASP.NET Core Web API with Identity Server 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;
        }
    }
}

At Client project (Blazor WebAssembly)在客户项目 (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;
}

Focus at these lines (1)关注这些线 (1)

string endPoint = "OrganizationUnit/GetGradeOfOrganizationUnit/" + organizationUnit.ParentId;
int orgUnitParentGrade = await Http.GetFromJsonAsync<int>(endPoint);

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

But the source code at (1) is syntax error.但是(1)处的源代码是语法错误。 How to fix it?如何解决?

Can you change:你能改变:

int orgUnitParentGrade = await Http.GetFromJsonAsync<int>(endPoint);

To:至:

var response = await Http.GetAsync(endPoint);
if (response.IsSuccessStatusCode)
            {
                var data = await response.Content.ReadAsStringAsync();
                var orgUnitParentGrade = JsonConvert.DeserializeObject<int>(data);
            }
else....

I think the real problem is that the method void OnRowUpdating(...) is not marked as asynchronous.我认为真正的问题是方法void OnRowUpdating(...)未标记为异步。

That's why your proposed solution worked - by forcing the asynchronous result to look like it's synchronous (that's what .Result does).这就是您提出的解决方案有效的原因 - 通过强制异步结果看起来像它是同步的(这就是.Result所做的)。 But that's not how you should 'fix' such problems in general - this way you mix async and sync code.但这不是您通常应该“解决”此类问题的方式 - 这样您就可以混合异步和同步代码。 This's a very popular anti-pattern (part 4).这是一个非常流行的反模式(第 4 部分)。

Better solution is to make you method OnRowUpdating asynchronous while keeping everything inside it as it was initially:更好的解决方案是让您的方法OnRowUpdating异步,同时将所有内容保持在最初的状态:

async Task OnRowUpdating(...)
{
    ...
    int orgUnitParentGrade = await Http.GetFromJsonAsync<int>(endPoint);
    ...
}

upd .更新 After looking through your code again, I think that you should carefully go through OnRegionChanged , OnRowInserting , OnRowUpdating , OnRowRemoving , and for each one look for two things:再次查看您的代码后,我认为您应该仔细 go 通过OnRegionChangedOnRowInsertingOnRowUpdatingOnRowRemoving ,并为每一个寻找两件事:

  1. They are asynchronous by nature, but each of them has synchronous signature.它们本质上是异步的,但它们每个都有同步签名。 So you should make them async the same way I did for OnRowUpdating .所以你应该让它们异步,就像我对OnRowUpdating所做的那样。

  2. They contain calls of asynchronous methods like Http.DeleteAsync , InvokeAsync and so on without awaiting their results.它们包含诸如Http.DeleteAsyncInvokeAsync等异步方法的调用,而无需等待它们的结果。 Are you sure that's intended?你确定这是故意的吗? If not, await what should be awaited!如果没有,等待应该等待的!

You can also check out documentation of the async programming model in .net to sharpen your understanding of it.您还可以查看 .net 中的异步编程 model 的文档,以加深您对它的理解。

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

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