如何使用Azure Functions解析表单数据
我正在尝试在Azure函数中获取表单数据.
I am trying to get form data within an Azure function.
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
NameValueCollection col = req.Content.ReadAsFormDataAsync().Result;
return req.CreateResponse(HttpStatusCode.OK, "OK");
}
我遇到以下错误:
执行函数:System.Net.Http.Formatting时发生异常:没有MediaTypeFormatter可以从媒体类型为"multipart/form-data"的内容中读取"FormDataCollection"类型的对象.
Exception while executing function: System.Net.Http.Formatting: No MediaTypeFormatter is available to read an object of type 'FormDataCollection' from content with media type 'multipart/form-data'.
我试图按此处所述通过SendGrid解析入站电子邮件. https://sendgrid.com/docs/Classroom/Basics/Inbound_Parse_Webhook/setting_up_the_inbound_par.
I am trying to parse inbound emails via SendGrid as described here. https://sendgrid.com/docs/Classroom/Basics/Inbound_Parse_Webhook/setting_up_the_inbound_parse_webhook.html
传入请求看起来正确.
-xYzZY内容处置:表单数据;name =附件"
--xYzZY Content-Disposition: form-data; name="attachments"
0--xYzZY内容处置:表单数据;name ="text"
0 --xYzZY Content-Disposition: form-data; name="text"
你好世界--xYzZY内容处置:表单数据;name ="subject"
Hello world --xYzZY Content-Disposition: form-data; name="subject"
主题--xYzZY内容处置:表单数据;name ="to"
Subject --xYzZY Content-Disposition: form-data; name="to"
由于似乎没有将 IFormCollection
转换为自定义模型/视图模型类型的好方法,所以我写了一篇扩展方法.
Since there doesn't appear to be a good way to convert an IFormCollection
to a custom model / viewmodel type, I wrote an extension method for this.
Azure Functions v2/v3尚不支持此功能是很遗憾的.
It's a shame that Azure Functions v2/v3 doesn't support this out of the box yet.
public static class FormCollectionExtensions
{
/// <summary>
/// Attempts to bind a form collection to a model of type <typeparamref name="T" />.
/// </summary>
/// <typeparam name="T">The model type. Must have a public parameterless constructor.</typeparam>
/// <param name="form">The form data to bind.</param>
/// <returns>A new instance of type <typeparamref name="T" /> containing the form data.</returns>
public static T BindToModel<T>(this IFormCollection form) where T : new()
{
var props = typeof(T).GetProperties();
var instance = Activator.CreateInstance<T>();
var formKeyMap = form.Keys.ToDictionary(k => k.ToUpper(), k => k);
foreach (var p in props)
{
if (p.CanWrite && formKeyMap.ContainsKey(p.Name.ToUpper()))
{
p.SetValue(instance, form[formKeyMap[p.Name.ToUpper()]].FirstOrDefault());
}
}
return instance;
}
}
这将尝试将 IFormCollection
绑定到您传递的任何模型类型.属性名称不区分大小写(即,您可以将 firstname = Bob
映射到 public字符串FirstName {get; set;}
.
This will attempt to bind an IFormCollection
to whatever model type you pass in. Property names are case insensitive (i.e. you can map firstname=Bob
to public string FirstName { get; set; }
.
用法:
var myModel = (await httpReq.ReadFormAsync()).BindToModel<MyModel>();