问题
I have the following code in my Function App
using System.Net;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
var data = await req.Content.ReadAsAsync<PostData>();
var sid = data.sid;
log.Info($"sid ={sid}");
return req.CreateResponse(HttpStatusCode.OK, $"Current Time : {DateTime.Now}");
}
public class PostData
{
public string sid { get; set; }
}
The error message is
No MediaTypeFormatter is available to read an object of type 'PostData' from content with media type 'application/x-www-form-urlencoded'.
How do I set the function up to work with the correct media type?
[Update]
If I change the code to
var content = req.Content;
var jsonContent = await content.ReadAsStringAsync();
log.Info(jsonContent);
I can see the jsonContent text logged starting with
ToCountry=AU&ToState=&SmsMessageSid=SM8cac6c6a851 etc
But I am unclear on how to go about extracting the data I need.
I tried adding
dynamic results = JsonConvert.DeserializeObject<dynamic>(jsonContent);
and
using Newtonsoft.Json;
however this causes a script compilation error
[Update] Studying the sample code on the Integration Tab
Example C# code for a GitHub WebHook function
#r "Newtonsoft.Json"
using System;
using System.Net;
using System.Threading.Tasks;
using Newtonsoft.Json;
public static async Task<object> Run(HttpRequestMessage req, TraceWriter log)
{
string jsonContent = await req.Content.ReadAsStringAsync();
log.Info("Hi 1"); // does log
dynamic data = JsonConvert.DeserializeObject(jsonContent);
log.Info("Hi 2"); // does not log
return req.CreateResponse(HttpStatusCode.OK, $"Current Time : {DateTime.Now}"
});
}
This produces an error
System.AggregateException : One or more errors occurred. ---> Unexpected character encountered while parsing value: T. Path '', line 0, position 0.
at Microsoft.Azure.WebJobs.Script.Description.DotNetFunctionInvoker.GetTaskResult(Task task)
回答1:
For application/x-www-form-urlencoded, the body of the HTTP message sent to the server is essentially one giant query string -- name/value pairs are separated by the ampersand (&), and names are separated from values by the equals symbol (=). An example of this would be:
MyVariableOne=ValueOne&MyVariableTwo=ValueTwo
We could get more info about application/x-www-form-urlencoded from another SO thread.
Currently, not all of the various ASP.NET WebHook receivers are handled fully yet in Functions. I also find a smilar SO Thread. Azure Functions can support 3 types of webhooks: Generic JSON,GitHub,Slack. But we could handle it with our logic. You could have a try to use the following code to get the key value in the Dictionary.
Dictionary<string, string> myDictionary = new Dictionary<string, string>();
if (req.Content.Headers.ContentType.ToString().ToLower().Equals("application/x-www-form-urlencoded"))
{
var body = req.Content.ReadAsStringAsync().Result;
var array = body.Split('&');
foreach (var item in array)
{
var keyvalue = item.Split('=');
myDictionary.Add(keyvalue[0],keyvalue[1]);
}
}
var sid = myDictionary["SmsMessageSid"];
log.Info($"sid ={sid}");
return req.CreateResponse(HttpStatusCode.OK, $"Current Time : {DateTime.Now}");
来源:https://stackoverflow.com/questions/47972655/how-do-i-set-up-a-function-app-to-extract-data-from-media-type-application-x-ww