【问题标题】:How to use HttpWebRequest to call a Web Service Operation that takes in a byte[] parameter?如何使用 HttpWebRequest 调用接受 byte[] 参数的 Web 服务操作?
【发布时间】:2009-04-01 02:47:18
【问题描述】:

我正在尝试从 C# 调用 [webmethod]。我可以调用接受“字符串”参数的简单网络方法。但是我有一个接受“byte []”参数的网络方法。当我尝试调用它时,我遇到了“500 内部服务器错误”。这是我正在做的一些示例。

假设我的方法是这样的

[WebMethod]
public string TestMethod(string a)
{
    return a;
}

我在 C# 中使用 HttpRequest 这样称呼它

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Credentials = CredentialCache.DefaultCredentials;
            req.Method = "POST";
            // Set the content type of the data being posted.
            req.ContentType = "application/x-www-form-urlencoded";

            string inputData = "sample webservice";
            string postData = "a=" + inputData;
            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] byte1 = encoding.GetBytes(postData);

            using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
            {
                StreamReader sr = new StreamReader(res.GetResponseStream());
                string txtOutput = sr.ReadToEnd();
                Console.WriteLine(sr.ReadToEnd());
            }

这工作得很好。现在我有另一个这样定义的网络方法

[WebMethod]
public string UploadFile(byte[] data)

我试着这样称呼它

            ASCIIEncoding encoding = new ASCIIEncoding();
            string postData = "data=abc";
            byte[] sendBytes = encoding.GetBytes(postData);
            req.ContentLength = sendBytes.Length;
            Stream newStream = req.GetRequestStream();
            newStream.Write(sendBytes, 0, sendBytes.Length);

但这给了我一个 500 内部错误:(

【问题讨论】:

    标签: .net web-services httpwebrequest asmx


    【解决方案1】:

    有可能,我自己做过

    首先是Header设置,如果你的webservice可以通过web执行并发送参数,就可以获得这个。我使用 Chrome 的开发者工具。简单的方法是查看 Web 服务的描述(即 http://myweb.com/WS/MyWS.asmx?op=Validation)

    WebRequest request = WebRequest.Create(http://myweb.com/WS/MyWS.asmx?op=Validation);
    request.Method = "POST";
    ((HttpWebRequest)request).UserAgent = ".NET Framework Example Client";
    request.ContentType = "text/xml; charset=utf-8";
    ((HttpWebRequest)request).Referer = "http://myweb.com/WS/MyWS.asmx?op=Validation";
    ((HttpWebRequest)request).Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
    ((HttpWebRequest)request).Host= "myweb.com";
     request.Headers.Add("SOAPAction","http://myweb.com/WS/Validation");
    

    然后是请求部分

    string message = "a=2";
    string envelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
            "<soap:Body><Validation xmlns=\"http://myweb.com/WS\"><data>@Data</data></Validation></soap:Body></soap:Envelope>";
    string SOAPmessage = envelope.Replace("@Data",   System.Web.HttpUtility.HtmlEncode(message));
    // The message must be converted to bytes, so it can be sent by the request
    byte[] data = Encoding.UTF8.GetBytes(SOAPmessage);
    request.ContentLength = data.Length;
    request.Timeout = 20000;
    Stream dataStream = request.GetRequestStream();
    dataStream.Write(data, 0, data.Length);
    dataStream.Close();
    WebResponse response = request.GetResponse();
    Stream inputStream = response.GetResponseStream(); 
    

    现在您可以从响应中获取传入流

    请记住根据来自 web 服务的页面详细信息(即 http://myweb.com/WS/MyWS.asmx?op=Validation)给出的描述来调整 SOAP 信封和要发送的参数。

    【讨论】:

      【解决方案2】:

      您正在使用 ASP.NET Web 服务管道的 HTTP POST/HTTP GET 功能,而不是发送实际的 Web 服务调用。这是一种允许您测试简单 Web 服务的机制,但它并不是真正为在生产应用程序中使用而设计的。事实上,如果您导航到 Web 服务 URL,您会发现它甚至无法显示该类型参数的测试输入表单。或许可以找到一种诱骗它工作的方法,但老实说,您应该按照预期的方式使用它并生成 Web 服务代理。

      在 Visual Studio 中,右键单击包含客户端代码的项目并选择添加服务或 Web 引用。然后输入 Web 服务的 URL,它将生成一个代理。如果你使用的是 WCF,它看起来像这样:

      // ServiceNameClient is just a sample name, the actual name of your client will vary.
      string data = "abc";
      byte[] dataAsBytes = Encoding.UTF8.GetBytes(data);
      ServiceNameClient client = new ServiceNameClient();
      client.UploadFile(dataAsBytes);
      

      希望这会有所帮助。

      【讨论】:

      • 假设我使用的是 C++ 和 HttpOpenRequest.. 那我该怎么做呢?
      • 我不确定 :)
      • 如果上述代码有效,您可以使用 Fiddler 查看 http 请求是如何构建的,然后使用该信息使您的自定义代码正常工作。
      【解决方案3】:

      您可能需要对二进制数据进行 base64 编码。

      但 500 错误是查看 Windows 事件日志并查看服务器端发生了什么的线索。

      【讨论】:

        【解决方案4】:

        字符串 postData = "data=abc";

        猜你应该将字节数组作为数组传递,而不是 base64 字符串。例如:

        string postData = "data=97&data=98&data=99"; //abc的字节数组是[97,98,99]

        请参考https://www.codeproject.com/Tips/457410/Xml-WebService-Array-Parameters

        【讨论】:

          猜你喜欢
          • 2011-02-28
          • 2011-03-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-12
          • 1970-01-01
          • 2011-07-30
          • 1970-01-01
          相关资源
          最近更新 更多