如何将绑定表单urlencoded数据建模到.net类

时间:2018-01-26 18:23:01

标签: model-binding asp.net-core-webapi

我们有第三方供应商以下列格式向我们发布数据。不幸的是,这是他们提供的唯一格式。 Json会很好,但我们没有选择余地。它正在使用.net核心webapi控制器方法。

contact%5Bid%5D=2&contact%5Bemail%5D=test@test.com&contact%5Bfirst_name%5D=john&contact%5Blast_name%5D=smith

控制器方法如下所示。

public IActionResult Endpoint([FromForm] customClass)
{
    //do something with customClass
    return Ok();
}

该课程类似于

using System;
using System.Runtime.Serialization;

namespace Domain.Models.Custom
{
    [DataContract]
    public class CustomClass
    {
        [DataMember(Name = "contact[id]")]
        public int Id { get; set; }

        [DataMember(Name = "contact[first_name]")]
        public string FirstName { get; set; }

        [DataMember(Name = "contact[last_name]")]
        public string LastName { get; set; }

        [DataMember(Name = "contact[phone]")]
        public string PhoneNumber { get; set; }

        [DataMember(Name = "contact[email]")]
        public string EmailAddress { get; set; }
    }
}

从我读过的所有内容来看,听起来像使用DataContract和DataMember属性来修饰类对我来说应该是模型绑定。但是当我在Endpoint方法中查看customClass的实例时,所有属性都为null。

1 个答案:

答案 0 :(得分:0)

使用FromForm绑定时,默认情况下不支持

DataContract / DataMember属性。正如您期望的那样,FromBody仅支持它们,因为所使用的序列化程序(通常为JSON.NET)支持这些属性-但这种支持独立于MVC绑定。

有一种方法可以在启动过程中扩展MVC的表单绑定:

services.AddMvc(options => options.ModelMetadataDetailsProviders.Add(new DataMemberBindingMetadataProvider()));

IBindingMetadataProvider的简单实现以查找DataMemberAttribute /名称:

public class DataMemberBindingMetadataProvider : IBindingMetadataProvider
{
    public void CreateBindingMetadata(BindingMetadataProviderContext context)
    {
        var dataMember = context.Attributes.OfType<DataMemberAttribute>().FirstOrDefault();
        if (dataMember != null)
        {
            context.BindingMetadata.BinderModelName = dataMember.Name;
        }
    }
}

或者,您可以尝试添加DataAnnotationsMetadataProvider而不是您自己的元数据提供程序,但是我发现它的构造函数依赖性使此问题变得很严重。