繁体   English   中英

使用XML将HTTP POST请求发送到Web服务并在Windows 8手机的C#中读取响应数据

[英]Sending HTTP POST Request with XML to a web service and reading response data in C# for windows 8 phone

我是Windows 8手机开发的新手。 我想将aync HTTP POST请求发送到在请求正文中带有一些标头和XML的PHP​​ Web服务。

另外,我想阅读PHP Web服务发送回的响应。

请指导我,如何实现上述两个目标。


到目前为止,我一直在尝试以下

// Main begins program execution.
    public static void SendRequest()
    {

        HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("http://mytestserver.com/Test.php");
        webRequest.Method = "POST";
        webRequest.ContentType = "text/xml";
        webRequest.Headers["SOURCE"] = "WinApp";

        var response = await httpRequest(webRequest);           

    }

    public static async Task<string> httpRequest(HttpWebRequest request)
    {
        string received;

        using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)))
        {
            using (var responseStream = response.GetResponseStream())
            {
                using (var sr = new StreamReader(responseStream))
                {

                    received = await sr.ReadToEndAsync();

                    MessageBox.Show(received.ToString());
                }
            }
        }
        return received;
    }

我可以使用上面的代码发送请求。 我只需要知道如何将请求正文中的XML发送到Web服务即可。

对于“设置文件,并接收服务器响应”,我将其用于发送.csv文件:

首先,我初始化一个POST请求:

/// <summary>
///     Initialize the POST HTTP request.
/// </summary>
public void SentPostReport()
{
    string url = "http://MyUrlPerso.com/";
    Uri uri = new Uri(url);
    // Create a boundary for HTTP request.
    Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.ContentType = "multipart/form-data; boundary=" + Boundary;
    request.Method = "POST";
    request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), est);
        allDone.WaitOne();
}

初始化请求后,我发送文件的不同部分(标题+内容+页脚)。

/// <summary>
///     Send a File with initialized request.
/// </summary>
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
    string contentType = "binary";
    string myFileContent = "one;two;three;four;five;"; // CSV content.
    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
    Stream memStream = request.EndGetRequestStream(asynchronousResult);
    byte[] boundarybytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + Boundary + "\r\n");

    memStream.Write(boundarybytes, 0, boundarybytes.Length);

    // Send headers.
    string headerTemplate = "Content-Disposition: form-data; ";
    headerTemplate += "name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: " + contentType + "\r\n\r\n";
    string fileName = "MyFileName.csv";
    string header = string.Format(headerTemplate, "file", fileName);
    byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
    memStream.Write(headerbytes, 0, headerbytes.Length);

    byte[] contentbytes = System.Text.Encoding.UTF8.GetBytes(myFileContent);

    // send the content of the file.
    memStream.Write(contentbytes, 0, contentbytes.Length);

    // Send last boudary of the file ( the footer) for specify post request is finish.
    byte[] boundarybytesend = System.Text.Encoding.UTF8.GetBytes("\r\n--" + Boundary + "--\r\n");
    memStream.Write(boundarybytesend, 0, boundarybytesend.Length);
    memStream.Flush();
    memStream.Close();

    allDone.Set();
    // Start the asynchronous operation to get the response
    request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}

而且,Finnaly,我得到了响应服务器响应,指示文件已转换。

/// <summary>
///     Get the Response server.
/// </summary>
private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

    try
    {
        HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
        Stream streamResponse = response.GetResponseStream();
        StreamReader streamRead = new StreamReader(streamResponse);

        string responseString = streamRead.ReadToEnd(); // this is a response server.

        // Close the stream object
        streamResponse.Close();
        streamRead.Close();

        // Release the HttpWebResponse
        response.Close();
    }
        catch (Exception ex)
        {
            // error.
        }
    }

此示例在Windows Phone 7和Windows Phone 8上运行。这是用于发送.csv内容的。 您可以修改此代码以发送Xml内容。 仅替换

string myFileContent = "one;two;three;four;five;"; // CSV content.
string fileName = "MyFileName.csv";

通过您的XML

string myFileContent = "<xml><xmlnode></xmlnode></xml>"; // XML content.
string fileName = "MyFileName.xml";

如果您要做的只是获取已经生成的XML并将其作为内容添加到现有请求中,那么您将需要能够写入请求流。 我并不特别在意获取请求流的股票模型,因此,我建议使用以下扩展名,使您的生活更轻松一些:

public static class Extensions
{
    public static System.Threading.Tasks.Task<System.IO.Stream> GetRequestStreamAsync(this System.Net.HttpWebRequest wr)
    {
        if (wr.ContentLength < 0)
        {
            throw new InvalidOperationException("The ContentLength property of the HttpWebRequest must first be set to the length of the content to be written to the stream.");
        }

        var tcs = new System.Threading.Tasks.TaskCompletionSource<System.IO.Stream>();

        wr.BeginGetRequestStream((result) =>
        {
            var source = (System.Net.HttpWebRequest)result.AsyncState;

            tcs.TrySetResult(source.EndGetRequestStream(result));

        }, wr);

        return tcs.Task;
    }
}

在这里,增加您的SendRequest方法:

public static void SendRequest(string myXml)
{
    HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("http://mytestserver.com/Test.php");
    webRequest.Method = "POST";
    webRequest.Headers["SOURCE"] = "WinApp";

    // Might not hurt to specify encoding here
    webRequest.ContentType = "text/xml; charset=utf-8";

    // ContentLength must be set before a stream may be acquired
    byte[] content = System.Text.Encoding.UTF8.GetBytes(myXml);
    webRequest.ContentLength = content.Length;

    var reqStream = await webRequest.GetRequestStreamAsync();
    reqStream.Write(content, 0, content.Length);

    var response = await httpRequest(webRequest);
}

如果您要访问的服务是SOAP服务,则可以通过让IDE为您生成客户端类来进一步简化此服务。 有关如何执行操作的更多信息,请参见MSDN文章 但是,如果该服务没有Web服务定义语言(WSDL)文档,则该方法将无法为您提供帮助。

您可以使用Windows Phone 8中的HTTP客户端库,并以与Windows 8相同的方式使用客户端。

首先,从Nuget获取HTTP客户端库 现在,执行POST呼叫

HttpClient client = new HttpClient();
HttpContent httpContent = new StringContent("my content: xml, json or whatever");
httpContent.Headers.Add("name", "value");

HttpResponseMessage response = await client.PostAsync("uri", httpContent);
if (response.IsSuccessStatusCode)
{
    // DO SOMETHING
}

我希望这可以帮助你 :)

我已经以其他方式解决了这个问题。

    class HTTPReqRes
    {
    private static HttpWebRequest webRequest;

    public static void SendRequest()
    {
        webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("https://www.mydomain.com");
        webRequest.Method = "PUT";
        webRequest.ContentType = "text/xml; charset=utf-8";
        webRequest.Headers["Header1"] = "Header1Value";



        String myXml = "<Roottag><info>test</info></Roottag>";

        // Convert the string into a byte array. 
        byte[] byteArray = Encoding.UTF8.GetBytes(myXml);

        webRequest.ContentLength = byteArray.Length;

        // start the asynchronous operation
        webRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), webRequest);                  
        //webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest);
    }

    private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
    {
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

        // End the operation
        Stream postStream = request.EndGetRequestStream(asynchronousResult);

        String myXml = <Roottag><info>test</info></Roottag>";

        // Convert the string into a byte array. 
        byte[] byteArray = Encoding.UTF8.GetBytes(myXml);

        // Write to the request stream.
        postStream.Write(byteArray, 0, byteArray.Length);
        postStream.Close();

        // Start the asynchronous operation to get the response
        request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
    }

    private static void GetResponseCallback(IAsyncResult asynchronousResult)
    {
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

        // End the operation
        HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
        Stream streamResponse = response.GetResponseStream();
        StreamReader streamRead = new StreamReader(streamResponse);
        string responseString = streamRead.ReadToEnd();
        System.Diagnostics.Debug.WriteLine(responseString);
        // Close the stream object
        streamResponse.Close();
        streamRead.Close();

        // Release the HttpWebResponse
        response.Close();
    }
}

这可以完美解决我的问题,在HTTP请求中发送XML,并在响应中从Web服务接收XML。

我建议使用RestSharp库。 您可以在此处找到示例请求。

这就是我用的。 确实很简单,将WindowsPhonePostClient.dll添加到您的引用中(如果不能,请首先尝试通过properties-> unblock取消阻止文件),然后使用以下代码:

private void Post(string YourUsername, string Password)
{
        Dictionary<string, object> parameters = new Dictionary<string, object>();
        parameters.Add("User", YourUsername);
        parameters.Add("Password", Password);
        PostClient proxy = new PostClient(parameters);
        proxy.DownloadStringCompleted += proxy_UploadDownloadStringCompleted;

        proxy.DownloadStringAsync(new Uri("http://mytestserver.com/Test.php",UriKind.Absolute));

} 


private void proxy_UploadDownloadStringCompleted(object sender,WindowsPhonePostClient.DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
        MessageBox.Show(e.Result.ToString());
}     

您需要创建对Web服务wsdl的引用,也可以尝试按此处详细说明手动进行操作: https : //stackoverflow.com/a/1609427/2638872

//The below code worked for me. I receive xml response back. 
private void SendDataUsingHttps()
{                   
     WebRequest req = null;       
     WebResponse rsp = null;
     string fileName = @"C:\Test\WPC\InvoiceXMLs\123File.xml";                  string uri = "https://service.XYZ.com/service/transaction/cxml.asp";
            try
            {
                if ((!string.IsNullOrEmpty(uri)) && (!string.IsNullOrEmpty(fileName)))
                {
                    req = WebRequest.Create(uri);
                    //req.Proxy = WebProxy.GetDefaultProxy(); // Enable if using proxy
                    req.Method = "POST";        // Post method
                    req.ContentType = "text/xml";     // content type
                    // Wrap the request stream with a text-based writer                  
                    StreamWriter writer = new StreamWriter(req.GetRequestStream());
                    // Write the XML text into the stream
                    StreamReader reader = new StreamReader(file);
                    string ret = reader.ReadToEnd();
                    reader.Close();
                    writer.WriteLine(ret);
                    writer.Close();
                    // Send the data to the webserver
                    rsp = req.GetResponse();
                    HttpWebResponse hwrsp = (HttpWebResponse)rsp;
                    Stream streamResponse = hwrsp.GetResponseStream();
                    StreamReader streamRead = new StreamReader(streamResponse);
                    string responseString = streamRead.ReadToEnd();                    
                    rsp.Close();
                }
            }
            catch (WebException webEx) { }
            catch (Exception ex) { }
            finally
            {
                if (req != null) req.GetRequestStream().Close();
                if (rsp != null) rsp.GetResponseStream().Close();
            }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM