Attributi di serializzazione sui WebMethod asincroni server-side
Oggi, lavorando con RoB ad un'applicazione che stiamo implementando, siamo
"cascati" in un problema che non saprei bene come definire.
Sicuramente è un comportamento "non immediato" dei web service ASMX, non lo definirei
semplicisticamente bug per scaricare la responsabilità su Microsoft, semplicemente è un
qualcosa che non avevo trovato documentato.
Se definiamo un WebMethod asincrono server-side, come spiego anche nel mio ormai vetusto :) libro
Full Contact XML & Web Services.
Se utilizziamo degli attributi di serializzazione, per esempio perché abbiamo correttamente usato un
approccio Contract First e con WSCF o WSDL.EXE abbiamo generato il codice server, gli attributi
devono essere tutti definiti sul metodo di Begin*, anche quelli relativi al return value, benché
il return value del Begin* method sia in realtà un IAsyncResult.
Questo comportamento è dovuto dal fatto che il motore di ASMX genera la signature dell'operazione
leggendo solo gli attributi di serializzazione del metodo di Begin* e non fonde gli attributi del
Begin* e End*.
Quindi in pratica, dobbiamo scrivere una cosa di questo tipo:
[System.Web.Services.Protocols.SoapHeaderAttribute("ActionSoapHeaderValue", Direction = System.Web.Services.Protocols.SoapHeaderDirection.InOut)]
[System.Web.Services.WebMethodAttribute()]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("urn:sendActionStep", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare, Binding = "mauiActionsServiceBinding")]
[return: System.Xml.Serialization.XmlElementAttribute("SendActionStepOutputMessage", Namespace = "http://schemas.devleap.it/Actions")]
public virtual IAsyncResult BeginSendActionStep([System.Xml.Serialization.XmlElementAttribute(Namespace = "http://schemas.devleap.it/Actions", ElementName = "SendActionStepInputMessage")] SendActionStepInputMessage sendActionStepInputMessage, AsyncCallback callback, Object state)
{
return (beginSendActionStepInternal(sendActionStepInputMessage, callback, state));
}
[System.Web.Services.WebMethodAttribute()]
public virtual SendActionStepOutputMessage EndSendActionStep(IAsyncResult ar)
{
return(endSendActionStepInternal(ar));
}
dove come si vede l'attributo [return:] è stato definito sul WebMethod di BeginSendActionStep,
anche se è relativo al risultato del WebMethod di EndSendActionStep. L'operazione in quanto tale
che verrà esposta sarà poi SendActionStep che solo a livello di architettura server sarà eseguita
in asincrono.