如何使用C#通过HTTP POST调用webservice

21

我想编写一个C#类,用于创建到运行在www.temp.com上的Web服务的连接,向DoSomething方法发送2个字符串参数并获取字符串结果。我不想使用WSDL。由于我知道Web服务的参数,所以我只想进行简单的调用。

我猜在.Net 2中应该有一种简单易行的方法来实现这一点,但我找不到任何例子...


1
这是您的网络服务吗?您能使用JSON或纯XML而不是SOAP来创建RESTful服务吗? - tvanfosson
@tvanfosson 是的,这是我的 Web 服务。我如何使用 JSON 创建 RESTful Web 服务? - Stavros
5个回答

26
如果这个 "webservice" 是一个简单的 HTTP GET 请求,你可以使用 WebRequest
WebRequest request = WebRequest.Create("http://www.temp.com/?param1=x&param2=y");
request.Method="GET";
WebResponse response = request.GetResponse();

从那里您可以查看response.GetResponseStream以获取输出。您可以以同样的方式访问POST服务。

但是,如果这是一个SOAP webservice,情况就不那么简单了。根据webservice的安全性和选项,有时您可以将已经形成的请求用作模板-替换参数值并发送它(使用webrequest),然后手动解析SOAP响应... 但在这种情况下,您需要进行大量额外的工作,最好使用wsdl.exe生成代理。


1
这看起来就是我需要的。我该如何将方法名(DoSomething)添加到此调用中? - Stavros
好,经过一些尝试,我成功找到了所需的额外材料来使用Post。谢谢! - Stavros
如果我想向我调用的 Web 服务提交一些附加数据,我该怎么做? - Madhav
Stavros - 也许你可以在这里发布“额外所需的东西”?这将有助于并增加答案的价值。 - Baruch Atta

12

我建议你考虑使用ASP.NET MVC来创建你的Web服务。你可以通过标准表单参数提供参数,并将结果作为JSON返回。

[HttpPost]
public ActionResult MyPostAction( string foo, string bar )
{
     ...
     return Json( new { Value = "baz" } );
}
在您的客户端中,使用HttpWebRequest。
var request = WebRequest.Create( "/controller/mypostaction" );
request.Method = "POST";
var data = string.Format( "foo={0}&bar={1}", foo, bar );
using (var writer = new StreamWriter( request.GetRequestStream() ))
{
    writer.WriteLine( data );
}
var response = request.GetResponse();
var serializer = new DataContractJsonSerializer(typeof(PostActionResult));
var result = serializer.ReadObject( response.GetResponseStream() )
                 as PostActionResult;

你所拥有的位置

public class PostActionResult
{
     public string Value { get; set; }
}

谢谢提供的信息,但我已经在没有Json的情况下实现了它。下次我会尝试一下。 - Stavros
DataContractJsonSerializer在Visual Studio中未被识别,可能需要使用using语句? - Windgate

4

另一种调用POST方法的方式是,我曾在WebAPI中使用过。

            WebClient wc = new WebClient();

            string result;
            wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
            result = wc.UploadString("http://localhost:23369/MyController/PostMethodName/Param 1/Param 2","");

            Response.Write(result);

1
您可以使用Newtonsoft.Json返回List对象:
WebClient wc = new WebClient();
  string result;
  wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
  var data = string.Format("Value1={0}&Value2={1}&Value3={2}", "param1", "param2", "param3");
  result = wc.UploadString("http:your_services", data);
  var ser = new JavaScriptSerializer();
  var people = ser.Deserialize<object_your[]>(result);

1
这是一个静态方法,可以在没有凭据的情况下调用任何服务。
    /// <summary>
    ///     Connect to service without credentials
    /// </summary>
    /// <param name="url">string url</param>
    /// <param name="requestType">type of request</param>
    /// <param name="objectResult">expected success object result</param>
    /// <param name="objectErrorResult">expected error object result</param>
    /// <param name="objectErrorResultDescription">expected error object description</param>
    /// <param name="body">request body</param>
    /// <param name="bodyType">type of body</param>
    /// <param name="parameters">parameters of request</param>
    /// <returns></returns>
    public static object ConnectToService(string url, string model, RequestType requestType, string objectResult, string objectErrorResult,
                                                      string objectErrorResultDescription, string body = null, string bodyType = null,
                                                      string parameters = null)
    {
        try
        {
            HttpClient client = new HttpClient();
            string tokenEndpoint = url;
            StringContent stringContent;
            string result = string.Empty;

            switch (requestType)
            {
                case RequestType.Get:
                    {
                        var returnRequest = client.GetAsync(tokenEndpoint).Result;
                        result = returnRequest.Content.ReadAsStringAsync().Result;

                        break;
                    }
                case RequestType.Post:
                    {
                        stringContent = new StringContent(body, Encoding.UTF8, bodyType);

                        var returnRequest = client.PostAsync(tokenEndpoint, stringContent).Result;
                        result = returnRequest.Content.ReadAsStringAsync().Result;

                        break;
                    }
                case RequestType.Put:
                    {
                        stringContent = new StringContent(body, Encoding.UTF8, bodyType);

                        var returnRequest = client.PutAsync(tokenEndpoint, stringContent).Result;
                        result = returnRequest.Content.ReadAsStringAsync().Result;

                        break;
                    }
                case RequestType.Delete:
                    {
                        var returnRequest = client.DeleteAsync(tokenEndpoint).Result;
                        result = returnRequest.Content.ReadAsStringAsync().Result;

                        break;
                    }
                default:
                    break;
            }

            JObject jobject = !string.IsNullOrEmpty(result) ? JObject.Parse(result) : null;
            var obj = jobject != null ? (jobject[objectResult]?.ToList()?.Count > 0 ? jobject[objectResult]?.ToList() : null) : null;

            return (obj == null && jobject?.ToString() == null && jobject[objectResult]?.ToString() == null) ? throw new Exception(($"{jobject[objectErrorResult]?.ToString()} - {jobject[objectErrorResultDescription]?.ToString()}") ?? (new { Error = new { Code = 400, Message = $"{model} - Requisição inválida." } }).ToString()) : (obj ?? (object)jobject[objectResult]?.ToString()) == null ? jobject : (obj ?? (object)jobject[objectResult]?.ToString());
        }
        catch (NullReferenceException)
        {
            return null;
        }
        catch (Exception e)
        {
            throw new Exception($"{model} - Requisição inválida. Detalhes: {e.Message ?? e.InnerException.Message}");
        }
    }

这是一个使用凭证调用任何服务的静态方法。
    /// <summary>
    ///     Connect to service with credentials
    /// </summary>
    /// <param name="url">string url</param>
    /// <param name="requestType">type of request</param>
    /// <param name="handler">credentials</param>
    /// <param name="objectResult">expected success object result</param>
    /// <param name="objectErrorResult">expected error object result</param>
    /// <param name="objectErrorResultDescription">expected error object description</param>
    /// <param name="body">request body</param>
    /// <param name="bodyType">type of body</param>
    /// <param name="parameters">parameters of request</param>
    /// <returns></returns>
    public static object ConnectToService(string url, string model, RequestType requestType, HttpClientHandler handler, string objectResult, string objectErrorResult,
                                                      string objectErrorResultDescription, string body = null, string bodyType = null,
                                                      string parameters = null)
    {
        try
        {
            HttpClient client = new HttpClient(handler);
            string tokenEndpoint = url;
            StringContent stringContent;
            string result = string.Empty;

            switch (requestType)
            {
                case RequestType.Get:
                    {
                        var returnRequest = client.GetAsync(tokenEndpoint).Result;
                        result = returnRequest.Content.ReadAsStringAsync().Result;

                        break;
                    }
                case RequestType.Post:
                    {
                        stringContent = new StringContent(body, Encoding.UTF8, bodyType);

                        var returnRequest = client.PostAsync(tokenEndpoint, stringContent).Result;
                        result = returnRequest.Content.ReadAsStringAsync().Result;

                        break;
                    }
                case RequestType.Put:
                    {
                        stringContent = new StringContent(body, Encoding.UTF8, bodyType);

                        var returnRequest = client.PutAsync(tokenEndpoint, stringContent).Result;
                        result = returnRequest.Content.ReadAsStringAsync().Result;

                        break;
                    }
                case RequestType.Delete:
                    {
                        var returnRequest = client.DeleteAsync(tokenEndpoint).Result;
                        result = returnRequest.Content.ReadAsStringAsync().Result;

                        break;
                    }
                default:
                    break;
            }

            JObject jobject = !string.IsNullOrEmpty(result) ? JObject.Parse(result) : null;
            var obj = jobject != null ? (jobject[objectResult]?.ToList()?.Count > 0 ? jobject[objectResult]?.ToList() : null) : null;

            return (obj == null && jobject?.ToString() == null && jobject[objectResult]?.ToString() == null) ? throw new Exception(($"{jobject[objectErrorResult]?.ToString()} - {jobject[objectErrorResultDescription]?.ToString()}") ?? (new { Error = new { Code = 400, Message = $"{model} - Requisição inválida." } }).ToString()) : (obj ?? (object)jobject[objectResult]?.ToString()) == null ? jobject : (obj ?? (object)jobject[objectResult]?.ToString());
        }
        catch (NullReferenceException)
        {
            return null;
        }
        catch (Exception e)
        {
            throw new Exception($"{model} - Invalid request. {e.Message.Split(',')[0] ?? e.InnerException.Message.Split(',')[0]}");
        }
    }

1
调用Web服务SOAP? - Kiquenet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接