【问题标题】:Asp.net Core/ODATA Controller not receiving the id when sent from PostmanAsp.net Core/ODATA 控制器在从 Postman 发送时未接收到 id
【发布时间】:2020-05-10 06:46:01
【问题描述】:

我正在探索 OData。

我一直关注Referbruv的Working with OData - Integrating an Existing ASP.NET Core 3.x API

我的 EdmModel 跟随他的,如下:

    internal static IEdmModel GetEdmModel() {
        // create OData builder instance
        var builder = new ODataConventionModelBuilder();

        // CLIENTS
        // map the entities set which are the types returned from the endpoint onto the OData pipeline
        // the string parameter is the name of the controller 
        // which supplies the data of type Client entity model in this case
        builder.EntitySet<ClientIndexDto>("ODataClient").EntityType.HasKey(x => x.id);
        builder.EntitySet<ClientDetailsDto>("ODataClientDetails").EntityType.HasKey(x => x.id);


        // configure a function onto the builder, AllClients 
        // which is same as the name provided in the ODataRoute
        builder.Function("AllClients")
            .ReturnsCollectionFromEntitySet<ClientIndexDto>("ODataClient");

        builder.Function("ClientById")
            .ReturnsCollectionFromEntitySet<ClientDetailsDto>("ODataClientDetails")
            .Parameter<int>("id");


        return builder.GetEdmModel();
    }

部分:

builder.Function("ClientById")
            .ReturnsCollectionFromEntitySet<ClientDetailsDto>("ODataClientDetails")
            .Parameter<int>("id");

处理通过 Id 获取客户。

为了完整起见,我在我的 StartUp.cs 文件中为 OData 提供了以下内容:

        app.UseEndpoints(endpoints => { 
            endpoints.MapControllers();
            endpoints.Select().Filter().OrderBy().Expand().Count().MaxTop(10);
            endpoints.MapODataRoute("odata", "odata", GetEdmModel());
        });

返回的$元数据如下:

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
    <edmx:DataServices>
        <Schema Namespace="JobsLedger.MODELS.API.App.Client" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityType Name="ClientIndexDto">
                <Key>
                    <PropertyRef Name="id" />
                </Key>
                <Property Name="id" Type="Edm.Int32" Nullable="false" />
                <Property Name="ClientNo" Type="Edm.String" />
                <Property Name="Active" Type="Edm.Boolean" Nullable="false" />
                <Property Name="ClientFirstName" Type="Edm.String" />
                <Property Name="ClientLastName" Type="Edm.String" />
                <Property Name="Company" Type="Edm.Boolean" Nullable="false" />
                <Property Name="CompanyName" Type="Edm.String" />
                <Property Name="MobilePhone" Type="Edm.String" />
                <Property Name="IsWarrantyCompany" Type="Edm.Boolean" Nullable="false" />
                <Property Name="JobsCount" Type="Edm.String" />
            </EntityType>
            <EntityType Name="ClientDetailsDto">
                <Key>
                    <PropertyRef Name="id" />
                </Key>
                <Property Name="id" Type="Edm.Int32" Nullable="false" />
                <Property Name="ClientNo" Type="Edm.String" />
                <Property Name="Company" Type="Edm.Boolean" Nullable="false" />
                <Property Name="IsWarrantyCompany" Type="Edm.Boolean" Nullable="false" />
                <Property Name="CompanyName" Type="Edm.String" />
                <Property Name="ClientFirstName" Type="Edm.String" />
                <Property Name="ClientLastName" Type="Edm.String" />
                <Property Name="MobilePhone" Type="Edm.String" />
                <Property Name="DeActivated" Type="Edm.String" />
                <Property Name="CreatedOn" Type="Edm.String" />
                <Property Name="CreatedBy" Type="Edm.String" />
                <Property Name="ModifiedOn" Type="Edm.String" />
                <Property Name="ModifiedBy" Type="Edm.String" />
                <Property Name="SuburbId" Type="Edm.Int32" Nullable="false" />
                <NavigationProperty Name="Address" Type="JobsLedger.MODELS.Common.Address.AddressDto" />
                <NavigationProperty Name="ClientJobs" Type="Collection(JobsLedger.MODELS.API.App.Job.ClientJobDto)" />
                <NavigationProperty Name="ClientNotes" Type="Collection(JobsLedger.MODELS.Common.Notes.ClientNoteDto)" />
            </EntityType>
        </Schema>
        <Schema Namespace="JobsLedger.MODELS.Common.Address" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityType Name="AddressDto">
                <Key>
                    <PropertyRef Name="Address1" />
                </Key>
                <Property Name="Address1" Type="Edm.String" Nullable="false" />
                <Property Name="Address2" Type="Edm.String" />
                <Property Name="SuburbId" Type="Edm.Int32" Nullable="false" />
                <Property Name="SuburbName" Type="Edm.String" />
                <Property Name="StateShortName" Type="Edm.String" />
                <Property Name="Postcode" Type="Edm.String" />
            </EntityType>
        </Schema>
        <Schema Namespace="JobsLedger.MODELS.API.App.Job" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityType Name="ClientJobDto">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false" />
                <Property Name="JobNo" Type="Edm.String" />
                <Property Name="AgentJobNo" Type="Edm.String" />
                <Property Name="Type" Type="Edm.String" />
                <Property Name="Status" Type="Edm.String" />
                <Property Name="WarrantyCompany" Type="Edm.String" />
                <Property Name="NumberOfVisits" Type="Edm.String" />
                <Property Name="CreatedOn" Type="Edm.String" />
                <Property Name="CreatedBy" Type="Edm.String" />
                <Property Name="ModifiedOn" Type="Edm.String" />
                <Property Name="ModifiedBy" Type="Edm.String" />
                <NavigationProperty Name="JobNotes" Type="Collection(JobsLedger.MODELS.Common.Notes.JobNoteDto)" />
                <NavigationProperty Name="JobVisits" Type="Collection(JobsLedger.MODELS.API.App.Job.JobVisitDto)" />
            </EntityType>
            <EntityType Name="JobVisitDto">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false" />
                <Property Name="DateCreated" Type="Edm.String" />
                <Property Name="VisitDate" Type="Edm.String" />
                <Property Name="StartTime" Type="Edm.String" />
                <Property Name="EndTime" Type="Edm.String" />
            </EntityType>
        </Schema>
        <Schema Namespace="JobsLedger.MODELS.Common.Notes" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityType Name="JobNoteDto">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false" />
                <Property Name="JobId" Type="Edm.Int32" Nullable="false" />
                <Property Name="Details" Type="Edm.String" />
                <Property Name="NoteType" Type="Edm.String" />
                <Property Name="CreatedOnDate" Type="Edm.String" />
                <Property Name="CreatedOnTime" Type="Edm.String" />
                <Property Name="CreatedBy" Type="Edm.String" />
                <Property Name="ModifiedOnDate" Type="Edm.String" />
                <Property Name="ModifiedOnTime" Type="Edm.String" />
                <Property Name="ModifiedBy" Type="Edm.String" />
            </EntityType>
            <EntityType Name="ClientNoteDto">
                <Key>
                    <PropertyRef Name="id" />
                </Key>
                <Property Name="id" Type="Edm.Int32" Nullable="false" />
                <Property Name="Details" Type="Edm.String" />
                <Property Name="NoteType" Type="Edm.String" />
                <Property Name="CreatedOnDate" Type="Edm.String" />
                <Property Name="CreatedOnTime" Type="Edm.String" />
                <Property Name="CreatedBy" Type="Edm.String" />
                <Property Name="ModifiedOnDate" Type="Edm.String" />
                <Property Name="ModifiedOnTime" Type="Edm.String" />
                <Property Name="ModifiedBy" Type="Edm.String" />
            </EntityType>
        </Schema>
        <Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <Function Name="AllClients">
                <ReturnType Type="Collection(JobsLedger.MODELS.API.App.Client.ClientIndexDto)" />
            </Function>
            <Function Name="ClientById">
                <Parameter Name="id" Type="Edm.Int32" Nullable="false" />
                <ReturnType Type="Collection(JobsLedger.MODELS.API.App.Client.ClientDetailsDto)" />
            </Function>
            <EntityContainer Name="Container">
                <EntitySet Name="ODataClient" EntityType="JobsLedger.MODELS.API.App.Client.ClientIndexDto" />
                <EntitySet Name="ODataClientDetails" EntityType="JobsLedger.MODELS.API.App.Client.ClientDetailsDto" />
                <FunctionImport Name="AllClients" Function="Default.AllClients" EntitySet="ODataClient" IncludeInServiceDocument="true" />
                <FunctionImport Name="ClientById" Function="Default.ClientById" EntitySet="ODataClientDetails" IncludeInServiceDocument="true" />
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

我的控制器如下:

using JobsLedger.API.Controllers.API.App.Interfaces;
using JobsLedger.API.ControllerServices.API.App.ClientService.Interfaces;
using JobsLedger.DATA;
using JobsLedger.DATA.Repositories.Interfaces;
using JobsLedger.MODELS.API.App.Client;

using Microsoft.AspNet.OData;
using Microsoft.AspNet.OData.Routing;
using Microsoft.AspNetCore.Mvc;

using System;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Authorization;

namespace JobsLedger.API.Controllers.API.App {

    [Route("api/[controller]")]
    [ApiController]
    [Authorize(Roles = "TenantAdmin,Admin,Employee")]
    public class ODataClientController : ODataController, IClientController {
        private readonly IClientServices _clientServices;

        public ODataClientController( IClientServices clientServices) {
            _clientServices = clientServices;
        }

        [HttpGet]
        [EnableQuery()]
        [ODataRoute("AllClients()")]
        public IActionResult Get() 
        {
            return Ok(_clientServices.GetAllClientsAsDto());
        }

        [HttpGet]
        [EnableQuery]
        [ODataRoute("ClientById(id={id})")]
        public IActionResult Get(int id) {
            return Ok(_clientServices.GetClient(id));
        }

我想获取一个 ID 为“5”的客户端,所以我在 Postman 中使用了以下 get 命令:

https://localhost:44301/odata/ClientById(id=5)?

正如教程所示 - “id=5”周围有括号

它到达端点,但 id 设置为“0”。

鉴于我的 EdmModel、#MetaData 和单个 Id 的控制器操作,为什么当我发送带有 (Id=5) 的 GET 命令时,我得到 Id=0?我需要做什么来解决这个问题?

【问题讨论】:

    标签: c# asp.net-core odata


    【解决方案1】:

    在 cmets 文章中,Referbruv 还提到了 .net core 3.1 中的路由问题。所以,你可以在 3.0 中尝试它,如果它在那里工作,那就是 3.1 的问题。

    如果您可以使用 id= 来做到这一点,那么基于 attr-routing 这应该可以工作。

    [ODataRoute("ClientById({id})")]
    
    

    【讨论】:

    • 在更改为 [ODataRoute("ClientById({id})")] 后得到“404 Not Found”。我使用:localhost:44301/odata/ClientById(5) 作为我的 URI.. 有什么想法吗?
    • 尝试从 ODataClientController 中移除 apicontroller 和 route 属性
    • 按照你的建议做了://[Route("api/[controller]")] //[ApiController] 得到了 404 问题..
    • 您可以将您的项目发布到 github 或其他地方吗?就这些课。谢谢
    • 我已经把它修好了...当回到上面的原始设置但将 EdmModel 函数更改为: var function = builder.Function("ClientById"); function.Parameter("id"); function.ReturnsCollectionFromEntitySet("ODataClientDetails");......我认为将“function.Parameter("id")”移动到returnsCollectionFromEntitySet之前有所不同..谢谢你看..我很感激。
    猜你喜欢
    • 1970-01-01
    • 2018-12-25
    • 2020-05-11
    • 1970-01-01
    • 2020-10-05
    • 2013-11-30
    • 1970-01-01
    • 2021-11-23
    • 2021-06-02
    相关资源
    最近更新 更多