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!
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.
What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
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]);
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");
});
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With