如何使用 HttpWebRequest 调用接受 byte[] 参数的 Web 服务操作?

发布于 2024-07-15 13:20:08 字数 1616 浏览 5 评论 0原文

我正在尝试从 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

[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 内部错误:(

I am trying to call a [webmethod] from C#. I can call simple webmethod that take in 'string' parameters. But I have a webmethod that takes in a 'byte[]' parameter. I am running into '500 internal server error' when I try to call it. Here is some example of what I am doing.

Lets say my method is like this

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

I call it like this using HttpRequest in C#

            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());
            }

This works perfectly fine. Now I have another webmethod that is defined like this

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

I tried calling it like this

            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);

But that gives me a 500 internal error :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别理我 2024-07-22 13:20:08

有可能,我自己已经完成了

首先是标题设置,如果您的Web服务可以通过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(); 

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

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

it is possible, I have done it myself

First the Header settings, this can be obtained if your webservice can be executed via web and sending the parameters. I use the Developer tools from Chrome. The easy way is to review the description of the webservice (i.e. 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");

Then the request part

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(); 

Now you can get the incoming stream from the response

Remember to adapt the SOAP envelop and the parameters to be sent according to the description given by the page details from the webservice (i.e. http ://myweb.com/WS/MyWS.asmx?op=Validation).

夜灵血窟げ 2024-07-22 13:20:08

您正在使用 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);

希望这会有所帮助。

You are using the HTTP POST/HTTP GET capability of the ASP.NET Web Service plumbing instead of sending an actual web-service call. This is a mechanism that allows you to test simple web services but it isn't really designed for use in a production application. In fact if you navigate to the web-service URL you'll find that it can't even display a test input form for that type of parameter. It might be possible to figure out a way to trick it into working, but to be honest, you should just use it the way it is intended and generate a web service proxy.

Within Visual Studio right mouse click on the project containing the client code and select Add Service or Web Reference. Then type in the URL to the web-service and it will generate a proxy. If you are using WCF it'll look something like this:

// 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);

Hope this helps.

紧拥背影 2024-07-22 13:20:08

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

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

You will probably need to base64 encode the binary data.

But the 500 error is a clue to look in the Windows event log and see what happened on the server side.

简单爱 2024-07-22 13:20:08

字符串 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

string postData = "data=abc";

guess you should pass byte array as array, not a base64 string. for example:

string postData = "data=97&data=98&data=99"; //byte array for abc is [97,98,99]

please refer to https://www.codeproject.com/Tips/457410/Xml-WebService-Array-Parameters

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文