中国气象局 Web Service
Endpoint: http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
WSDL: http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
1、.NET Core 客户端 添加服务引用 WebService
项目右键 - 添加 - 连接的服务
配置 WCF Web Service Reference
选择 Microsoft WCF Web Service Reference 提供服务 -> Url 输入WebService地址,例如【http://localhost:8001//WebService.asmx?wsdl】 -> 转到 -> 完成;
客户端调用 Web Service 方法
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Threading.Tasks;
using System.Xml;
namespace Web.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
/// <summary>
///
/// </summary>
/// <returns></returns>
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var binding = new BasicHttpBinding();
var endpoint = new EndpointAddress("http://192.168.1.179:8111/WebService1.asmx");
var channelFactory = new ChannelFactory<ServiceReference1.WebService1Soap>(binding, endpoint);
var serviceClient = channelFactory.CreateChannel();
ServiceReference1.TestRequest request = new ServiceReference1.TestRequest();
ServiceReference1.TestResponse response = null;
Task task = Task.Factory.StartNew(() =>
{
response = serviceClient.TestAsync(request).Result;
});
task.Wait();
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = $"{Summaries[rng.Next(Summaries.Length)]},WebService结果:{response.Body.TestResult}"
})
.ToArray();
}
/// <summary>
/// 异步方法 请求 Web Service
/// </summary>
/// <returns></returns>
[HttpGet("task")]
public async Task<string> GetTask()
{
var binding = new BasicHttpBinding();
var endpoint = new EndpointAddress("http://192.168.1.179:8111/WebService1.asmx");
var channelFactory = new ChannelFactory<ServiceReference1.WebService1Soap>(binding, endpoint);
var serviceClient = channelFactory.CreateChannel();
ServiceReference1.TestRequest request = new ServiceReference1.TestRequest();
ServiceReference1.TestResponse result = await serviceClient.TestAsync(request);
return result.Body.TestResult;
}
/// <summary>
/// Http POST 请求 Web Service
/// </summary>
/// <returns></returns>
[HttpGet("api")]
public IEnumerable<WeatherForecast> GetApi()
{
QDHttpClient client = new QDHttpClient((int)EnumContentType.urlencoded, "http://192.168.1.179:8111/WebService1.asmx/Test", "");
string xml = client.ExecutePost();
XmlDocument resultXml = new XmlDocument();
resultXml.LoadXml(xml);
string json = resultXml.InnerText;
Company company = JsonConvert.DeserializeObject<Company>(json);
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)],
}).ToArray();
}
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
}
public class Company
{
public int code { get; set; }
public string name { get; set; }
}
}
Postman 调用 Web Service【案例1】
POST /WebService1.asmx/Test HTTP/1.1
Host: 192.168.1.179:8111
Content-Type: application/xml
Postman 调用 Web Service【案例2 中国气象局】
POST /WebServices/WeatherWebService.asmx/getSupportCity HTTP/1.1
Host: www.webxml.com.cn
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
byProvinceName=河北
*
一:WebService中的方法是否允许重载?
例如:
[WebMethod]
public string GetName()
{
return "从小就犯困";
}
[WebMethod]
public string GetName(string strValue)
{
return strValue;
}
会报错。
二:为什么WebService中不支持方法的重载?
WebService中不支持方法的重载,这还得从WebService的工作机制中说起,当客户端调用一个WebService的方法时,首先要将方法名称和需要传递的参数包装成XML,也就是SOAP包,通过HTTP协议传递到服务器端,然后服务器端解析这段XML,得到被调用的方法名称和传递过来的参数,进而调用WebService相应的方法,方法执行完毕后,将返回结果再次包装为XML,也就是SOAP响应,发送到客户端,最后客户端解析这段XML,最终得到返回结果,关键在于服务器端解析XML时无法识别重载的方法,WebService只认方法的名称,而且两个方法的名称相同,服务器端不知道该调用哪个相应的方法
三:如何解决WebService中方法的重载?
(1)将类的WebServiceBinding属性中ConformsTo指定为WsiProfiles.None
(2)可以通过MessageName属性消除由于多个相同的名称造成的Web服务无法识别的问题,因为MessageName属性使得Web服务能够确定唯一别名的重载方法,默认时候是方法本身的名称,当指定MessageName属性后,SOAP将反映MessageName的值,而不是方法名称本身,所以这就解决了WebService中不支持方法的重载
代码1:[WebServiceBinding(ConformsTo = WsiProfiles.None)]
代码2:[WebMethod(MessageName="FirstMethod")]
public string GetName()
{
return "从小就犯困";
}
[WebMethod(MessageName="SecondMethod")]
public string GetName(string strValue)
{
return strValue;
}
四、webservice如何直接用DataSet、DataTable、DataRow作为返回类型?
需要在Web.config文件添加序列化转换器的属性,示例代码:
- <system.web.extensions>
- <scripting>
- <webServices>
- <jsonSerialization>
- <converters>
- <add name="DataSetConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataSetConverter, Microsoft.Web.Preview"/>
- <add name="DataRowConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataRowConverter, Microsoft.Web.Preview"/>
- <add name="DataTableConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataTableConverter, Microsoft.Web.Preview"/>
- </converters>
- </jsonSerialization>
- </webServices>
- </scripting>
- </system.web.extensions>