One of our consumer would like to have the soap/wsdl operation named differently from requestDTO.
Given the following scenario:
//RequestDTO
public class GetCountries
{
[DataMember]
[ApiMember(Name = "Ids", Description = "Ids Description",
ParameterType = "path", DataType = "int", IsRequired = true, AllowMultiple = true)]
public int[] Ids { get; set; }
public GetCountries()
{
Ids = new int[0];
}
}
//ResponseDTO
[DataContract]
public class GetCountriesResponse
{
public GetCountriesResponse()
{
Countries = new List<Country>();
}
[DataMember]
public List<Country> Countries { get; set; }
}
we end up with the following wsdl defition
<xs:schema xmlns:tns="http://acme.org/myservice/types" elementFormDefault="qualified" targetNamespace="http://acme.org/myservice/types" xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
<xs:complexType name="GetCountries">
<xs:sequence>
<xs:element minOccurs="0" name="Ids" nillable="true" xmlns:q4="http://schemas.microsoft.com/2003/10/Serialization/Arrays" type="q4:ArrayOfint" />
</xs:sequence>
</xs:complexType>
<xs:element name="GetCountries" nillable="true" type="tns:GetCountries" />
<xs:complexType name="GetCountriesResponse">
<xs:sequence>
<xs:element minOccurs="0" name="Countries" nillable="true" type="tns:ArrayOfCountry" />
</xs:sequence>
</xs:complexType>
<xs:element name="GetCountriesResponse" nillable="true" type="tns:GetCountriesResponse" />
...
</xs:schema>
<wsdl:message name="GetCountriesIn">
<wsdl:part name="par" element="tns:GetCountries" />
</wsdl:message>
<wsdl:message name="GetCountriesOut">
<wsdl:part name="par" element="tns:GetCountriesResponse" />
</wsdl:message>
<wsdl:portType name="ISyncReply">
<wsdl:operation name="GetCountries">
<wsdl:input message="svc:GetCountriesIn" />
<wsdl:output message="svc:GetCountriesOut" />
</wsdl:operation>
...
</wsdl:portType>
<wsdl:binding name="WSHttpBinding_ISyncReply" type="svc:ISyncReply">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="GetCountries">
<soap:operation soapAction="http://acme.org/myservice/types/GetCountries" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
...
</wsdl:binding>
all that leads to the following proxy signature(generated w/ svcutil)
public GetCountriesResponse GetCountries(GetCountries GetCountries1){..}
Our consumer would like to have instead (he don’t waht have the proxy method named same as the requestDTO type)
public GetCountriesDTOResponse GetCountries(GetCountriesDTO GetCountries1){..}
As far as I understood, the soap “operation” is totally transparent to the SS framework: the only thing that matter for SS is the DTO.
So I can name the wsdl operation as I wish and that won’t impact the SS as long as the DTO is consistent with the ServiceModel(RequestDTO)
My idea to accomplish his request is based on the following step:
-
Rename the DTOs adding the “DTO” string within the name: GetCountries->GetCountriesDTO, GetCountriesResponse->GetCountriesResponseDTO
-
use the GenerateWsdl override to customize the wsdl (rename the operation)
public override string GenerateWsdl(WsdlTemplateBase wsdlTemplate)
{
var wsdl = base.GenerateWsdl(wsdlTemplate);
string input = wsdl;
string pattern = “<wsdl:operation name=”(?.*?)DTO">";
string replacement = “<wsdl:operation name=”${operationName}">";
string result = Regex.Replace(input, pattern, replacement);
return result;}
The types within the xs:schema will be renamed contianing the “DTO” string(I’ll skip all the xml for brevity)
<wsdl:message name="GetCountriesDTOIn">
<wsdl:part name="par" element="tns:GetCountriesDTO" />
</wsdl:message>
<wsdl:message name="GetCountriesDTOOut">
<wsdl:part name="par" element="tns:GetCountriesDTOResponse" />
</wsdl:message>
<wsdl:portType name="ISyncReply">
<wsdl:operation name="GetCountries">
<wsdl:input message="svc:GetCountriesDTOIn" />
<wsdl:output message="svc:GetCountriesDTOOut" />
</wsdl:operation>
...
<wsdl:binding name="WSHttpBinding_ISyncReply" type="svc:ISyncReply">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="GetCountries">
<soap:operation soapAction="http://acme.org/myservice/types/GetCountriesDTO" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
...
The only point left is the documentation / metadata page: after the DTO rename, the “Operations” listed within the page will be named with the suffix DTO.
A quick&dirty solution could be create a custom html template injecting some javascript to rename the operation name removing the DTO.
I wonder if ther’s a better solution for that: is there any server-side hook to perform that rename?