Rather than exposing the system generated meta data I'd like to provide my meta data which is kept it a text file (say) on the server. I guess this means responding to the HTTP GET request http://[service address]?wdsl.
You could simply turn off metadata export (remove serviceMetadataBehavior or set its httpGetEnabled flag to false) and then put your WSDL document at a URL that makes sense for your app (?wsdl is a WCF / ASMX convention but its not a standard)
This is pretty easy if you are using IIS hosting but would need a REST endpoint for Self Hosting
You can develop a custom MetaExporter and then find ServiceMetadataBehavior, in that behavior, you can override the default MetadataExporter.
Therefore in your MetaExporter, you can do anything you want.
Related
I'm building a WCF router which needs to act as a proxy for a number of internal web services (WCF and ASMX). The routing part is fairly straight-forward, but I can't understand how the service metadata exchange would work in this solution.
In other words: how would a client obtain metadata for an internal service behind the router? Do I need to manually supply WSDL files to the consumer? Can I somehow setup the router to return the metadata for an appropriate internal service?
Or perhaps my architecture is completely wrong?
I see 2 options here:
It may be an option to create a "non-transparent" proxy, if you don't want to expose the internal addresses. The advantage is that you can do more than just routing messages (i.e. such proxy may serve as a "security boundary", unwrapping ciphered messages and passing them plain to the internal endpoint). It can also provide an "interoperable level", exposing a WCF service as simple SOAP using same datatypes/message XML structure. The downside is that you'll have to update its code along with the proxied services
You may implement a WSDL rewriter. With it, you can mask the internal service URL on-the-fly - depending on your conditions, a simple string replace may or may not suffice.
Refer to:
Message Inspectors
IWsdlExportExtension
The same "router service" can also be used to get the individual WSDL for internal services behind the router.
Check out this thread
Have you considered using a simple HTTP Proxy instead? All WCF using REST or SOAP are at their core HTTP requests. It seems like the routing functionality (which I am assuming you are basing on hostname, URL path or parameters) could be performed by proxying the HTTP request without needing to understand the contents. ASP.Net will do a fairly good job of sanitizing incoming requests on its own, but you could always add additional custom filtering as necessary.
Using a console app to serve a REST WCF service. Showing the WSDL in the browser is usually done in demonstrations. It would be cool to take the favicon.ico and have that appear instead of the IE logo, but there is no real "home directory". Is it possible to show the Favorites Icon when doing a web service?
Thanks.
A couple of things:
REST services don't use WSDL - WSDL is a SOAP construct
The WSDL engine in WCF takes over the processing of GET requests to the metadata address and therefore you cannot engineer a response to favicon.ico (just tried to put a REST endpoint to do this side by side with the metadata and it doesn't get invoked)
The only thing you could do would be to generate the WSDL yourself and serve it from a REST endpoint which also had code to process favicon.ico (which seems like a lot of work to show an icon on a WSDL page - especially when WSDL isn't really designed for human consumption)
I am developing a wcf service (basicHttpBinding) that should also be consumed by non .net clients (e.g. Java clients). But now I wonder how the client can define his client config file. Or is this file only needed for .net-clients? (I am thinking of configurations like maxReceivedMessageSize or maxItemsInObjectGraph for example).
Each development platform (call it as you want: SOAP stack, Framework, API) has its own way to configure communication. You don't need to bother with it. You just need to expose correct WSDL and client's developer will be responsible for configuring the client application based on his needs.
If you want to extend documentation of your service in WSDL you can use wsdl:documentation. WCF doesn't offer it by default but you can use this technology sample to extend WCF. You can use such documentation for example to describe that service operation can return large amount of data. Another approach to add wsdl:documentation is using WCF Extras.
From the sound of it, the client shouldn't have access to those configuration options. For instance, why should a client to the WCF service be able to specify the maxReceivedMessageSize?
What you probably want to do is define these configuration options on the server-side. If a client makes a call and there is a conflict with one of your options (i.e. the client exceeds maxReceivedMessageSize), you'll want to throw a SoapException back to the client.
If you want to let the client have access to the configuration settings before he or she sends a request, you can always implement a simple web service method that sends back the values.
It is just magic that I put some file in my site's Bin folder and place a svc file to point to some assembly pointing to my service type. And then, I could magically Add Service Reference to the url like this:
http://www.myserver.com//xxx.svc
I really want to know how what happens from my click "Add Service Reference" to the proxy is generated properly. What does the IIS do during this period?
It's not really magic - it's metadata exchange ! :-)
When you do a Add Service Reference in Visual Studio, behind the scenes, that service endpoint specified by the svc file is interrogated for its metadata. This is basically similar to a WSDL (Web Service Description Language) file - a machine-readable description of your service, its methods, what parameters they expect etc. - and a XSD (XML schema) that - again in machine-readable form - defines the parameter types used.
Based on those two pieces of information, the WCF client side import can create C# or VB.NET classes that
mirror the exact service implementation on the service side - same method names, same parameters expected and returned
create the necessary data classes - again in C# or VB.NET - based off of the XML schema file
So in the end - it's really not magic. It's the beauty of self-describing services and a bit of code generation that reads that metadata and creates client-side proxy classes from that metadata description
If you're interested in more details about metadata, read the MSDN docs on WCF metadata - quite extensive and in-depth.
As marc_s stated, the "Add Service Reference" button runs a tool that collects the metadata from the service, and generates client code from it.
I just wanted to add that if you want to view that metadata (WSDL) yourself, you can just add "?wsdl" to your URL:
http://localhost/MyService.svc?wsdl
One WSDL document will chain to many others, so you would have to make several requests to dig through them all, but it is interesting to see how the data types and contracts are transmitted.
Also, if you want to prevent other people from automatically generating a client to your service, you can disable the WSDL by removing the "mex" (Metadata EXchange) endpoint from your WCF configuration.
This is a major issue for me. In earlier times, web service clients could simply use EnableDecompression = true and all was good, but why did Microsoft not add something similar to WCF?
I really NEED gzip compressed responses from my WCF services (and they need to be http... legacy issues, as usual... you know...).
Check out this blog post which basically ends up suggesting:
Conclusion
I now ditched this as we also need to
support clients that do not set the
AcceptEncoding header so I really need
the ability to read the http header in
request and set a "context" value to
(not) compress the response and I have
not found out yet how to do that per
multiple concurrent requests. I really
recommend to use the IIS http
compression and not try to do this
with WCF hacking as described here!
There's also a WCF Extensions project on Codeplex which has a WCF Compression Channel - maybe that'll be what you're looking for.
The most bang for the buck would be to use the binaryMessageEncoding in WCF instead of the textMessageEncoding (which is the default for HTTP bindings). That would require you to create a custom http based binding, and would render your service incompatible with other http-based clients other than .NET clients that are also using the same custom binding configuration.