2014-10-23 2 views
0

나는 link에 코드를 기반으로 웹 서버를 작성하고 있습니다. 양식에서 POST 데이터를 가져 오려고하는데, 데이터를 가져 오는 데 문제가 있습니다. 웹 서버는 자체 호스팅 될 예정입니다. 그것의 기본적으로 제어 패널을 추가하고 스택 조명이라고 불리는이 장치들을 편집 할 수 있습니다. 여기 내 WebServer.Run 방법입니다 : 내 페이지를 얻을 수 WebServerRequestData라는 클래스를 사용하고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); 
      } 
     }); 
    } 

, CSS, 자바 스크립트와 이미지 나 서버들을 수 있습니다.

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

을 그리고 이것은 내 양식이다 : 그 클래스는 다음과 같습니다 이름, IP 일부 안전 조명에 쓰는 사용자 정의 클래스에 대한 & 포트 :

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 필드입니다. 이 클래스는 다른 클래스의 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; 
      } 

여기가 내 요청을 처리하는 곳입니다. HttpListenerRequest 객체 인 RawUrl 속성을 기반으로하는 if 문이 몇 개 있습니다. 양식 데이터를 가져 오려고합니다. 섹션에서 :

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

입력 스트림을 가져올 수 있지만 양식 데이터를 가져 오지 못했습니다. 이 데이터는 내가 받고있는 데이터입니다. "------WebKitFormBoundaryAGo7VbCZ2YC79zci--\r\n"

입력 스트림에 내 양식 데이터가 있어야하지 않아야합니까?

InputStream의 양식 필드에있는 데이터가 표시되지 않습니다. application/x-www-form-urlencoded을 사용해 보았지만 ctx.Request에서 null InputStream을 반환합니다. (ctx 내 HttpListenerContext 개체입니다).

multipartform 및 application/x-www-form-urlencoded 사용에 대해 읽었으며 둘 다 시도했습니다.

지금까지 multipart 형식은 데이터를 제공하지만 (양식 데이터가 아니더라도) 다른 형식은 제공하지 않습니다.

나는 내가 지금까지 붙어있는 내 양식 데이터를 얻는 것에 가깝다고 생각합니다. 무엇을해야할지 모르겠습니다.또한

, 지금은 현재에 유사한 게시물을 읽고있다 stackoverflow 편집

:

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; 
    } 
관련 문제