如何使用Azure Functions解析表单数据

时间:2017-07-28 02:57:48

标签: c# function azure sendgrid

我正在尝试在Azure函数中获取表单数据。

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”类型的对象。

我正在尝试通过SendGrid解析入站电子邮件,如此处所述。 https://sendgrid.com/docs/Classroom/Basics/Inbound_Parse_Webhook/setting_up_the_inbound_parse_webhook.html

传入的请求看起来是正确的。

- XYZZY 内容处理:表格数据;名称= “附件”

0 --xYzZY 内容处理:表格数据;名称= “文本”

你好世界 --xYzZY 内容处理:表格数据;名称= “受试者”

主题 --xYzZY 内容处理:表格数据; NAME = “至”

3 个答案:

答案 0 :(得分:2)

根据错误消息,您使用multipart / form-data作为请求内容类型。但是您没有将任何媒体类型数据发布到服务器。

如果您只想将一些普通数据发送到服务器,可以将内容类型更改为application / x-www-form-urlencoded并按以下格式修改您的请求正文。

name=attachments&anothername=anothervalue

如果您想从多部分帖子中获取表单数据,可以使用MultipartFormDataStreamProvider。

string filePath = "set a temp path to store the uploaded file";
var provider = new MultipartFormDataStreamProvider(filePath);
var multipartProvider = await req.Content.ReadAsMultipartAsync(provider);
var formData = multipartProvider.FormData;

手动解析请求正文的内容。

string content = await req.Content.ReadAsStringAsync();
string formdata = content.Split(';')[1];
string[] namevalues = formdata.Split('&');
NameValueCollection col = new NameValueCollection();
foreach (string item in namevalues)
{
    string[] nameValueItem = item.Split('=');
    col.Add(nameValueItem[0], nameValueItem[1]);
}

答案 1 :(得分:2)

由于似乎没有将$ python -v 转换为自定义模型/视图模型类型的好方法,因此我为此编写了扩展方法。

Azure Functions v2 / v3尚不支持此功能是很遗憾的。

IFormCollection

这将尝试将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 string FirstName { get; set; }

答案 2 :(得分:0)

要读取表单数据,应使用方法ReadAsMultipartAsync:

data = await req.Content.ReadAsMultipartAsync().ConfigureAwait(false);