如何使用C#调用远程iis上托管的wcf服务
如何使用C#调用远程iis上托管的wcf服务而不添加引用
服务我尝试此代码但它返回null
How to call wcf service hosted on remote iis using C# without add reference
of service i try this code but it return null
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
namespace Test
{
[System.Web.Services.WebServiceBindingAttribute(Name = "MyWebService", Namespace = "http://microsoft.com/webservices/")]
public class SoapProtocol : SoapHttpClientProtocol
{
public SoapProtocol():base()
{
this.Url = "http://localhost:8080/WebService.asmx"; //"http://localhost/wcf/WebService.asmx";
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
// [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/HelloWorld", RequestNamespace = "http://tempuri.org", ResponseNamespace = "http://tempuri.org", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[SoapDocumentMethod("http://tempuri.org/HelloWorld", ResponseElementName = "HelloWorldResponse", RequestNamespace = "http://tempuri.org/", ResponseNamespace = "http://schemas.xmlsoap.org/soap/envelope/",Use=System.Web.Services.Description.SoapBindingUse.Literal,ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
// [return:XmlArray("string",Namespace="",IsNullable = false)]
public object[] HelloWorld(ref string data)
{
var res = this.Invoke("HelloWorld", new object[]{});
int g;
System.Windows.Forms.MessageBox.Show(res[0].ToString());
return res;
}
}
}
/////////// soap request
POST /WebService.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/HelloWorld"
<?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>
<HelloWorld xmlns="http://tempuri.org/" />
</soap:Body>
</soap:Envelope>
///////////// soap response
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?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>
<HelloWorldResponse xmlns="http://tempuri.org/">
<HelloWorldResult>string</HelloWorldResult>
</HelloWorldResponse>
</soap:Body>
</soap:Envelope>
您好Mahmoud_Gamal
如果您不想添加服务引用(为什么?),您可以通过自己管理每个服务的WcfProxy和通信通道来解决此问题。但是你必须知道这个解决方案的服务合同(意味着你可以参考定义合同的程序集) - 我不知道你是否可以这样做......
来自我的代码库的示例:( IService只是我所有服务的基本接口,可以将它们识别为服务,它什么都不实现)
Hi Mahmoud_Gamal
If you don't want to add a service reference (why?) you could solve this by managing a WcfProxy and a communication channel for each Service by yourself. But you will have to "know" the service contract with this solution (means you can reference the assembly where the contract is defined) - I don't know if this is possible for you...
Example from my codebase: (IService is just a base interface for all my Services to identify them as service, it implements nothing)
public interface ICommandDispatcher
{
TResult ExecuteCommand<TService, TResult>(Func<TService, TResult> command)
where TResult : class
where TService : class, IService;
}
可能的实现方式如下:
A possible implementation could look like this:
public class WcfCommandDispatcher : ICommandDispatcher
{
class WcfProxy<TService> : ClientBase<TService>
where TService : class, IService
{
public TService WcfChannel
{
get { return Channel; }
}
}
public TResult ExecuteCommand<TService, TResult>(Func<TService, TResult> command)
where TResult : class
where TService : class, IService
{
WcfProxy<TService> proxy = new WcfProxy<TService>();
try
{
TResult result = command.Invoke(proxy.WcfChannel);
proxy.InnerChannel.Close();
return result;
}
catch (Exception)
{
proxy.Abort();
throw;
}
}
}
有了这个助手,您可以通过拨打任何服务知道这是合同。
来自我的代码库的示例,我从 ICultureService
获取了一些文化列表
With this helper in place you can call any service by "knowing" it's contract.
Example from my codebase where I get some list of "Cultures" from my ICultureService
WcfCommandDispatcher dispatcher = new WcfCommandDispatcher();
IEnumerable<Culture> cultures = dispatcher.ExecuteCommand<ICultureService, IEnumerable<Culture>>(s =>
{
return s.GetAll();
}
所以你看,你可以在ExecuteCommand函数中使用该服务并且可以做无论你想要什么。不要忘记添加对System.ServiceModel和Service-Contract程序集的引用。以与服务引用相同的方式配置你的服务。(App.config)
我希望这会有所帮助。
亲切的问候
Johannes
So you see, you can just use the service inside the ExecuteCommand function and can do whatever you want. Don't Forget to add a reference to System.ServiceModel and your Service-Contract assembly. Configure your service in the same way you would do with a service reference. (App.config)
I hope this helps.
Kind regards
Johannes