Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我的HTTP帖子在添加Microsoft.AspNetCore.OData.Versioning后不再传递正文内容_C#_Asp.net Core_Odata_Api Versioning_Microsoft Odata - Fatal编程技术网

C# 为什么我的HTTP帖子在添加Microsoft.AspNetCore.OData.Versioning后不再传递正文内容

C# 为什么我的HTTP帖子在添加Microsoft.AspNetCore.OData.Versioning后不再传递正文内容,c#,asp.net-core,odata,api-versioning,microsoft-odata,C#,Asp.net Core,Odata,Api Versioning,Microsoft Odata,我正在开发一个ASP.NET Core 2.2 API,该API通过Microsoft.AspNetCore.OData v7.1.0 NuGet实现OData。我一切正常,所以我决定通过Microsoft.AspNetCore.OData.Versioning v3.1.0添加API版本控制 现在,控制器中的GET和GET{id}方法可以正确地进行版本控制。例如,我可以使用URL访问get list端点方法 ~/api/v1/addresscompliancecodes 或 但是,当我尝试创

我正在开发一个ASP.NET Core 2.2 API,该API通过Microsoft.AspNetCore.OData v7.1.0 NuGet实现OData。我一切正常,所以我决定通过Microsoft.AspNetCore.OData.Versioning v3.1.0添加API版本控制

现在,控制器中的GET和GET{id}方法可以正确地进行版本控制。例如,我可以使用URL访问get list端点方法

~/api/v1/addresscompliancecodes

但是,当我尝试创建一个新记录时,请求路由到控制器中的正确方法,但现在请求正文内容没有传递到POST控制器方法

我一直在遵循Microsoft.ApsNetCore.OData.Versioning中的示例

我的控制器中有HttpPost方法

    [HttpPost]
    [ODataRoute()]
    public async Task<IActionResult> CreateRecord([FromBody] AddressComplianceCode record, ODataQueryOptions<AddressComplianceCode> options)
    {

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        _context.Add(record);
        await _context.SaveChangesAsync();

        return Created(record);
    }
它在控制器的HttpPost方法中与[FromBody]一起工作

然而,在遵循API版本控制OData GitHub中的示例时,我现在使用的是如下所示的配置类,而不是以前的模型生成器

public class AddressComplianceCodeModelConfiguration : IModelConfiguration
{

    private static readonly ApiVersion V1 = new ApiVersion(1, 0);

    private EntityTypeConfiguration<AddressComplianceCode> ConfigureCurrent(ODataModelBuilder builder)
    {
        var addressComplianceCode = builder.EntitySet<AddressComplianceCode>("AddressComplianceCodes").EntityType;

        addressComplianceCode
            .HasKey(p => p.Code)
            .Filter()
            .Count()
            .Expand()
            .OrderBy()
            .Page() // Allow for the $top and $skip Commands
            .Select();


        return addressComplianceCode;
    }
    public void Apply(ODataModelBuilder builder, ApiVersion apiVersion)
    {
        if (apiVersion == V1)
        {
            ConfigureCurrent(builder);
        }
    }
}
如果相关,我在Startup.cs->ConfigureServices中有以下代码

        // Add Microsoft's API versioning
        services.AddApiVersioning(options =>
        {
            // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
            options.ReportApiVersions = true;
        });

        // Add OData 4.0 Integration
        services.AddOData().EnableApiVersioning();

        services.AddMvc(options =>
            {
                options.EnableEndpointRouting = false; // TODO: Remove when OData does not causes exceptions anymore
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(opt =>
            {
                opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });
我觉得问题在于这个模型有点不匹配,但我不明白为什么不匹配

19年3月18日更新-其他信息

这是我的实体类

[Table("AddressComplianceCodes")]
public class AddressComplianceCode : EntityBase
{
    [Key]
    [Column(TypeName = "char(2)")]
    [MaxLength(2)]
    public string Code { get; set; }

    [Required]
    [Column(TypeName = "varchar(150)")]
    [MaxLength(150)]
    public string Description { get; set; }
}
和EntityBase类

public class EntityBase : IEntityDate
{
    public bool MarkedForRetirement { get; set; }

    public DateTimeOffset? RetirementDate { get; set; }

    public DateTimeOffset? LastModifiedDate { get; set; }

    public string LastModifiedBy { get; set; }

    public DateTimeOffset? CreatedDate { get; set; }

    public string CreatedBy { get; set; }

    public bool Delete { get; set; }

    public bool Active { get; set; }
}
这是邮递员的请求正文

{   
    "@odata.context": "https://localhost:44331/api/v1/$metadata#AddressComplianceCodes",
    "Code": "Z1",
    "Description": "Test Label - This is a test for Z1",
    "Active": true
}

有什么想法吗?

事实证明,问题在于我没有在Postman请求正文中使用camel-case作为我的属性名。这不仅仅是Microsoft.AspNetCore.Odata的问题,但一旦我添加了Microsoft.AspNetCore.Odata.Versioning NuGet包,它就失败了,属性名的开头字符为大写。似乎Microsoft.AspNetCore.Odata.Versioning使用了自己的MediaTypeFormatter,它支持小写。我在下面的GitHub帖子中发现了这一点

事实证明,问题在于我没有在Postman请求主体中使用camel-case作为属性名。这不仅仅是Microsoft.AspNetCore.Odata的问题,但一旦我添加了Microsoft.AspNetCore.Odata.Versioning NuGet包,它就失败了,属性名的开头字符为大写。似乎Microsoft.AspNetCore.Odata.Versioning使用了自己的MediaTypeFormatter,它支持小写。我在下面的GitHub帖子中发现了这一点

没有定制的MediaTypeFormatter,但是在3.0中,这种行为确实发生了变化,因为对于大多数基于JSON的API来说,使用驼峰大小写似乎是默认的。然而,这很容易恢复

modelBuilder.ModelBuilderFactory = () => new ODataConventionModelBuilder();
// as opposed to the new default:
// modelBuilder.ModelBuilderFactory = () => new ODataConventionModelBuilder().EnableLowerCamelCase();
这里也是您执行或更改与模型生成器相关的任何其他设置的地方。将调用factory方法根据API版本创建新的模型生成器

值得指出的是,您确实需要绘制两次路线图。出于演示目的,配置了by查询字符串和by URL路径。您应该选择一个或另一个,并删除未使用的一个


我希望这会有所帮助。

没有定制的MediaTypeFormatter,但在3.0中,这种行为确实发生了变化,因为对于大多数基于JSON的API来说,使用驼峰大小写似乎是默认的。然而,这很容易恢复

modelBuilder.ModelBuilderFactory = () => new ODataConventionModelBuilder();
// as opposed to the new default:
// modelBuilder.ModelBuilderFactory = () => new ODataConventionModelBuilder().EnableLowerCamelCase();
这里也是您执行或更改与模型生成器相关的任何其他设置的地方。将调用factory方法根据API版本创建新的模型生成器

值得指出的是,您确实需要绘制两次路线图。出于演示目的,配置了by查询字符串和by URL路径。您应该选择一个或另一个,并删除未使用的一个


我希望这会有所帮助。

您能为我们发布一个较小的可重复示例,以尝试重现您的问题吗?您能为我们发布一个较小的可重复示例,以尝试重现您的问题吗?
public class EntityBase : IEntityDate
{
    public bool MarkedForRetirement { get; set; }

    public DateTimeOffset? RetirementDate { get; set; }

    public DateTimeOffset? LastModifiedDate { get; set; }

    public string LastModifiedBy { get; set; }

    public DateTimeOffset? CreatedDate { get; set; }

    public string CreatedBy { get; set; }

    public bool Delete { get; set; }

    public bool Active { get; set; }
}
{   
    "@odata.context": "https://localhost:44331/api/v1/$metadata#AddressComplianceCodes",
    "Code": "Z1",
    "Description": "Test Label - This is a test for Z1",
    "Active": true
}
modelBuilder.ModelBuilderFactory = () => new ODataConventionModelBuilder();
// as opposed to the new default:
// modelBuilder.ModelBuilderFactory = () => new ODataConventionModelBuilder().EnableLowerCamelCase();