I am using VS2012. My client configuration not updated when I have added service reference of WCF REST service. It is updating if I change binding to 'basicHttpBinding' in a WCF Service. Following is my WCF Service configuration.
<endpoint address="" binding="webHttpBinding" contract="MyService.IService1" behaviorConfiguration="RestBehavior">
<endpointBehaviors>
<behavior name="RestBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
My WCF service is split into following projects.
WCFHost(has only .svc file with web.config mentioned above and uses following two projs)
WCFInterfaces (Class library, has no config file)
WCFImplementaions (Class library, has no config files)
I wonder if I am doing anything wrong with decoupling of WCF layers above and hence my client app unable to get config details when Service reference added.
Visual Studio service reference does the magic because SOAP services provide WSDL. If you create a REST service, there is no WSDL and it will not work. The moment you switch to basic HTTP, it works because it is SOAP. You have to use HTTP libraries like HttpClient to talk to a REST endpoint.
Related
What is the difference between the Service node/section and the Client node/section in the configuration section? Why configure endpoints in one section over the other? Which is best for interoperability?
I'm currently building a service that talks to another service. I have endpoints for my clients and endpoints for the other service. Visual Studio seems to lump all the endpoints into the Client section.
I thought that client node was for your consumption and service node was for producing. But when you create a new wcf service visual studio puts your new service endpoint settings under the client node. I have moved my endpoint between both sections trying to figure out what the difference is.
When should I use service over client?
<system.serviceModel>
<services>
<service> <!--I noticed some tutorials and using wcf config edit tool
puts producer endpoint settings here -->
<endpoint blah settings/>
<endpoint blah settings/>
</service>
</services>
<client> <!--Visual Studio puts both producer and consumer endpoint
settings here -->
<endpoint blah settings />
<endpoint blah settings />
<endpoint blah settings />
</client>
<bindings>.....
</system.serviceModel>
Many settings in the WCF web.config (or app.config for that matter) can be shared for both consumers of a service as well as publishers of a service including:
Bindings
Endpoint Behaviors
Diagnostics
However as you have discovered, some config is specific to a service. A well-written service usually specifies:
It's base address. This is a convenience when defining a service as it allows your to define endpoints using relative addresses. Clients however don't use this particular setting as they need an absolute path. For this reason it makes no sense to specify in the section
Services can also be clients. If the client and server endpoints were all plonked together, WCF would not be able to know which should utilise the base address for one thing
Service behavior
By dividing up config between client and server, WCF is better able to know where to look for endpoints.
Which is best for interoperability?
I don't think that has anything to do with it. WCF is a means to achieve interopability but just by using WCF does not imply you will achieve it. Interopability is established when both parties agree on say a particular service contract; canonical data model; data transformation; message version or many of the other patterns as defined by SOA Patterns.org So there are various patterns you must follow. e.g. If you change a method on service contract but have not updated the clients then you have broken interopability by breaking the schema of the service.
Visual Studio seems to lump all the endpoints into the Client section
If your WCF process is both a consumer and producer of WCF services then it should not be putting all the endpoints under
It's my understanding that MEX and WSDL are two different ways of publishing metadata. In the interest of letting clients choose the one they prefer, I'd like to enable both. But I'm not entirely sure how.
My webconfig simply contains:
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
and when browsing to it shows that default page, with a link to serviceblahblah?wsdl which suggests I am publishing just the WSDL.
My question is, is this using MEX, if not how can I also publish MEX, and should I be publishing both?
I'm using the basichttpsbinding if that makes any difference.
and when browsing to it shows that default page, with a link to serviceblahblah?wsdl which suggests I am publishing just the WSDL.
No, you are just visiting the WSDL. What else do you expect to see on that URL? ;-)
The httpGetEnabled attribute enables the publishing of WSDL metadata. As shown in the mexHttpBinding documentation and Getting Started, if you want to expose MEX, you also have to expose a MEX endpoint you can then access:
<!-- the mex endpoint is explosed[sic] at
http://localhost/servicemodelsamples/service.svc/mex -->
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
Clients, when discovering your service, will try to call the /mex endpoint first. If not found, they will request the WSDL. You can see this using Fiddler when you click "Add Service Reference" in Visual Studio and input the plain service URL, and I'm sure this behaviour documented somewhere.
I have a fairly standard WCF service (hosted on IIS7) which generates a fairly standard WSDL when queried with ?wsdl:
<wsdl:definitions>
<!-- ... -->
<wsdl:service>
<wsdl:port>
<soap:address location="https://machine/virtual_dir/servicename.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
(boring bits omitted)
I'm after a quick 'n dirty way to change the address given in this generated WSDL to something completely different, for example:
https://othermachine/other_dir/other_service.svc
What is the easiest way of doing this?
There are several approaches you could look at:
WCF supports a lot of extensibility points, and the generation of the WSDL is one of those. You could write your own custom WSDL generator and plug it into WCF
the probably easier way would be to generate the WSDL you have, then tweak it manually, and put that WSDL file somewhere and configure it to be served up (instead of WCF generating the WSDL at runtime, when requested to do so)
You can configure option #2 with the <serviceMetadata> behavior:
<behaviors>
<serviceBehaviors>
<behavior name="StaticMetadata">
<serviceMetadata httpGetEnabled="true"
externalMetadataLocation="(url path to your static WSDL file)" />
</behavior>
</serviceBehaviors>
</behaviors>
If you do this, and your service uses this service behavior, any requests for the WSDL or for MEX data will be routed to that static WSDL you've provided, instead of using the auto-generated WSDL that WCF would normally supply.
I am trying to find some good tutorials that would show me to create a simple SOAP based service using WCF and deploy it. I have been googling for the past 2 hour and can't seem to find any good resource.. Can anyone help me?
As for resources: there's the MSDN WCF Developer Center which has everything from beginner's tutorials to articles and sample code.
Also, check out the screen cast library up on MSDN for some really useful, 10-15 minute chunks of information on just about any topic related to WCF you might be interested in.
Also very good are The Service Station articles in MSDN magazine on various aspects of WCF - some more basic like Serialization in WCF or WCF Bindings in Depth, some more advanced and esoteric - but always worth a look!
Update: for learning WCF and SOAP, check out e.g.
Getting Started Tutorial
First Steps Screencast about WCF (using SOAP!)
and a great many more - there are a ton of tutorial and learnings materials on WCF using SOAP bindings - not just REST stuff for sure!
REST / SOAP endpoints for a WCF service
You can expose the service in two different endpoints. the SOAP one can use the binding that support SOAP e.g. basicHttpBinding, the RESTful one can use the webHttpBinding. I assume your REST service will be in JSON, in that case, you need to configure the two endpoints with the following behaviour configuration
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
An example of endpoint configuration in your scenario is
<services>
<service name="TestService">
<endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
<endpoint address="json" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="ITestService"/>
</service>
</services>
so, the service will be available at
http://www.example.com/soap
http://www.example.com/json
Apply [WebGet] to the operation contract to make it RESTful. e.g.
public interface ITestService
{
[OperationContract]
[WebGet]
string HelloWorld(string text)
}
Note, if the REST service is not in JSON, parameters of the operations can not contain complex type.
For plain old XML as return format, this is an example that would work both for SOAP and XML.
[ServiceContract(Namespace = "http://test")]
public interface ITestService
{
[OperationContract]
[WebGet(UriTemplate = "accounts/{id}")]
Account[] GetAccount(string id);
}
POX behavior for REST Plain Old XML
<behavior name="poxBehavior">
<webHttp/>
</behavior>
Endpoints
<services>
<service name="TestService">
<endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
<endpoint address="xml" binding="webHttpBinding" behaviorConfiguration="poxBehavior" contract="ITestService"/>
</service>
</services>
Service will be available at
http://www.example.com/soap
http://www.example.com/xml
REST request try it in browser,
http://www.example.com/xml/accounts/A123
SOAP request client endpoint configuration for SOAP service after adding the service reference,
<client>
<endpoint address="http://www.example.com/soap" binding="basicHttpBinding"
contract="ITestService" name="BasicHttpBinding_ITestService" />
in C#
TestServiceClient client = new TestServiceClient();
client.GetAccount("A123");
Another way of doing it is to expose two different service contract and each one with specific configuration. This may generate some duplicates at code level, however at the end of the day, you want to make it working.
WCF is a technology for building services. It does not assume that the services are SOAP services or RESTFul or anything else. You have to learn WCf basics such as Service and DataContracts, Endpoints, Bindings etc to be able to work with any kind of service.
The links given marc_s are very helpful for that.
Now as far as SOAP is concerned, it is a format\technology used to transport messages from one endpoint to another. This details is covered by the Binding aspect of the WCF. When you expose and consume services you just have to choose a Binding which uses SOAP.
Hence, you should, using links given by marc_s, learn WCF basics to build a service. Then you will know how to build a service and which binding to choose to use SOAP.
Hope this helps.
I am new to WCF and WCF derived services.
I am using VS 2010, silverlight 4, ria services 4.
Recently I created plain WCF REST services (no RIA, no SOAP) with my endpoint (using wsHttpBinging):
<endpoint address="" behaviorConfiguration="wsBehavior" binding="wsHttpBinding" bindingConfiguration="wsbinding" contract="WcfService1.IService1"/>
<behaviors>
<endpointBehaviors>
<behavior name="wsBehavior">
<webHttp/>
</behavior>.........
I use this service from silverlight 4 client and everything works fine.
THEN, i created new project using "silverlight Business application" template which used RIA service. Now the web.config uses DomainServices and when i add wsHttpBind endpoint I doesnot work. I know i am not doing this correctly and i cant find any help online so far.
What I am trying to do is creat a RESTful WCF application with RIA (no SOAP) and that i can use from silverlight 4 client. For some reason i cannot get the service working.
I don't think silverlight supports wsHttpBinding.