HttpListener发布表单数据

时间:2014-10-23 13:57:07

标签: c# webserver http-post httplistener httplistenerrequest

我正在根据此link中的代码编写一个网络服务器。我试图从表单中获取POST数据但是我 我无法获取这些数据。网络服务器应该是自托管的。它基本上是一个控制面板,我可以添加和编辑这些称为堆栈灯的设备。这是我的WebServer.Run方法:

public void Run()
    {
        ThreadPool.QueueUserWorkItem((o) =>
        {
            Console.WriteLine("StackLight Web Server is running...");

            try
            {
                while (_listener.IsListening)
                {
                    ThreadPool.QueueUserWorkItem((c) =>
                    {
                        var ctx = c as HttpListenerContext;

                        try
                        {
                            // set the content type
                            ctx.Response.Headers[HttpResponseHeader.ContentType] = SetContentType(ctx.Request.RawUrl);
                            WebServerRequestData data = _responderMethod(ctx.Request);

                            string post = "";
                            if(ctx.Request.HttpMethod == "POST")
                            {
                                using(System.IO.StreamReader reader = new StreamReader(ctx.Request.InputStream, ctx.Request.ContentEncoding))
                                {
                                    post = reader.ReadToEnd();
                                }
                            }

                            if(data.ContentType.Contains("text") || data.ContentType.Equals("application/json"))
                            {
                                // serve text/html,css,js & application/json files as UTF8
                                // images don't need to be served as UTF8, they don't have encodings
                                char[] chars = new char[data.Content.Length / sizeof(char)];
                                System.Buffer.BlockCopy(data.Content, 0, chars, 0, data.Content.Length);
                                string res = new string(chars);
                                data.Content = Encoding.UTF8.GetBytes(res);
                            }

                            // this writes the html out from the byte array
                            ctx.Response.ContentLength64 = data.Content.Length;
                            ctx.Response.OutputStream.Write(data.Content, 0, data.Content.Length);
                        }
                        catch (Exception ex)
                        {
                            ConfigLogger.Instance.LogCritical(LogCategory, ex);
                        }
                        finally
                        {
                            ctx.Response.OutputStream.Close();
                            ctx.Response.Close();
                        }
                    }, _listener.GetContext());
                }
            }
            catch (Exception ex)
            {
                ConfigLogger.Instance.LogCritical(LogCategory, ex); 
            }
        });
    }

我正在使用一个名为WebServerRequestData的类来获取我的页面,css,javascript和图像,以便我可以为它们提供服务。该课程如下:

public class WebServerRequestData
{
    // Raw URL from the request object
    public string RawUrl { get; set; }

    // Content Type of the file
    public string ContentType { get; set; }

    // A byte array containing the content you need to serve
    public byte[] Content { get; set; }

    public WebServerRequestData(string data, string contentType, string rawUrl)
    {
        this.ContentType = contentType;
        this.RawUrl = rawUrl;

        byte[] bytes = new byte[data.Length * sizeof(char)];
        System.Buffer.BlockCopy(data.ToCharArray(), 0, bytes, 0, bytes.Length);
        this.Content = bytes;
    }

    public WebServerRequestData(byte[] data, string contentType, string rawUrl)
    {
        this.ContentType = contentType;
        this.RawUrl = rawUrl;
        this.Content = data;
    }
}

这是我的表格:

public static string EditStackLightPage(HttpListenerRequest request)
    {
        // PageHeadContent writes the <html><head>...</head> stuf
        string stackLightPage = PageHeadContent();

        // start of the main container
        stackLightPage += ContainerDivStart;

        string[] req = request.RawUrl.Split('/');
        StackLightDevice stackLight = Program.StackLights.First(x => x.Name == req[2]);

        stackLightPage += string.Format("<form action='/edit/{0}/update' method='post' enctype='multipart/form-data'>", stackLight.Name);
        stackLightPage += string.Format("Stack Light<input type='text' id='inputName' value='{0}'>", stackLight.Name);
        stackLightPage += string.Format("IP Address<input type='text' id='inputIp' value='{0}'>", stackLight.Ip);
        stackLightPage += string.Format("Port Number<input type='text' id='inputPort' value='{0}'>", stackLight.Port);

        stackLightPage += "<button type='submit'>Update</button>";
        stackLightPage += "</form>";

        // end of the main container
        stackLightPage += ContainerDivEnd;

        stackLightPage += PageFooterContent();

        return stackLightPage;
    }

它只有3个字段:name,ip&amp;写入某些安全灯的自定义类的端口。它是从另一个类的SendResponse方法调用的。

private static WebServerRequestData SendResponse(HttpListenerRequest request)

这是我的表单被调用的片段,编辑网址的示例为localhost:8080/edit/stackLight-Name,更新为localhost:8080/edit/stackLight-Name/update。这是检查rawurl是否包含这些路由的代码:

if(request.RawUrl.Contains("edit"))
            {
                if (request.RawUrl.Contains("update"))
                {
                    // get form data from the edit page and return to the edit
                    _resultString = WebServerHtmlContent.EditStackLightPage(request);
                    _data = new WebServerRequestData(_resultString, "text/html", request.RawUrl);
                    return _data;
                }

                _resultString = WebServerHtmlContent.EditStackLightPage(request);
                _data = new WebServerRequestData(_resultString, "text/html", request.RawUrl);
                return _data;
            }

这是我处理请求的地方。它基于HttpListenerRequest对象的RawUrl属性得到了一些if语句。我正在尝试获取表单数据。在以下部分:

if(ctx.Request.HttpMethod == "POST")
                            {
                                using(System.IO.StreamReader reader = new StreamReader(ctx.Request.InputStream, ctx.Request.ContentEncoding))
                                {
                                    post = reader.ReadToEnd();
                                }
                            }

我能够获得一个InputStream,但我没有得到表单数据。这是我得到的数据:"------WebKitFormBoundaryAGo7VbCZ2YC79zci--\r\n"

输入流是否应该包含我的表单数据?

我没有看到InputStream中表单字段中的任何数据。我尝试过使用application/x-www-form-urlencoded但是从ctx.Request返回一个null InputStream。 (ctx是我的HttpListenerContext对象)。

我读到了关于使用multipartform和application / x-www-form-urlencoded并尝试过它们。

到目前为止,多部分表单为我提供了数据(即使它不是表单数据),而另一部分则没有。

我认为我已经接近让我的表单数据出现了,我只是坚持这一点。我不知道该怎么做。

此外,我现在正在stackoverflow

上阅读此类似文章

修改 从该链接读取后,我已将我的Web服务器运行方法更改为以下内容:

try
                        {
                            // set the content type
                            WebServerRequestData data = _responderMethod(ctx.Request);

                            string post = "";
                            if(ctx.Request.HttpMethod == "POST")
                            {
                                data.ContentType = ctx.Request.ContentType;
                                post = GetRequestPostData(ctx.Request);
                            }

                            ctx.Response.ContentLength64 = data.OutputBuffer.Length;
                            ctx.Response.OutputStream.Write(data.OutputBuffer, 0, data.OutputBuffer.Length);
                        }

这是方法GetRequestPostData():

private static string GetRequestPostData(HttpListenerRequest request)
    {
        if (!request.HasEntityBody)
            return null;
        using(System.IO.Stream body = request.InputStream)
        {
            using(System.IO.StreamReader reader = new StreamReader(body, request.ContentEncoding))
            {
                return reader.ReadToEnd();
            }
        }
    }

我仍然只是"------WebKitFormBoundaryjiSulPEnvWX7MIeq--\r\n"

1 个答案:

答案 0 :(得分:0)

我已经弄明白了,我忘了在表格字段中添加一个名字。

public static string EditStackLightPage(HttpListenerRequest request)
    {
        // PageHeadContent writes the <html><head>...</head> stuf
        string stackLightPage = PageHeadContent();

        // start of the main container
        stackLightPage += ContainerDivStart;

        string[] req = request.RawUrl.Split('/');
        StackLightDevice stackLight = Program.StackLights.First(x => x.Name == req[2]);

        stackLightPage += string.Format("<div class='col-md-8'><form action='/edit/{0}/update' class='form-horizontal' method='post' enctype='multipart/form-data'>", stackLight.Name);
        stackLightPage += string.Format("<fieldset disabled><div class='form-group'><label for='inputName' class='control-label col-xs-4'>Stack Light</label><div class='col-xs-8'><input type='text' class='form-control' id='inputName' name='inputName' value='{0}'></div></div></fieldset>", stackLight.Name);
        stackLightPage += string.Format("<div class='form-group'><label for='inputIp' class='control-label col-xs-4'>IP Address</label><div class='col-xs-8'><input type='text' class='form-control' id='inputIp' name='inputIp' value='{0}'></div></div>", stackLight.Ip);
        stackLightPage += string.Format("<div class='form-group'><label for='inputPort' class='control-label col-xs-4'>Port Number</label><div class='col-xs-8'><input type='text' class='form-control' id='inputPort' name='inputPort' value='{0}'></div></div>", stackLight.Port);

        stackLightPage += "<div class='form-group'><div class='col-xs-offset-4 col-xs-8'><button type='submit' class='btn btn-inverse'>Update</button></div></div>";
        stackLightPage += "</form></div>";

        // end of the main container
        stackLightPage += ContainerDivEnd;

        stackLightPage += PageFooterContent();

        return stackLightPage;
    }