[英]HttpListener Post form data
我正在根據此鏈接中的代碼編寫Web服務器。 我正在嘗試從表單獲取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個字段:用於寫入一些安全燈的自定義類的名稱,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;
}
這是我正在處理我的請求的地方。 有一些基於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返回空的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"
我已經弄清楚了,我忘了在表單字段中添加名稱。
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.