Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Owin WebApp: Parsing POST Requests?

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!

like image 610
Ganesh_AT Avatar asked Dec 14 '13 00:12

Ganesh_AT


People also ask

What C is used for?

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 ...

What is the full name of C?

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.

Is C language easy?

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 in C language?

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.


3 Answers

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]);
like image 190
bilmuhfk Avatar answered Nov 10 '22 01:11

bilmuhfk


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");
                });
        }
like image 22
Praburaj Avatar answered Nov 10 '22 01:11

Praburaj


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

like image 33
Hamlet Leon Avatar answered Nov 10 '22 01:11

Hamlet Leon