2014-10-23 6 views
0

Я пишу веб-сервер, основанный на коде в этом link. Я пытаюсь получить данные POST из формы, но у меня возникли проблемы с получением этих данных. Веб-сервер предназначен для самостоятельного размещения. Его в основном панель управления, где я могу добавлять и редактировать эти устройства, называемые стеке. Вот мой метод WebServer.Run:HttpListener Данные формы сообщения

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 поля: имя, IP-& порт для пользовательского класса, который записывает некоторые огни безопасности. Его вызывается из метода SendResponse в другом классе.

private static WebServerRequestData SendResponse(HttpListenerRequest request) 

Это сегмент, где моя форма вызывается, пример редактирования URL является 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; 
      } 

Здесь я обрабатываю свои запросы. У него есть несколько операторов if, основанных на свойстве RawUrl объектов HttpListenerRequest. Я пытаюсь получить данные формы. В разделе:

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, но возвращает null InputStream из ctx.Request. (ctx - мой объект HttpListenerContext).

Я прочитал об использовании multipartform и application/x-www-form-urlencoded и попробовал их обоих.

До сих пор многостраничная форма давала мне данные (даже если это не данные формы), а другая нет.

Я думаю, что я близок к тому, чтобы получить данные моей формы, чтобы я появился. Я просто застрял в этой точке. Я не уверен, что делать.

Кроме того, сейчас я в настоящее время читают эту аналогичную должность на stackoverflow

EDIT: После чтения из этой ссылке, я изменил мой метод запуска веб-сервера на следующее:

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(); 
      } 
     } 
    } 

d Я все еще просто получаю "------WebKitFormBoundaryjiSulPEnvWX7MIeq--\r\n"

ответ

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; 
    } 
Смежные вопросы