具有多个部件的HttpWebResponse

时间:2014-09-18 21:52:57

标签: c# .net httpwebresponse

我们有一台服务器,我们可以使用网络服务查询照片。维护服务器的人是Java开发人员,但我需要能够使用dotNET查询服务器,因为我使用SDK与我们正在运行的现有应用程序集成,她不愿意/无法协助DOTNET。

这是我对照片的要求(请注意所需的证书): -

private WebResponse Request()
{
    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(Validate);
    X509Certificate certificate = X509Certificate.CreateFromCertFile("wmbuat.crt");

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(server.Text);
    request.Headers.Add("SOAP:Action");
    request.ContentType = "text/xml";
    request.Accept = "text/xml";
    request.Method = "POST";
    request.ClientCertificates.Add(certificate);

    GetXml().Save(request.GetRequestStream());
    return request.GetResponse();
}

private static Boolean Validate(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
    return true;
}

我可以查询服务器没有戏剧,但是HttpWebResponse在一个流中包含两个部分 - 一个包含照片信息的XML部分,以及一个JPEG的二进制部分。例如: -

--WMBMIME2Boundaryurn_uuid_C123
Content-Type: text/xml; charset=utf-8
Content-Transfer-Encoding: binary
Content-ID: <0.urn:uuid:C123@ibm.com>

<NS1:Envelope xmlns:NS1="http://schemas.xmlsoap.org/soap/envelope/">...</NS1:Envelope>
--WMBMIME2Boundaryurn_uuid_C123
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <987>

yoya..JFIF...

我在这里看到了几个与此有关的问题,但我似乎无法使用这些库的证书。是否只有一种方法来包装输出流以将部件作为单独的对象?我很高兴它只是String和byte [],我可以将它转换为XML和Image。

我尝试使用StreamReader并读取第二个空白行,这是二进制数据开始的位置,然后从原始Stream读取剩余部分到文件,但这不起作用: - /

非常感谢任何帮助。

感谢。

2 个答案:

答案 0 :(得分:0)

您正在使用的客户端,请求和响应类来自System.Net命名空间,它比System.Net.Http命名空间中的一些较新的类抽象少了一些。像任何新东西一样,文档和示例都较少,但在这种特殊情况下,我认为使用“Microsoft WebAPI框架”附带的客户端类将使您受益。

具体来说,WebAPI框架中的响应类称为HttpResponseMessage,它具有属性

HttpResponseMessage response = ...
HttpContent content = response.Content;
if(content is MultipartContent)
{
    // loop through parts
}

您可以在此处找到有关此不同命名空间的更多文档:

http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client

旧版.NET可能存在一个交易破坏者。我相信WebAPI 2需要最新最好的版本4.5,但你可能会发现版本4.我没有使用过以前的版本,但我想他们将它分成多个内容部分所做的解析是非微不足道的。

答案 1 :(得分:0)

对于那些试图完成类似事情的人来说,我已经为这个概念验证做了一些解决方法。它不是最有效的代码,但它可以在短期内完成工作,同时我会在其他所有事情之间进行改进: - )

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

namespace COPS_Photo_Viewer
{
    public partial class CPV : Form
    {
        public CPV()
        {
            InitializeComponent();

            textIP.Text = Dns.GetHostAddresses(Dns.GetHostName())[0].MapToIPv4().ToString();
            textID.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            textMachine.Text = Dns.GetHostName();
            textApplication.Text = Application.ProductName;
        }

        private Image ExtractImage(byte[] binary)
        {
            int start = 0;
            for (; start < binary.Length; ++start)
                if (((char)binary[start]) == 'ÿ')
                    break;

            byte[] image = new byte[binary.Length - start];
            for (int index = start; index < binary.Length; ++index)
                image[index - start] = binary[index];

            return Bitmap.FromStream(new MemoryStream(image));
        }

        private void GetImage(Object sender, EventArgs args)
        {
            WebResponse response = Request();
            byte[] input = ReadStream(response.GetResponseStream());
            photograph.Image = ExtractImage(input);
        }

        private XmlDocument GetXml()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(...);
            return xml;
        }

        private byte[] ReadStream(Stream stream)
        {
            Queue<byte> input = new Queue<byte>();
            byte[] buffer = new byte[1];

            for (int read = stream.ReadByte(); read >= 0; read = stream.ReadByte())
                input.Enqueue((byte)read);

            return input.ToArray<byte>();
        }

        private WebResponse Request()
        {
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(Validate);
            System.Security.Cryptography.X509Certificates.X509Certificate certificate =
            System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile("wmbuat.crt");

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(textURL.Text);
            request.Headers.Add("SOAP:Action");
            request.ContentType = "text/xml";
            request.Accept = "text/xml";
            request.Method = "POST";
            request.ClientCertificates.Add(certificate);

            GetXml().Save(request.GetRequestStream());
            return request.GetResponse();
        }

        private static Boolean Validate(Object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors errors)
        {
            return true;
        }
    }
}

当按下表单上的按钮时,最初会运行GetImage。一旦有结果,它将响应流转换为字节数组,然后搜索“ÿ”的第一个实例(在我们的情况下它只会出现在JPEG的开头),然后转为剩下的将数组转换为MemoryStream,然后将其转换为图像。

显然,一次将一个字节读入队列并不是最好的,但幸运的是,这是通过网络运行的(至少在初始开发阶段),这不是问题,照片仍会立即加载。 / p>

相关问题