C# Owin WebApp: Parsing POST Requests?
Solution 1
Since the data returns in KeyValuePair format you can cast it as IEnumerable which looks something like the following:
var formData = await context.Request.ReadFormAsync() as IEnumerable<KeyValuePair<string, string[]>>;
//now you have the list that you can query against
var formElementValue = formData.FirstOrDefault(x => x.Key == "NameOfYourHtmlFormElement").Value[0]);
Solution 2
You can use the ReadFormAsync() utility on the IOwinRequest object to read/parse the form parameters.
public void Configuration(IAppBuilder app)
{
app.Run(async context =>
{
//IF your request method is 'POST' you can use ReadFormAsync() over request to read the form
//parameters
var formData = await context.Request.ReadFormAsync();
//Do the necessary operation here.
await context.Response.WriteAsync("Hello");
});
}
Solution 3
To extract the body Parameters for each content type you can use a method like this:
public async static Task<IDictionary<string, string>> GetBodyParameters(this IOwinRequest request)
{
var dictionary = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
if (request.ContentType != "application/json")
{
var formCollectionTask = await request.ReadFormAsync();
foreach (var pair in formCollectionTask)
{
var value = GetJoinedValue(pair.Value);
dictionary.Add(pair.Key, value);
}
}
else
{
using (var stream = new MemoryStream())
{
byte[] buffer = new byte[2048]; // read in chunks of 2KB
int bytesRead;
while ((bytesRead = request.Body.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, bytesRead);
}
var result = Encoding.UTF8.GetString(stream.ToArray());
// TODO: do something with the result
var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(result);
foreach(var pair in dict)
{
string value = (pair.Value is string) ? Convert.ToString(pair.Value) : JsonConvert.SerializeObject(pair.Value);
dictionary.Add(pair.Key, value);
}
}
}
return dictionary;
}
private static string GetJoinedValue(string[] value)
{
if (value != null)
return string.Join(",", value);
return null;
}
References: Most efficient way of reading data from a stream
Ganesh_AT
Updated on June 14, 2022Comments
-
Ganesh_AT almost 2 years
I would like some help on parsing HTTP POST requests in a C# console application. The app runs a 'web-server' using Owin. Details of the application are available here and the current 'stable version' of the relevant code is here.
I am extending the above application to enable configuration through the web UI. For example, the app currently reports a large number of parameters. I would like the end-user to be able to select which parameters get reported over the network. Towards this, I made some modifications to the code above:
using Microsoft.Owin; using Owin; ......... [assembly: OwinStartup(typeof(SensorMonHTTP.WebIntf))] ......... ......... namespace SensorMonHTTP { ... public class WebIntf { public void Configuration(IAppBuilder app) { app.Run(context => { var ConfigPath = new Microsoft.Owin.PathString("/config"); var ConfigApplyPath = new Microsoft.Owin.PathString("/apply_config"); var SensorPath = new Microsoft.Owin.PathString("/"); if (context.Request.Path == SensorPath) { return context.Response.WriteAsync(GetSensorInfo()); /* Returns JSON string with sensor information */ } else if (context.Request.Path == ConfigPath) { /* Generate HTML dynamically to list out available sensor information with checkboxes using Dynatree: Tree3 under 'Checkbox & Select' along with code to do POST under 'Embed in forms' in http://wwwendt.de/tech/dynatree/doc/samples.html */ /* Final segment of generated HTML is as below: <script> ..... $("form").submit(function() { var formData = $(this).serializeArray(); var tree = $("#tree3").dynatree("getTree"); formData = formData.concat(tree.serializeArray()); // alert("POST this:\n" + jQuery.param(formData)); // -- This gave the expected string in an alert when testing out $.post("apply_config", formData); return true ; }); ...... </script></head> <body> <form action="apply_config" method="POST"> <input type="submit" value="Log Selected Parameters"> <div id="tree3" name="selNodes"></div> </body> </html> End of generated HTML code */ } else if (context.Request.Path == ConfigApplyPath) { /* I want to access and parse the POST data here */ /* Tried looking into context.Request.Body as a MemoryStream, but not getting any data in it. */ } } } ........ }
Can anyone help me with how the POST data can be accessed in the above code structure?
Thanks in advance!
-
Ganesh_AT over 10 yearsAndrew, Thanks for the response. It turned out that I had a problem in modifying the JavaScript code from the Dynatree example: particularly, the form submit procedure apparently had to return 'false' for the form data to be sent over correctly. I have since resolved the issue.