Я пытаюсь получить доступ к старому веб-сервису ASMX с помощью WCF, вызвав метод ChannelFactory.CreateChannel()
.
Если веб-сервис создан WCF, все просто. Я могу создать экземпляр прокси-клиента, сгенерированного инструментом svcutil, или вручную вызвать метод ChannelFactory.CreateChannel()
. После этого я могу вызывать методы веб-службы одинаково для обоих сценариев.
Но если веб-служба имеет старую разновидность ASMX, я все равно могу создать экземпляр прокси, но я не могу вызвать тот же метод веб-службы.
Например, предположим, что этот базовый интерфейс веб-службы WCF:
[ServiceContract]
public interface IWebService
{
[OperationContract]
string HelloWorld();
}
После использования svcutil
для генерации прокси я могу позвонить HelloWorld()
одним из 2 способов:
WebServiceClient proxy = new ServiceReference.WebServiceClient();
textBox1.Text += proxy.HelloWorld();
или
ChannelFactory<ServiceReference.IWebService2> cfactory =
new ChannelFactory<ServiceReference.IWebService>("BasicHttpBinding_IWebService");
ServiceReference.IWebService proxy = cfactory.CreateChannel();
((IClientChannel)proxy).Open();
textBox1.Text += proxy.HelloWorld();
Теперь предположим, что этот веб-сервис ASMX:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
public WebService() { }
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
Вызов HelloWorld()
с использованием SoapClient
, созданного инструментом svcutil
, почти такой же, как если бы это был веб-сервис WCF:
WebServiceSoapClient proxy = new ServiceReference.WebServiceSoapClient();
textBox1.Text += proxy.HelloWorld();
Но пытаясь позвонить HelloWorld()
, если вы создадите канал самостоятельно, и вы получите ошибку:
ChannelFactory<ServiceReference.WebServiceSoap> cfactory =
new ChannelFactory<ServiceReference.WebServiceSoap>("WebServiceSoap");
ServiceReference.WebServiceSoap proxy = cfactory.CreateChannel();
((IClientChannel)proxy).Open();
textBox1.Text += proxy.HelloWorld();
Ошибка «Нет перегрузки для метода HelloWorld, принимающего 0 аргументов».
Кажется, это потому, что метод HelloWorld
в автоматически сгенерированном интерфейсе (ServiceReference.WebServiceSoap)
принимает аргумент типа ServiceReference.HelloWorldRequest
.
Таким образом, в итоге я смог заставить его работать, только просмотрев сгенерированный код svcutil
и изменив мою реализацию на следующее:
ChannelFactory<ServiceReference.WebServiceSoap> cfactory =
new ChannelFactory<ServiceReference.WebServiceSoap>("WebServiceSoap");
ServiceReference.WebServiceSoap proxy = cfactory.CreateChannel();
((IClientChannel)proxy).Open();
ServiceReference.HelloWorldRequest inValue =
new WCFConsumeWebServices.ServiceReference.HelloWorldRequest();
inValue.Body = new WCFConsumeWebServices.ServiceReference.HelloWorldRequestBody();
ServiceReference.HelloWorldResponse retVal = proxy.HelloWorld(inValue);
textBox1.Text += retVal.Body.HelloWorldResult;
Это так и должно быть?
Для одного типа базового http веб-сервиса мы используем практически один и тот же код для вызова метода, но для другого нам нужно перебрать сгенерированный прокси-код и реализовать его в зависимости от того, как вы открываете канал?