6
6kjfsyg02
I am trying to return one of two different objects from the same
method, but I can not do it in WSDL or C#.
I have a web service with three methods.
I have been told that one of the methods must return either <Respuesta
....> or <ConfirmacionPeticion ...> directly under the SOAP Body. Other
methods are already capable of returning just <Respuesta ...> or just
<ConfirmacionPeticion ...>. What is new is one method being capable of
returning both types.
I have been modifying over one of the previous methods:
[WebMethodAttribute( Description = "Blah...")]
[SoapDocumentMethod( ourMethodNamespace, Use = SoapBindingUse.Literal,
ParameterStyle = SoapParameterStyle.Bare)]
[return: XmlElement( Respuesta.Marca, Namespace =
Respuesta.EspacioNombres)]
public Respuesta solicitaRespuestaAsincrona( ...)
The obvious thing is to substitute the return type by object:
[WebMethodAttribute( Description = "Blah...")]
[SoapDocumentMethod( ourMethodNamespace, Use = SoapBindingUse.Literal,
ParameterStyle = SoapParameterStyle.Bare)]
public object solicitaRespuestaAsincrona( ...)
But then the automatic WSDL becomes:
<wsdl:message name="solicitaRespuestaAsincronaSoapOut">
<wsdlart name="solicitaRespuestaAsincronaResult"
element="tns:solicitaRespuestaAsincronaResult"/>
</wsdl:message>
That is, under <soap:Body> I get a <solicitaRespuestaAsincronaResult>
element followed by the members of the actual object being returned.
This is not what I want, I want either <Respuesta> or
<ConfirmacionRespuesta>.
I then tried to have several XML return attributes:
[WebMethodAttribute( Description = "Blah...")]
[SoapDocumentMethod( ourMethodNamespace, Use = SoapBindingUse.Literal,
ParameterStyle = SoapParameterStyle.Bare)
[return:
XmlElement( Respuesta.Marca,
Namespace = Respuesta.EspacioNombres),
XmlElement( ConfirmacionPeticion.Marca,
Namespace = ConfirmacionPeticion.EspacioNombres)]]
public object solicitaRespuestaAsincrona( ...)
but then I get:
System.InvalidOperationException: You need to add
XmlChoiceIdentifierAttribute to the 'solicitaRespuestaAsincronaResult'
member.
I then tried the inverse route of hacking the WSDL. I created a new
type:
<wsdl:types>
....
<!-- Since this does not have a namespace, this breaks the Basic
Profile. -->
<s:schema elementFormDefault="qualified">
<s:complexType name="RespuestaOConfirmacion" >
<s:sequence>
<s:choice minOccurs="0" maxOccurs="1">
<s:element minOccurs="1" maxOccurs="1" name="Respuesta" />
<s:element minOccurs="1" maxOccurs="1"
name="ConfirmacionPeticion" />
</s:choice>
</s:sequence>
</s:complexType>
<!-- Without an explicit element:
// CODEGEN: The operation binding 'solicitaRespuestaAsincrona'
from
namespace 'http://www.map.es/scsp/' was ignored.
Specifying a type for use=literal messages is not supported.
Type name='RespuestaOConfirmacion' from targetNamespace=''
cannot be used as top-level any element.-->
<s:element name="RespuestaOConfirmacion"
type="RespuestaOConfirmacion"/>
</s:schema>
</wsdl:types>
and
<wsdl:message name="solicitaRespuestaAsincronaSoapOut">
<wsdlart name="solicitaRespuestaAsincronaResult"
element="RespuestaOConfirmacion"/>
</wsdl:message>
This type is stubbed as
public partial class RespuestaOConfirmacion
{
[XmlElement("ConfirmacionPeticion", typeof(ConfirmacionPeticion))]
[XmlElement("Respuesta", typeof(Respuesta))]
[XmlChoiceIdentifier("nombreElemento")]
public object unaRespuestaOUnaConfirmacion;
[System.Xml.Serialization.XmlIgnoreAttribute()]
public RespuestaOConfirmacionEleccion nombreElemento;
}
[System.Xml.Serialization.XmlTypeAttribute(IncludeInSchema =
false)]
public enum
RespuestaOConfirmacionEleccion
{
ConfirmacionPeticion,
Respuesta
}
I then tried with:
....
[return:
XmlChoiceIdentifier(MemberName = "nombreElemento"),
XmlElement( Respuesta.Marca,
Namespace = Respuesta.EspacioNombres),
XmlElement( ConfirmacionPeticion.Marca,
Namespace = ConfirmacionPeticion.EspacioNombres)]
public RespuestaOConfirmacion solicitaRespuestaAsincrona( ...)
This causes:
System.InvalidOperationException: There was an error reflecting
'solicitaRespuestaAsincronaResult'. --->
System.InvalidOperationException: Missing 'nombreElemento' member
needed for serialization of choice 'solicitaRespuestaAsincronaResult'.
in spite of me assigning a value to the nombreElemento field in the
return value.
If I have
[return:
XmlChoiceIdentifier(MemberName = "nombreElemento"),
XmlElement( Respuesta.Marca,
Namespace = Respuesta.EspacioNombres),
XmlElement( ConfirmacionPeticion.Marca,
Namespace = ConfirmacionPeticion.EspacioNombres)]
[return: XmlElement("RespuestaOConfirmacion", Namespace = "")]
the return value is serialized as
<RespuestaOConfirmacion>
<Respuesta ...>
....
</RespuestaOConfirmacion>
That is, the Respuesta or the ConfrimacionPeticion are wrapped with
<RespuestaOConfirmacion> which again is not what I want.
So summarizing, how do you express either in C# or in WSDL that you can
return any of two different elements under <soap:Body>?
Thanks in advance.
method, but I can not do it in WSDL or C#.
I have a web service with three methods.
I have been told that one of the methods must return either <Respuesta
....> or <ConfirmacionPeticion ...> directly under the SOAP Body. Other
methods are already capable of returning just <Respuesta ...> or just
<ConfirmacionPeticion ...>. What is new is one method being capable of
returning both types.
I have been modifying over one of the previous methods:
[WebMethodAttribute( Description = "Blah...")]
[SoapDocumentMethod( ourMethodNamespace, Use = SoapBindingUse.Literal,
ParameterStyle = SoapParameterStyle.Bare)]
[return: XmlElement( Respuesta.Marca, Namespace =
Respuesta.EspacioNombres)]
public Respuesta solicitaRespuestaAsincrona( ...)
The obvious thing is to substitute the return type by object:
[WebMethodAttribute( Description = "Blah...")]
[SoapDocumentMethod( ourMethodNamespace, Use = SoapBindingUse.Literal,
ParameterStyle = SoapParameterStyle.Bare)]
public object solicitaRespuestaAsincrona( ...)
But then the automatic WSDL becomes:
<wsdl:message name="solicitaRespuestaAsincronaSoapOut">
<wsdlart name="solicitaRespuestaAsincronaResult"
element="tns:solicitaRespuestaAsincronaResult"/>
</wsdl:message>
That is, under <soap:Body> I get a <solicitaRespuestaAsincronaResult>
element followed by the members of the actual object being returned.
This is not what I want, I want either <Respuesta> or
<ConfirmacionRespuesta>.
I then tried to have several XML return attributes:
[WebMethodAttribute( Description = "Blah...")]
[SoapDocumentMethod( ourMethodNamespace, Use = SoapBindingUse.Literal,
ParameterStyle = SoapParameterStyle.Bare)
[return:
XmlElement( Respuesta.Marca,
Namespace = Respuesta.EspacioNombres),
XmlElement( ConfirmacionPeticion.Marca,
Namespace = ConfirmacionPeticion.EspacioNombres)]]
public object solicitaRespuestaAsincrona( ...)
but then I get:
System.InvalidOperationException: You need to add
XmlChoiceIdentifierAttribute to the 'solicitaRespuestaAsincronaResult'
member.
I then tried the inverse route of hacking the WSDL. I created a new
type:
<wsdl:types>
....
<!-- Since this does not have a namespace, this breaks the Basic
Profile. -->
<s:schema elementFormDefault="qualified">
<s:complexType name="RespuestaOConfirmacion" >
<s:sequence>
<s:choice minOccurs="0" maxOccurs="1">
<s:element minOccurs="1" maxOccurs="1" name="Respuesta" />
<s:element minOccurs="1" maxOccurs="1"
name="ConfirmacionPeticion" />
</s:choice>
</s:sequence>
</s:complexType>
<!-- Without an explicit element:
// CODEGEN: The operation binding 'solicitaRespuestaAsincrona'
from
namespace 'http://www.map.es/scsp/' was ignored.
Specifying a type for use=literal messages is not supported.
Type name='RespuestaOConfirmacion' from targetNamespace=''
cannot be used as top-level any element.-->
<s:element name="RespuestaOConfirmacion"
type="RespuestaOConfirmacion"/>
</s:schema>
</wsdl:types>
and
<wsdl:message name="solicitaRespuestaAsincronaSoapOut">
<wsdlart name="solicitaRespuestaAsincronaResult"
element="RespuestaOConfirmacion"/>
</wsdl:message>
This type is stubbed as
public partial class RespuestaOConfirmacion
{
[XmlElement("ConfirmacionPeticion", typeof(ConfirmacionPeticion))]
[XmlElement("Respuesta", typeof(Respuesta))]
[XmlChoiceIdentifier("nombreElemento")]
public object unaRespuestaOUnaConfirmacion;
[System.Xml.Serialization.XmlIgnoreAttribute()]
public RespuestaOConfirmacionEleccion nombreElemento;
}
[System.Xml.Serialization.XmlTypeAttribute(IncludeInSchema =
false)]
public enum
RespuestaOConfirmacionEleccion
{
ConfirmacionPeticion,
Respuesta
}
I then tried with:
....
[return:
XmlChoiceIdentifier(MemberName = "nombreElemento"),
XmlElement( Respuesta.Marca,
Namespace = Respuesta.EspacioNombres),
XmlElement( ConfirmacionPeticion.Marca,
Namespace = ConfirmacionPeticion.EspacioNombres)]
public RespuestaOConfirmacion solicitaRespuestaAsincrona( ...)
This causes:
System.InvalidOperationException: There was an error reflecting
'solicitaRespuestaAsincronaResult'. --->
System.InvalidOperationException: Missing 'nombreElemento' member
needed for serialization of choice 'solicitaRespuestaAsincronaResult'.
in spite of me assigning a value to the nombreElemento field in the
return value.
If I have
[return:
XmlChoiceIdentifier(MemberName = "nombreElemento"),
XmlElement( Respuesta.Marca,
Namespace = Respuesta.EspacioNombres),
XmlElement( ConfirmacionPeticion.Marca,
Namespace = ConfirmacionPeticion.EspacioNombres)]
[return: XmlElement("RespuestaOConfirmacion", Namespace = "")]
the return value is serialized as
<RespuestaOConfirmacion>
<Respuesta ...>
....
</RespuestaOConfirmacion>
That is, the Respuesta or the ConfrimacionPeticion are wrapped with
<RespuestaOConfirmacion> which again is not what I want.
So summarizing, how do you express either in C# or in WSDL that you can
return any of two different elements under <soap:Body>?
Thanks in advance.