代码之家  ›  专栏  ›  技术社区  ›  Gogoku7

C#-通过WebRequest和HttpListener发送/接收和保存XML文件

  •  0
  • Gogoku7  · 技术社区  · 7 年前

    我的目标 就是要有ASP。NET Webapplication将刚刚通过Http更新的XML文件发送到Windows服务,该服务具有HttpListener。

    到目前为止我所做的 :

    ASP。NET应用程序:

    public string PushSettings(string serverName, string xmlFile)
    {
        var prefix = "http://" + serverName+ ":";
        var portnumber = ConfigurationManager.AppSettings["PortNumber"];
        var command = ConfigurationManager.AppSettings["PushSettingsCommand"];
        var request = (HttpWebRequest)WebRequest.Create(prefix + portnumber + command);
        var bytes = System.Text.Encoding.ASCII.GetBytes(xmlFile);
        request.ContentType = "text/xml; encoding='utf-8'";
        request.ContentLength = bytes.Length;
        request.Method = "POST";
        var requestStream = request.GetRequestStream();
        requestStream.Write(bytes, 0, bytes.Length);
        requestStream.Close();
    
        try
        {
            var response = (HttpWebResponse)request.GetResponse();
            return response.StatusCode.ToString();
        }
        catch (WebException ex)
        {
            Log.Info("WebException thrown while trying to connect to httplistener. Exception message: " + ex.Message + " The following request was attempted: " + prefix + portnumber + command);
            throw new WebException("WebException thrown while trying to connect to httplistener. Exception message: " + ex.Message + " The following request was attempted: " + prefix + portnumber + command);
        }
    }
    

    ( 字符串xmlFile 是作为字符串的整个XML文件)

    public void RunHttpListener()
    {
        var listener = new HttpListener();
        try
        {
            listener.Prefixes.Add(_Prefix);
    
            listener.Start();
    
            var context = listener.GetContext();
            var request = context.Request;
            var ipAdress = context.Request.RemoteEndPoint?.ToString();
    
            if(_Prefix.Contains("PushSettings"))
            {
                SaveFile(context.Request.ContentEncoding, getSettings.GetBoundary(context.Request.ContentType), context.Request.InputStream);
            }
    
            var response = context.Response;
            const HttpStatusCode responseString = HttpStatusCode.OK;
            var buffer = Encoding.UTF8.GetBytes(responseString.ToString());
            response.ContentLength64 = buffer.Length;
            var output = response.OutputStream;
            output.Write(buffer, 0, buffer.Length);
            output.Close();
            listener.Stop();
        }
        catch (Exception ex)
        {
            Log.Info(ex.Message);
            if (listener.IsListening)
            {
                listener.Stop();
            }
        }
    }
    

    ( _前缀

    Httplistener and file upload ,这会引发异常,因为len在第三次循环第一个while(true){}时等于0。以下是该线程的代码:

    public String GetBoundary(String ctype)
    {
        return "--" + ctype.Split(';')[1].Split('=')[1];
    }
    
    public void SaveFile(Encoding enc, String boundary, Stream input)
    {
        var boundaryBytes = enc.GetBytes(boundary);
        var boundaryLen = boundaryBytes.Length;
    
        using (var output = new FileStream("Settings.xml", FileMode.Create, FileAccess.Write))
        {
            var buffer = new Byte[1024];
            var len = input.Read(buffer, 0, 1024);
            var startPos = -1;
    
            // Find start boundary
            while (true)
            {
                if (len == 0)
                {
                    throw new Exception("Start Boundaray Not Found");
                }
    
                startPos = IndexOf(buffer, len, boundaryBytes);
                if (startPos >= 0)
                {
                    break;
                }
                else
                {
                    Array.Copy(buffer, len - boundaryLen, buffer, 0, boundaryLen);
                    len = input.Read(buffer, boundaryLen, 1024 - boundaryLen);
                }
            }
    
            // Skip four lines (Boundary, Content-Disposition, Content-Type, and a blank)
            for (var i = 0; i < 4; i++)
            {
                while (true)
                {
                    if (len == 0)
                    {
                        throw new Exception("Preamble not Found.");
                    }
    
                    startPos = Array.IndexOf(buffer, enc.GetBytes("\n")[0], startPos);
                    if (startPos >= 0)
                    {
                        startPos++;
                        break;
                    }
                    else
                    {
                        len = input.Read(buffer, 0, 1024);
                    }
                }
            }
    
            Array.Copy(buffer, startPos, buffer, 0, len - startPos);
            len = len - startPos;
    
            while (true)
            {
                var endPos = IndexOf(buffer, len, boundaryBytes);
                if (endPos >= 0)
                {
                    if (endPos > 0) output.Write(buffer, 0, endPos - 2);
                    break;
                }
                else if (len <= boundaryLen)
                {
                    throw new Exception("End Boundaray Not Found");
                }
                else
                {
                    output.Write(buffer, 0, len - boundaryLen);
                    Array.Copy(buffer, len - boundaryLen, buffer, 0, boundaryLen);
                    len = input.Read(buffer, boundaryLen, 1024 - boundaryLen) + boundaryLen;
                }
            }
        }
    }
    
    public Int32 IndexOf(Byte[] buffer, Int32 len, Byte[] boundaryBytes)
    {
        for (var i = 0; i <= len - boundaryBytes.Length; i++)
        {
            var match = true;
            for (Int32 j = 0; j < boundaryBytes.Length && match; j++)
            {
                match = buffer[i + j] == boundaryBytes[j];
            }
    
            if (match)
            {
                return i;
            }
        }
    
        return -1;
    }
    

    下面是一个(缩短的)XML文件的示例

    <?xml version="1.0" encoding="UTF-8"?>
    <MonitorSettings>
      <Interval>30000</Interval>
      <QueuCheck>False</QueuCheck>
      <MailAlert>False</MailAlert>
      <WindowsServices>mongodb</WindowsServices>
    </MonitorSettings>
    

    到目前为止,我拥有的Windows服务代码能够接收来自Webapplication的请求,但由于len==0时引发的异常,它没有保存XML文件。我有没有做错什么?有更好的方法做事情吗?有什么好的StackOverflow线程可以帮助您吗?

    更准确地说,在函数中这里提出了异常 保存文件()

    if (len == 0)
    {
        throw new Exception("Start Boundaray Not Found");
    }
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Gogoku7    7 年前

    看起来我使用了一种过于复杂的方法,试图将请求主体保存到XML文件中。我做了更多的研究,发现这段代码有效:

        public void SaveFile(HttpListenerContext context)
        {
            // Get the data from the HTTP stream
            var body = new StreamReader(context.Request.InputStream).ReadToEnd();
    
            var xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(body);
            xmlDocument.Save("Settings.xml");
        }