My client has specified a WSDL file as contract for a web service that I have to implement. (It really must be that WSDL file, because it has been communicated already to other partners and so on, and they will implement their own web services and clients based on that WSDL too. It’s a WSDL file of 63 KB.)
With wsdl.exe I have created the proxy classes for the server side. So I could implement the web service. BUT: if making use of wsdl.exe to create the client side proxy classes based on the original WSDL file, then that results in a client application that is not able to communicate with the web service!
INSTEAD: by开发者_JAVA技巧 adding “?wsdl” to the web service URL, I get another WSDL file. When making use of that second WSDL file to create the client side proxy classes, then that results in client applications which are perfectly able to communicate with the web service. Strangely, that second WSDL file has a size of 288 KB instead of the 63 KB of the original WSDL file.
So that should mean that the WSDL is not round-trip… (WSDL file -> wsdl.exe to create server side proxy classes -> web service -> adding “?wsdl” to web service URL -> results in another WSDL file as the original one (and worse: they are not compatible).)
Can anyone explain this? (For my project it is important, because the other parties will make use of the original WSDL file and so they won’t be able to communicate with my web service…)
I did tests with C# as well as with CLI. It is reproducible. I am making use of IIS 7.5 and .NET framework 3.5.
Your original WSDL is used only to generate some stubs and for nothing more. By adding ?wsdl
to the service address you instruct service to get you its WSDL document but by default it creates its own. If you want to force it to return your former document you must modify your service.
Anyway if your client and service generated from the same WSDL are not able to talk to each other you have much bigger problem then different WSDL provided. With that part we will hardly help you if we don't know the WSDL.
After having modified slightly the code that was generated by my code wizard (a freely available template for CLI ASP.NET web services for Visual Studio 2008, but the standard C# web service template generates the same kind of code), I got something like that :
// MyWebService.cpp : main project file.
#include "stdafx.h"
#include "Global.asax.h"
#include "HeaderFileGeneratedByWsdlExe.h"
using namespace System;
using namespace System::Web;
using namespace System::Web::Services;
namespace MyWebService {
[WebService(Namespace = L"http://MyNamespace.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles::BasicProfile1_1)]
public ref class MyWebService : public System::Web::Services::WebService
{
public:
[WebMethod(Description = L"myMethod does something")]
System::Void myMethod(MyClass ^myInstance)
{
DoSth(myInstance);
}
};
}
"HeaderFileGeneratedByWsdlExe.h" is of course the header file that I generated with wsdl.exe (based on the specified WSDL file), specifying ‘serverInterface’ mode. (In that header file ‘MyClass’ is defined.) At this point it is possible to build the web service correctly and run it. I could ‘discover’ the wsdl file of my web service, generate client side proxy classes for it and implement a client application that could communicate correctly with my web service. Unfortunately, when I made use of the original WSDL file to generate the client side proxy classes, the client application still could send a MyClass instance to the web service, but the web service was not able to serialize that MyClass instance.
The code must be changed as follows:
// MyWebService.cpp : main project file.
#include "stdafx.h"
#include "Global.asax.h"
#include "HeaderFileGeneratedByWsdlExe.h"
using namespace System;
using namespace System::Web;
using namespace System::Web::Services;
namespace MyWebService {
[WebService(Namespace = L"http://MyNamespace.org/")]
public ref class MyWebService : public InterfaceFromHeaderFile
{
public:
System::Void myMethod(MyClass ^myInstance)
{
DoSth(myInstance);
}
};
}
The modifications are: - I removed the WebServiceBinding attribute. - I deduced the class from the abstrµact server side proxy class in the generated header file instead of from ‘WebService’. - I removed the WebMethod attribute.
After these modifications everything is working as expected.
精彩评论