Oggi stavo estendendo il web service della nostra applicazione aggiungendo due nuovi web methods. I due web methods in questioni fanno la stessa cosa di altri due web methods già presenti ma a differenza di essi hanno un parametro in più.
In pratica ho:
[WebMethod]public DataSet ReadData(string applicationName, DataSet dataSet) {…}
[WebMethod]public bool WriteData(string applicationName, DataSet dataSet){…}
Quindi mi sono detto: “facile, uso l’overloading in C#, inserisco i due nuovi metodi chiamandoli come i vecchi e cambiando solo il numero dei parametri; poi il web server funzionerà allo stesso modo”. Et voila
[WebMethod]public DataSet ReadData(string applicationName, DataSet dataSet) {…}
[WebMethod]public bool WriteData(string applicationName, DataSet dataSet){…}
[WebMethod]public DataSet ReadData(string moduleName, string applicationName, DataSet dataSet) {…}
[WebMethod]public bool WriteData(string moduleName, string applicationName, DataSet dataSet){…}
Sbagliato!!
Quando da Visual Studio cerco di aggiornare la signature del Web Service per un mio client di test, questo mi risponde:
“Both ReadData(string applicationName, DataSet dataSet) and public DataSet ReadData(string moduleName, string applicationName, DataSet dataSet) use the same name ‘ReadData"’. Use the Messa” <— il bello che qui il messaggio si tronca!!!
Va beh una rapida ricerca nel web e scopro che i WebMethods non possono avere lo stesso nome. [In realtà scopro ora che per avere l’errore completo basta fare browse su service.asmx]
Quindi lato C# posso naturalmente usare l’overloading poi però in fase di pubblicazione devo differenziare i metodi attraverso la proprietà “MessageName” dell’attributo WebMethod.
Cambio dunque il codice sopra in:
[WebMethod]public DataSet ReadData(string applicationName, DataSet dataSet) {…}
[WebMethod]public bool WriteData(string applicationName, DataSet dataSet){…}
[WebMethod (MessageName=”ReadDataForModule”)]public DataSet ReadData(string moduleName, string applicationName, DataSet dataSet) {…}
[WebMethod (MessageName=”WriteDataForModule”)]]public bool WriteData(string moduleName, string applicationName, DataSet dataSet){…}
E riprovo a fare l’update del Web Service dal mio client. Stavolta l’errore è il seguente:
Server Error in ‘/WebServices’ Application.
Service ‘Service’ does not conform to WS-I Basic Profile v1.1. Please examine each of the normative statement violations below. To turn off conformance check set the ConformanceClaims property on corresponding WebServiceBinding attribute to WsiClaims.None.
R2304: Operation name overloading in a wsdl:portType is disallowed by the Profile. A wsdl:portType in a DESCRIPTION MUST have operations with distinct values for their name attributes. Note that this requirement applies only to the wsdl:operations within a given wsdl:portType. A wsdl:portType may have wsdl:operations with names that are the same as those found in other wsdl:portTypes.
- Operation ‘ReadData’ on portType ‘ServiceSoap’ from namespace ‘http://txt.it/webservices/’.
- Operation ‘WriteData’ on portType ‘ServiceSoap’ from namespace ‘http://txt.it/webservices/’.
To make service conformant please make sure that all web methods belonging to the same binding have unique names.
Documentandomi un po’ in rete trovo che le mie modifiche fanno si che il web service non è più conforme ad una serie di regole guida definite per garantire l’interoperabilità (le guidelines sono qui) . Nello specifico la R2304 dice:
“R2304 A wsdl:portType in a DESCRIPTION MUST have operations with distinct values for their name attributes. Note that this requirement applies only to the wsdl:operations within a given wsdl:portType. A wsdl:portType may have wsdl:operations with names that are the same as those found in other wsdl:portTypes.”
In pratica anche se ho usato la proprietà MessageName, si sta lamentando del fatto che ho metodi con lo stesso nome.
Penso che sia possibile disabilitare il check di queste guidelines ma scelgo la strada più semplice e tolgo l’overloading.
[WebMethod]public DataSet ReadData(string applicationName, DataSet dataSet) {…}
[WebMethod]public bool WriteData(string applicationName, DataSet dataSet){…}
[WebMethod]public DataSet ReadDataForModule(string moduleName, string applicationName, DataSet dataSet) {…}
[WebMethod]public bool WriteDataForModule(string moduleName, string applicationName, DataSet dataSet){…}
Dunque overloading di web method? No grazie.