Can be through the code or configuration file hosted WCF service, in the use of some of the experience, record, convenient follow-up review.
Preparation of knowledge, the role of several addresses
1, behavior. Httpgeturl defines the address of the metadata, and if you do not define a base address, you must define Httpgeturl, which is the absolute or relative location of the metadata.
2, baseaddresses the address of the service, because the metadata (metadata) belongs to a host, does not belong to a endpoint. This base address is the address that the client adds the service reference to.
So baseaddress solved where to locate the WCF Service?
If you define endpoint daaress= "", then endpoint daaress equals baseaddresses
3, the endpoint endpoint address, for communication with the client, the server and client endpoint address must be strictly corresponding.
4, in these three addresses if there is no base address defined, the other two addresses Httpgeturl,endpoint address must not be empty
5. If baseaddress is defined, the other two addresses can be empty. At this point endpoint address is the URL defined by baseaddress
If the server endpoint is configured as:
<endpoint address= "Http://127.0.0.1:8882/DBServer" binding= "Wshttpbinding" contract= "Icontract.icontract"/>
That is, the service-side definition address is "http://127.0.0.1:8882/DBServer", then the client endpoint address must also be "http://127.0.0.1:8882/DBServer" to establish communication.
When we host a WCF service, we have to define one or more endpoint for him, and then the service listens for requests from the client through this defined endpoint. When our application needs to call this service, because the client and service are communicating through endpoint, we have to define the client side endpoint for our application. Client requests can be heard by the service side only if the client's endpoint and service side endpoint match (the service side can define multiple endpoint for a service). That is, we can call this service only if the client has a endpoint that exactly matches the service side. And this match is very strict, for example, from the match address aspect, the client side and the service side endpoint address not only on the URI to exactly match the service, their headers also need to match each other. For binding, in general, the client needs to have a binding that is exactly the same as the service side, so that they can communicate with each other.
4, if the base address is defined, then the endpoint address can be set to NULL, so that all endpoint address is the URL defined by the base site
Here is an example of establishing a WCF service and invocation
1. Create a new console project, Add the following assembly reference
Using System.ServiceModel;
Using System.ServiceModel.Web;
2, add Class icontract, just to demonstrate, contract and service are built in a project
Using system;using system.collections.generic;using system.linq;using system.text;using System.ServiceModel;using System.servicemodel.web;namespace IContract//Note: If the namespace is wcfhost, the configuration file is not recognized when the configuration file is hosted, and you do not know why { [ ServiceContract] public interface IContract { [OperationContract] [WebInvoke (UriTemplate = "add/{x }/{y} ")] double Add (double x, double y); } }
3. Add Class Dbservice
Using system;using system.collections.generic;using system.linq;using system.text;namespace DBService // Note: If the namespace is wcfhost, the configuration file is not recognized when the configuration file is hosted, and I do not know why {public class DBService:IContract.IContract {public Double Add (double x, double y) { return x+y;}} }
4, the use of code to configure the service and open the service, three addresses are defined
Using system;using system.collections.generic;using system.linq;using system.text;using System.ServiceModel;using System.servicemodel.web;namespace wcfhost{class Program {static void Main (string[] args) { try {//uri uri = new Uri ("Http://127.0.0.1:8881/DBServer");//And the following sentence equivalent URI Uri = new Uri ("Http://localhost:8881/DBServer"); using (ServiceHost host = new ServiceHost (typeof (Dbservice.dbservice), Uri)) {//define metadata publication method, where the WSDL is advertised by adding "? wsdl" to the URL of the service, which can be accessed directly through HTTP. System.ServiceModel.Description.ServiceMetadataBehavior behavior = new System.ServiceModel.Description.ServiceMetadataBehavior (); Behavior. Httpgetenabled = true; This sentence can also be httpgeturl, which defines the URL behavior of the metadata. Httpgeturl = new Uri ("Http://localhost:8882/DBService"); Host. DESCRIPTION.BEHAVIORS.ADD (behavior); Uri endpointaddress =new uri ("Http://127.0.0.1:8883/DBServer"); Add endpoint host. AddServiceEndpoint (typeof (Icontract.icontract), New Wshttpbinding (), endpointaddress); Defines the endpoint address (which can be empty if baseadress is defined)//host. AddServiceEndpoint (typeof (Icontract.icontract), New Wshttpbinding (), ""); Host. Opened + = host_opened; Host. Open (); Console.ReadLine (); }} catch (Exception e) {throw e; }} static void Host_opened (object sender, EventArgs e) {Console.WriteLine ("Dbservice ope Ned successful "); } }}
5, configure the service with the configuration file and turn on the service, the same 4
5.1 Add configuration file, the configuration file defines three address, base address (service address), metadata addresses, and the client's communication address
<?xml version= "1.0" encoding= "Utf-8"?><configuration> < system.servicemodel> <behaviors> <serviceBehaviors> <behavior name= "Metadatabehavior" > <servicemetadata httpgetenabled= "true" Httpgeturl= "Http://127.0.0.1:8881/DBServer" ></servicemetadata> ; </behavior> </serviceBehaviors> </behaviors> <services> <!--note Here name must be named with the third step service Space consistent--<service behaviorconfiguration= "Metadatabehavior" name= "Dbservice.dbservice" > <endpoint ad dress= "Http://127.0.0.1:8882/DBServer" binding= "Wshttpbinding" contract= "Icontract.icontract"/>
5.2 Open Service
Using system;using system.collections.generic;using system.linq;using system.text;using System.ServiceModel;using System.servicemodel.web;namespace wcfhost{ class program { static void Main (string[] args) { Try { ServiceHost host1 = new ServiceHost (typeof (Dbservice.dbservice)); Host1. Opened + = host_opened; Host1. Open (); Console.ReadLine (); } catch (Exception e) { throw e; } } static void Host_opened (object sender, EventArgs e) { Console.WriteLine ("Dbservice opened successful"); } }}
6, open the service address in the browser: Http://127.0.0.1:8883/DBServer, such as
Open metadata Address: http://127.0.0.1:8881/DBServer, such as
Clients add services, using service addresses or metadata addresses to find services.
and the endpoint address: Http://127.0.0.1:8882/DBServer, unable to open,
7. When the client invokes the service, the definition endpoint address must have the service-defined endpoint address match, as follows
Using system;using system.collections.generic;using system.linq;using system.text;using System.ServiceModel;using System.servicemodel.web;namespace wcfclient{ class program { static void Main (string[] args) { Wshttpbinding binding = new Wshttpbinding (); EndpointAddress address = new EndpointAddress (New Uri ("Http://127.0.0.1:8882/DBServer")); Servicereference1.contractclient client = new Servicereference1.contractclient (binding, address); Double i = client. ADD (1, 2); Console.WriteLine (i); Console.ReadLine ();}}}
8, only define baseaddress, do not define the other two address
8.1 Configuration file Definitions
<?xml version= "1.0" encoding= "Utf-8"?><configuration> <system.serviceModel> < behaviors> <serviceBehaviors> <behavior name= "Metadatabehavior" > <servicemetadata Httpgetenabled= "true"/> </behavior> </serviceBehaviors> </behaviors> < Services> <!--Note here that name must match the namespace of the third step service-- <service behaviorconfiguration= "Metadatabehavior" Name= "Dbservice.dbservice" > <endpoint address= "" binding= "Wshttpbinding" contract= " Icontract.icontract "/>
Open service
ServiceHost host1 = new ServiceHost (typeof (Dbservice.dbservice)); Host1. Opened + = host_opened; Host1. Open (); Console.ReadLine ();
8.2 Code Definition and opening services
Using system;using system.collections.generic;using system.linq;using system.text;using System.ServiceModel;using System.servicemodel.web;namespace wcfhost{class Program {static void Main (string[] args) { try {//uri uri = new Uri ("Http://127.0.0.1:8881/DBServer");//And the following sentence equivalent URI Uri = new Uri ("Http://localhost:8881/DBServer"); using (ServiceHost host = new ServiceHost (typeof (Dbservice.dbservice), Uri)) {//define metadata publication method, where the WSDL is advertised by adding "? wsdl" to the URL of the service, which can be accessed directly through HTTP. System.ServiceModel.Description.ServiceMetadataBehavior behavior = new System.ServiceModel.Description.ServiceMetadataBehavior (); Behavior. Httpgetenabled = true; Host. DESCRIPTION.BEHAVIORS.ADD (behavior); Host. AddServiceEndpoint (typeof (Icontract.icontract), New Wshttpbinding (), ""); Host. Opened+ = host_opened; Host. Open (); Console.ReadLine (); }} catch (Exception e) {throw e; }} static void Host_opened (object sender, EventArgs e) {Console.WriteLine ("Dbservice ope Ned successful "); } }}
8.3 Client, adding a service reference directly will automatically generate the configuration file and then call
<?xml version= "1.0" encoding= "Utf-8"?><configuration> <system.serviceModel> < bindings> <wsHttpBinding> <binding name= "wshttpbinding_icontract"/> </ wshttpbinding> </bindings> <client> <endpoint address= "http://localhost:8881/ DBServer "binding=" Wshttpbinding " bindingconfiguration=" Wshttpbinding_icontract "contract=" Servicereference1.icontract " name=" wshttpbinding_icontract "/> </client> </ System.servicemodel></configuration>
Using system;using system.collections.generic;using system.linq;using system.text;using System.ServiceModel;using System.servicemodel.web;namespace wcfclient{ class program { static void Main (string[] args) { Servicereference1.contractclient client = new Servicereference1.contractclient (); Double i = client. ADD (1, 2); Console.WriteLine (i); Console.ReadLine ();}}}
8.4 can also be called directly from the code without a configuration file
Using system;using system.collections.generic;using system.linq;using system.text;using System.ServiceModel;using System.servicemodel.web;namespace wcfclient{ class program { static void Main (string[] args) { Wshttpbinding binding = new Wshttpbinding (); EndpointAddress address = new EndpointAddress (New Uri ("Http://127.0.0.1:8881/DBServer")); Servicereference1.contractclient client = new Servicereference1.contractclient (binding, address); Client. endpoint.binding = Binding; Double i = client. ADD (1, 2); Console.WriteLine (i); Console.ReadLine ();}}}
9. There are two ways to compare WCF publishing metadata, either way the Servicemetadata node must exist.
Metadata describes the details of the service, and the export and publishing metadata are implemented by ServiceMetadataBehavior in a service.
You must configure the servicemetadata behavior for the service, that is, to configure the node to publish metadata before you can use Httpgetenabled=true or httpgetenabled=false to publish the meta data.
<serviceBehaviors>
<behavior name= "Metadatabehavior" >
<servicemetadata/>
</behavior>
</serviceBehaviors>
9.1 wsdl, this method publishes the WSDL by adding "? wsdl" to the URL of the service, which can be accessed directly through HTTP.
Set httpgetenabled= "True" to publish the metadata (see step 6 above), set to False to not publish the meta data. The following conditions are set to false:
<?xml version= "1.0" encoding= "Utf-8"?><configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name= "Metadatabehavior" > <!--<servicemetadata httpgetenable D= "true"/>--> <!--set to true to advertise metadata, service can be turned on, client can also access service--<servicemetadata httpgetenabled= "false"/& Gt <!--set to False to not advertise metadata, the service can be turned on, but the client cannot access the service-</behavior> </serviceBehaviors> </BEHAVIORS&G T <services> <!--note Here name must match the namespace of the third step service--<service behaviorconfiguration= "Metadatabehavior" name= "Dbservice.dbservice" > <endpoint address= "" binding= "Wshttpbinding" contract= "Icontract.icontract"/> Case set to False:
9.2 MEX: This method is advertised as a general endpoint and supports various protocols: HTTP, TCP, Namedpipe
Note: Metadata content that is exposed as an endpoint cannot be viewed by a browser
Add the MEX endpoint publishing metadata, at which point the httpgetenabled is set to True and false to access the service, but the metadata is published differently.
There is a MEX endpoint, httpgetenabled= "true", at which time the service can be turned on, the client can access the service, and the metadata is published in WSDL mode.
<?xml version= "1.0" encoding= "Utf-8"?><configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name= "Metadatabehavior" > <servicemetadata httpgetenabled= "True "/> <!--set true to be published in WSDL--<!--<servicemetadata httpgetenabled=" false "/>--> <!--setting F Alse, then the MEX release-</behavior> </serviceBehaviors> </behaviors> <services> <!--note here that name must match the namespace of the third step service--<service behaviorconfiguration= "Metadatabehavior" Name= " Dbservice.dbservice "> <endpoint address=" "binding=" Wshttpbinding "contract=" Icontract.icontract "/> <endpoint address= "Mex" binding= "mexHttpBinding" contract= "IMetadataExchange"/>
There is a MEX endpoint, httpgetenabled= "false", at which time the service can be turned on, the client can access the service, and the metadata is published in MEX mode.
<?xml version= "1.0" encoding= "Utf-8"?><configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name= "Metadatabehavior" > <!--<servicemetadata httpgetenable D= "true"/>--> <!--set true to be published in WSDL--<servicemetadata httpgetenabled= "false"/> <!--settings F Alse, then the MEX release-</behavior> </serviceBehaviors> </behaviors> <services> <!--note here that name must match the namespace of the third step service--<service behaviorconfiguration= "Metadatabehavior" Name= " Dbservice.dbservice "> <endpoint address=" "binding=" Wshttpbinding "contract=" Icontract.icontract "/> <endpoint address= "Mex" binding= "mexHttpBinding" contract= "IMetadataExchange"/>
Examples of source code
Reference:My WCF Journey (2): Endpoint OverviewWCF exposes service metadata modeorganize your ideas and explore WCF (ii)2 ways to publish WCF metadata: Httpgetenabled and MexWCF Chapter Fifth Export and publish metadata (service behavior)How to: Publish Metadata for a service by using codeMy WCF Journey Blog Series SummaryWCF Boarding mode code, configuration file