The simplest way to invoke a service is to add a service reference directly to VS and enter the address of the service, whether it be a normal Web service or a WCF service. VS will automatically generate client code based on the metadata obtained.
If the service has a large number of calls, it can be used on IIS as a Web resource. However, WCF is not limited to this, it can run in a process, or it can be put on the Windows service process, but it is a universal communication technology for the Windows platform.
In order to be forced, today's old week will demonstrate how to invoke WCF manually, which can be called only through channel (channels). In fact, at some point, manual also has the advantage of manual, manually call, the code is not much, also more flexible.
Of course, this demo is for reference only.
In order to successfully complete the demonstration, the first need to get a service example, used to do a service to perform subtraction to test, today, since to install force, just pretend to have a creative point, to a calculation of the N-square, such as 2 of the 3 square is 8.
I do not know whether you remember the steps to establish a WCF, so small program, do not have IIS to run, directly with a console application can be, simple and elegant and elegant level.
The first thing to declare is the service contract.
[ServiceContract (Name ="Pow_service", Namespace ="http://my")] InterfaceIService {[OperationContract (Name="POW", Action ="powaction", replyaction ="powreply")] DoublePow (DoubleXDoubley); }
The contract is just an interface that is implemented on the server side, but the client does not need to know the code that implements the interface, as long as the client also defines one such interface. Of course, if you do not want to repeat the definition of the contract, you can define this interface to a shared class library, preferably with a portable library, so that the platform is omnipotent.
The advantage of defining the contract interfaces separately in the server and client is that there is no need to be consistent on both sides, the interface name and interface methods can be different, and the parameter names can be different, as long as the order, type, quantity, and return value of the parameter are the same type.
The focus is on the servicecontractattribute attached to the interface, and the OperationContractAttribute feature attached to the method. The interface names of the server and client can be different, as long as the attribute values of the attached attributes are the same.
So, in the Win10 app client, I can declare this interface myself:
[ServiceContract (Name ="Pow_service", Namespace ="http://my")] InterfaceIpowservice {[OperationContract (Name="POW", Action ="powaction", replyaction ="powreply")] Task<Double> Powasync (DoubleXDoubley); }
You might as well see that the interface name differs from the interface member name, but the contract attribute of the callout is the same. The so-called contract, that is, the server and the client must have a little "tacit understanding", the Protocol interface is a specification, otherwise, the client does not know what operation methods of the service, it can not be called.
After the completion of the contract, the server side to implement the contract interface, to do specific operations.
class Powservice:iservice { publicdouble Pow (doubledouble y) { Double res = Math.pow (x, y); return res; } }
WCF that is hosted on the process is better handled without too complex configuration, and a few lines of code can start the service host.
using(ServiceHost host =NewServiceHost (typeof(Powservice))) {NetTcpBinding binding=Newnettcpbinding (Securitymode.none); //Add endpoints directlyHost. AddServiceEndpoint (typeof(IService), binding,"Net.tcp://localhost:1700/pow"); Host. Opened+ = (h, ea) = Console.WriteLine ("The service is open. "); //Open Service Try{host.} Open (); } Catch(Exception ex) {Console.WriteLine (ex). Message); } console.readkey (); }
Actually very easy,servicehost responsible for running the service, can be interpreted as a service host. Because the service is accessed manually, the base address can be omitted. Then you directly add the service contract as an endpoint to the service host as appropriate. When you add an endpoint, you need to specify the type of the contract, a binding, and, of course, the address.
Here I use the TCP protocol to communicate, with the NetTcpBinding class, NET TCP address to "NET.TCP:" Start.
After that, the service can be run directly by open.
Note that this service can only be called manually and cannot generate code with a service reference because the metadata is not exposed and the WSDL is not found when the code is generated.
=========================================================
It can then be called directly in the Windows app client.
//End point AddressEndpointAddress EP =NewEndpointAddress ("Net.tcp://localhost:1700/pow"); //TCP BindingsNetTcpBinding binding =Newnettcpbinding (Securitymode.none); //Create a channelChannelfactory<wcfsvcontracts.ipowservice> factory =NewChannelfactory<wcfsvcontracts.ipowservice>(binding, EP); Wcfsvcontracts.ipowservice Channel=Factory. CreateChannel (); //Invoke Service Doublex =Double. Parse (txt1. Text); Doubley =Double. Parse (txt2. Text); DoubleR =awaitChannel. Powasync (x, y); Tbres. Text= $"calculation result: {r:g}";
Wcfsvcontracts.ipowservice is a service contract that is redefined on the client, but the characteristics of the contract are the same as the service, and the interface name can be different. This has been posted on the code, I will post a complete.
usingSystem;usingSystem.ServiceModel;usingSystem.Threading.Tasks;namespacewcfsvcontracts{[ServiceContract (Name="Pow_service", Namespace ="http://my")] InterfaceIpowservice {[OperationContract (Name="POW", Action ="powaction", replyaction ="powreply")] Task<Double> Powasync (DoubleXDoubley); }}
Somewhat different from the definition on the server, in the client, I declare the action method to support asynchronous wait, that is, return TASK<TRESULT>, this is allowed, you do not have to doubt.
You will see that calling on the client is also quite simple, first using a endpointaddress to represent the address of the endpoint, which must match the address of the endpoint added on the server, or the service cannot be found.
Then instantiate a NetTcpBinding object, and the type of the binding and the attribute value must match the binding on the server. The security mode of nettcpbinding on the server is set to none, and the client is set to none. Because it is not a dirty data, disable Safe mode.
Finally, a channelfactory<tchannel> is used to complete the service invocation. The type of TChannel is the contract interface, and as the CreateChannel method is called, the channel it creates is returned based on the contract interface, and the actual type it returns is a dynamic type, but it can be invoked on a contract interface basis.
The results of the operation are as follows.
Sample code Download
"Win 10 app development" calls WCF services manually