我们有第三方供应商以下列格式向我们发布数据。不幸的是,这是他们提供的唯一格式。 Json会很好,但我们没有选择。它正在击中一个.net核心webapi控制器方法。
contact%5Bid%5D=2&contact%5Bemail%[email protected]&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。
使用FromForm
绑定时,默认情况下不支持DataContract / DataMember属性。它们只有你期望的FromBody
支持,因为使用的序列化程序(通常是JSON.NET)支持这些属性 - 但是这种支持独立于MVC绑定。
有一种方法可以在启动期间扩展MVC的表单绑定:
services.AddMvc(options => options.ModelMetadataDetailsProviders.Add(new DataMemberBindingMetadataProvider()));
简单实现IBindingMetadataProvider
以查找DataMemberAttribute / Name:
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
而不是您自己的元数据提供程序,但我发现它的构造函数依赖项使这个问题。