Web service newbie... Please bear with me.
I was given a WSDL file to import into my vb .NET project. I understand that this is a contract which is supposed to tell me how to use the related web service. That's where my problem comes in. I see all kinds of classes, properties, Interfaces, etc. in the imported service reference. Nothing telling me that "if you have X, Y, and Z as inputs call this function to return W".
At the risk of sounding too vague, what is it that I should be looking for that tells me how I should be using this? How do I know which functions to call and from what classes to call them from? Should I expect some documentation to be provided with the WSDL or is the WSDL supposed to be enough for me to look at it and say "ahh, that's how this is used!".
I've read through the various WSDL tutorials out on the web and they gave me a basic understanding (I think...?). I'm missing something somewhere though and I'm really sure where.
Thank you for any assistance.
The classes that have been generated are easy to use.
Basically you would have one client class, and in that class one method for each endpoint/operation declared in the WSDL.
In addition, there should be one class for each complex type defined in the XSD part (the operation input arg object and output result object).
You can then invoke your WS in a way similar to the following (simplified) example.
Try
Dim service As New MyServiceRef.MyServiceClient()
service.Open()
Dim output As MyServiceRef.myCallResponse
Dim args As New MyServiceRef.myCallRequest
args.arg1 = 1
args.arg2 = "A"
output = service.myCallRequest(args)
...
Catch ex As Exception
treat ( ex )
End Try
The WSDL will tell you or, perferably, a SOAP library how to communitcate with the SOAP server. A SOAP service can be an interface to get data for almost anything.
However, if the function names and parameters are not named well, it could be very vague what data you are to send to the SOAP service and what the response will be.
Most of the time, it should be documented. You should get those documents or learn what the service actually does from the service provider. The WSDL is not really meant to be for human consumption. Though, if you are writing your own XML, then yes, you'd need to pay attention to the WSDL. If a library is creating the XML for you, it usually works with the WSDL to find out how to structure the XML and read the response.
When you add reference of the web service, it creates a proxy for you to call the web methods on the server. Here is a simple tutorial for consuming web services in VB.NET
Related
I have an existing WCF Service with more than thirty functions each returning XML to the client app. I enabled the help page by following these instructions from Microsoft. This summarizes the methods of my service and lets me drill down to see the Request an Response formats, but does not include my enums. I'm opening up the service to a third-party vendor and I'd like to expand on the help file in a self-documenting way.
Unfortunately, I have most of my functions return a generic XMLElement like so:
<OperationContract()>
<WebGet(ResponseFormat:=WebMessageFormat.Xml, UriTemplate:="GetToken?u={sUser}&p={sPass}")>
<Description("Validates a user's credentials")>
Function GetToken(ByVal sUser As String, ByVal sPass As String) As XmlElement
The payload of several of these functions will include a handful of enumerated values, and table data. Because I don't have a strongly type Return, the Help page doesn't show any detail.
I've checked other similar questions, and I see differing advice on whether to expose the enums. The part I'm missing is the actual details of how to do it. I've tried using the following in both my IMyService.vb and MyService.svc.vb files, but nothing new shows up in my help page:
<DataContract(Name:="StatusCode")>
Enum StatusCode As Integer
<EnumMember> Success = 0
<EnumMember> UserNameMissing = -1
PasswordMissing = -2
PermissionError = -3
AccountNotFound = -4
BusinessRuleViolation = -5
SystemDown = -99
UnknownError = -100
End Enum
I tried some hokey workarounds like attempting to add multi-line comments to my tags. I can't use "" & Environment.NewLine & "" concatenation or \n or tags. I started on trying to make a more strongly typed class that inherits from XMLElement, but I'd rather avoid the risk of breaking compatibility if there's some trick to the help file.
I see that I can add an XML Comment to the output file that gives some background info to developers, but they'd have to hit each of the methods to read it. (I've set it to only appear on the development server and not in production).
I suppose I could add another Method to the contract that just says ListMyEnums and returns a strongly typed set of the values, but that seems strange. I would appreciate any advice on this.
I assume the XmlElement returned from your operation needs to at some point be deserialized on the client side to be of use? If so, then the consumer must already have some kind of equivalent object graph with which to work.
I think the simplest thing for you to do is to provide the consumer object graph via a consumer package released over something like NuGet or npm (or even just a shared assembly).
The consumer package would contain the actual graph you used to serialise the XML you're sending (enums and all), and could even encapsulate the means by which consumers call your service. That way you can control the object graph and deserialization of the XmlElement on the client.
Consumers would benefit because all they would need to do is consume your client package and then make the call, similar to how it works with WSDL and SOAP.
The existing consumers are loosely coupled
I would actually expect a high degree of coupling between service and consumer. In fact, I would not use the term coupling in this instance, but cohesion. Highly cohesive software is good.
I have a WSDL file from a published ASMX web service. What I am after
is creating a mock service that mimics the real service for testing purposes.
From the WSDL, I used SvcUtil.exe to generate code. Apparently it also generates
the server side interface.
Well the issue is that it generates very chunky interfaces. For example, a method
int Add(int, int) is showing up in the generated .cs file as AddResponse Add(AddRequest). AddRequest and AddResponse have a AddRequestBody and AddRequestResponse and so on.
The issue is that, to implement, I need to create the body and response instances for each method, even when I just want to return a simple int result.
Why can't it generate the method signature properly? Is there a better way of generating WCF Server side interface/contracts from WSDL?
The message structure you are describing is caused by two things:
better interoperability across web service stacks and their programming models (RPC vs messaging);
flexibility to accommodate new parameters into existing web services.
You are not the first one to complain about it, or the last. It's a WSDL binding style commonly called the document/literal wrapped pattern. It produces document/literal web services and yet also supports an RPC programming style. It's very "WS interoperability friendly", so to speak...
The WS-I Basic profile specifies that the soap:body must have only one child element and in this case it's a wrapper for the operation name that's being invoked. The parameters of the call are packed into only one element as a best practice since it's more flexible to later changes. In case of WCF you usualy end up with a MessageContract which has one MessageBodyMember which wraps all the parameters.
Basically, you are seeing the results of web service battles fought long time ago.
Here is some extra reading on the subject (and that's just the tip of the iceberg):
Which style of WSDL should I use?
RPC/Literal and Freedom of Choice
My Take on the Document/Literal 'Wrapped' Idiom
Is it possible to create a "generic" as in "adaptable" routing service, which will NOT have any public methods to call. Instead, you'd be able to call any command, which would then be mapped in the service and will pass it to appropriate end point with simple message transformation where required.
It may be hard to understand and idea might seem a bit crazy (it came from a colleague of mine), but it's clearer if you look at the example:
similar to what's described in this article, only difference is that our service should not have a "SubmitTimeSheet" public method, in fact it should have no public methods to call. We'd have to "intercept" an incoming call on a much lower level before it returns "Method Not Found" error.
Is this at all possible? The reason for this is obvious: possibility of adding new clients without having to change the code. All we'd have to do is to add a new mapping entry in some sort of config file or even database, e.g.
<Client address="newClientAddress" method="DoAnything" transformation="NewClientDoAnything.xslt" endPoint="endPointClientAddress" endPointMethod="endPointClientDoAnything" />
Check out WCF 4 routing - supports content based routing, xpath transforms and much more.
http://blogs.msdn.com/b/routingrules/
They have already done it in Nirvana. But it is very expensive.
This is not possible in WCF unless you define your contract as a very loose, fit-for-all contract which takes a message and returns a message. By doing this, you will los all the goodness (although not huge goodness in WCF) of WCF.
I'm having very strange issue with my WCF Service Proxy client generated by "svcutil.exe" . My WCF Service works very fine if I don't have a function that returns DataTable. As soon as I add a method that returns a DataTable the client generated by svcutil.exe is behaving very strangely. The Interface is no longer found and client is not able to call the service. But if I add as a Service Reference its working very smoothly. I know its not a good habit to use DataTable as a return type but I need to. I cannot use the Service Reference :-( Any idea why its behaving or what I'm missing!!!
Have a look at the DataTableSurrogate class. It is used by the SyncFramework for serialization and really easy to use.
MSDN DataTableSurrogate
You shouldn't really serialize datasets, instead you should use datamodels and keep anything to do with datasets, tables, readers etc on your backend & in the business layer.
But.. if you want to do so you need to add the following "include" in svcutil, which is causing your issue. (Tells to reuse the types defined in System.Data.dll and not generate them in the proxy)
/r:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Data.dll
I'm trying to use NeoLoad to generate and execute SOAP requests and upon supplying the WSDL, it doesn't seem to like the imports that they are referring to.
I'm thinking I would need to flatten the WSDL generated by the WCF service.
Are there any techniques I could use to flatten it?
I've been reading:
http://blogs.msdn.com/dotnetinterop/archive/2008/09/23/flatten-your-wsdl-with-this-custom-servicehost-for-wcf.aspx
http://blogs.thinktecture.com/cweyer/archive/2007/05/10/414840.aspx
Would this be something I should be trying out?
Yes, some clients have trouble with the (standards-compliant) way that Microsoft has implemented the WSDL and XSD.
Those two articles you mention are great starting points - they show how you can get your WCF service to render out a flattened WSDL (which includes the XSD inside it).
The same goes for WCF Extras on Codeplex, which also does a few more things in addition (most notably exporting the XML comments from your C# or VB.NET code into the WSDL). Highly recommended.