在POST中从表单序列化备用属性名称

ton*_*mke 5 c# asp.net asp.net-web-api

我正在为第三方API创建一个回调端点.调用者将POST多部分表单数据发送给它.

像这样的东西:

public SomeApiController : ApiController {
  public AModel Post(AModel input) {
    return input; //for demonstration
  }
}
Run Code Online (Sandbox Code Playgroud)

它将发布的一些字段在名称中有破折号,它不能是实际的.NET属性名称.因此,我使用[DataContract]和[DataMember(name ="blah")]来定义序列化规则.

模型:

//input model class
[DataContract]
public class AModel {
  [DataMember]
  public string NormalProperty {get; set;} //value set appropriately
  [DataMember(Name="abnormal-property")]
  public string AbnormalProperty {get; set;} //always null (not serializing)
}
Run Code Online (Sandbox Code Playgroud)

使用标准的XML和JSON帖子,这很好用.设置正常和异常属性,我可以继续我的业务.

但是,对于表单数据的任何变体(form-data,multiplart/form-data,x-urlencoded-form-data,AbnormalProperty都没有正确地反序列化到模型中,并且将始终为null.

是否有指令我缺少什么?

ton*_*mke 0

经过一番猛烈的抨击之后,我们或多或少做了两件事的结合。

对于 url 编码的表单,我们遵循了Zen Coder的示例,它运行得完美无缺。

但是,对于流式传输到服务器的传统多部分表单(它们可以包含文件数据),我们创建了一个简单的解决方案来从请求中读取键/值,然后手动序列化。

在我们的特定用例中,我们不必担心文件数据的传入或任何其他事情,因此我们可以假设所有内容都是字符串并从那里进行序列化工作。但是,为实际文件添加 ContentDisposition 标头的简单检查可能是明智之举。

例子:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;

namespace WebApplication1.Controllers
{
    public class ValuesController : ApiController
    {
        public async Task<Dictionary<string,string>> Post()
        {
            if (!Request.Content.IsMimeMultipartContent())
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            var provider = new MultipartMemoryStreamProvider();
            var formData = new Dictionary<string,string>();
            try
            {
                await Request.Content.ReadAsMultipartAsync(provider);
                foreach (var item in provider.Contents)
                {
                    formData.Add(item.Headers.ContentDisposition.Name.Replace("\"",""), await item.ReadAsStringAsync());
                }

                return formData;
            }
            catch (Exception e)
            {
                throw new HttpResponseException(HttpStatusCode.InternalServerError);
            }
        }    
  }
}
Run Code Online (Sandbox Code Playgroud)