【问题标题】:C# webservice unable to use HTTP POST to send bytes to itC# webservice 无法使用 HTTP POST 向其发送字节
【发布时间】:2017-12-11 17:50:06
【问题描述】:

我定义了以下网络服务。

       [WebMethod]
        public String sendBytes(byte[] a)
        {
            return "good";
        }

我可以使用 Webservice 代理类成功调用它。

但是,我无法将带有二进制文件的 HTTP POST 发送到此 Web 方法。 我试过这个:

      try
           {
               HttpWebRequest request = HttpWebRequest.Create(address) as 
               HttpWebRequest;

            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            //request.ContentLength = 0;


            var postData = "xxx";         

            var data = Encoding.UTF8.GetBytes(postData);

            request.ContentLength = data.Length;

            using (var stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }
            var response = (HttpWebResponse)request.GetResponse();
            Console.Write("Sending request\n\n");
            var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
            String x = Console.ReadLine();

我得到了这个

System.NullReferenceException:对象引用未设置为对象的实例。 在 System.Web.Services.Protocols.ValueCollectionParameterReader.Read(NameValueCollection 集合) 在 System.Web.Services.Protocols.HtmlFormParameterReader.Read(HttpRequest 请求) 在 System.Web.Services.Protocols.HttpServerProtocol.ReadParameters() 在 System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

问题是我可以使用这种方法发送字符串,但不能发送二进制数据。 webservice POST 示例中的定义也很奇怪。

http://localhost:50178/WebService1.asmx?op=sendBytes

感谢您对此主题的任何帮助或建议。感谢阅读:)

编辑: 感谢您的快速回复。

我想我已经解决了空异常,我认为它的原因是因为它找不到我发送的值的参数。但是我现在有另一个问题:

System.ArgumentException:无法将 ef 转换为 System.Byte。 参数名称:type ---> System.FormatException:输入字符串的格式不正确。 在 System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) 在 System.Number.ParseInt32(String s,NumberStyles 样式,NumberFormatInfo 信息) 在 System.Byte.Parse(String s, NumberStyles 样式, NumberFormatInfo 信息) 在 System.String.System.IConvertible.ToByte(IFormatProvider 提供程序) 在 System.Convert.ChangeType(对象值,类型转换类型,IFormatProvider 提供程序) 在 System.Web.Services.Protocols.ScalarFormatter.FromString(字符串值,类型类型) --- 内部异常堆栈跟踪结束 --- 在 System.Web.Services.Protocols.ScalarFormatter.FromString(字符串值,类型类型) 在 System.Web.Services.Protocols.ValueCollectionParameterReader.Read(NameValueCollection 集合) 在 System.Web.Services.Protocols.HtmlFormParameterReader.Read(HttpRequest 请求) 在 System.Web.Services.Protocols.HttpServerProtocol.ReadParameters() 在 System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

代码如下:

          try
        {
            HttpWebRequest request = HttpWebRequest.Create(address) as 
           HttpWebRequest;

            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            //request.ContentLength = 0;


            var postData = "a=";         

            var data = Encoding.UTF8.GetBytes(postData);
            byte[] bytedata = new byte[] { 0x65,0x66};
            request.ContentLength = data.Length + bytedata.Length;

            using (var stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
                stream.Write(bytedata, 0, bytedata.Length);
            }
            var response = (HttpWebResponse)request.GetResponse();
            Console.Write("Sending request\n\n");
            var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

编辑 2: 我尝试过 Aaron 的建议,但没有奏效。

这里是修改后的代码:

        try
        {
            HttpWebRequest request = HttpWebRequest.Create(address) as 
          HttpWebRequest;

            request.Method = "POST";
            request.ContentType = "application/octet-stream";

            //request.ContentLength = 0;


            var postData = "a=";         

            var data = Encoding.UTF8.GetBytes(postData);
            byte[] bytedata = new byte[] { 0x65,0x66};
            request.ContentLength = data.Length + bytedata.Length;

            using (var stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
                stream.Write(bytedata, 0, bytedata.Length);
            }
            var response = (HttpWebResponse)request.GetResponse();
            Console.Write("Sending request\n\n");
            var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

出现以下错误:

System.InvalidOperationException:请求格式无效: 应用程序/八位字节流。 在 System.Web.Services.Protocols.HttpServerProtocol.ReadParameters() 在 System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

参考:How can I make a local file as body of an HttpWebRequest?

问题是我尝试更改 url,因为如果问题是数据包没有很好地形成,我会得到同样的错误,但它没有。会不会是我的网络服务在某个地方出错了?

【问题讨论】:

标签: c# asp.net web-services http-post


【解决方案1】:

尝试将request.ContentType 设置为application/octet-stream。此内容类型用于表示请求正文包含任意二进制数据。

请记住,HTTP 是一种基于文本的协议,它在其消息中使用 ASCII 编码。在您的测试数据中,0x65 和 0x66 是“e”和“f”,这就是为什么您得到的异常显示“无法将 ef 转换为 System.Byte”。您尝试发送的字节被编码为 ASCII,因此成为一个字符串,您的端点需要字节。

编辑:

您也可以尝试使用 multipart/form-data 请求。如何使用 C# 执行此操作的示例如下:

https://gist.github.com/bgrins/1789787

参考资料:

Why Http Protocol is designed in a plain text way

Which Mime Type to use for a binary file

【讨论】:

  • 哇!!!可能缺少的另一部分是请求不是多部分/表单数据:stackoverflow.com/questions/16958448/… 我将编辑我的答案以包含此内容。您可能还必须在表单正文中删除“a=”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2015-02-11
  • 2017-06-19
  • 1970-01-01
相关资源
最近更新 更多