locked
Webservice, Generating WSDL with elementFormDefault = “Unqualified” RRS feed

  • Question

  • User-1303772121 posted

    Hello,

    we are right now trying to expose a Web Service method to another company. Their demands are that the method is OneWay and we need to have the attribute **elementFormDefault = "Unqualified" **.

    We don't fully understand the way this works, we are using VS 2010 and we added a new Item called "Web Service". Then we defined our Web Method and build the solution. Everything worked well and the WSDL generated looks good. The only problem is that we always have elementFormDefault = "Qualified" no matter how we define our class.

    We can make the WSDL generated to indicate that all attributes are unqualified but we always have the element for default defined as qualified...

    When our client tries to use our method we receive empty information...

    our class to generate the XML is this one, note that the class is a bit messy as we tried multiple solutions:

     using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    using WSGerfip.Ws_Tesouraria;
    using System.IO;
    using System.Xml;
    using System.Xml.Serialization;
    using WSGerfip.Client_IlcrCallback;
    
    namespace WSGerfip
    {
    
    
        // -----------------------------------------------------------------------------------------------------------------------------------
        // CallBack - WebService que a ESPAP chama.
        //            Este WebService CallBack, por sua vez, chama o Web Service da Tesouraria (Ws_NotasCobranca)
        //            Foi necess�rio implementer esta camada no dotnet, porque em Outsystems n�o dava para definir o atributo OneWay
        // -----------------------------------------------------------------------------------------------------------------------------------
    
        [WebService(Namespace = "urn:espap.gerfip.ilcr.v1")]
        //[XmlRoot(Namespace = "urn:espap.gerfip.ilcr.v1", IsNullable=true)]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        [System.ComponentModel.ToolboxItem(false)]
    
    
        // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
        // [System.Web.Script.Services.ScriptService]
        //glide.wsdl.schema.UnqualifiedElementFormDefault
    
    
    
    
        public class CallBackReceita : System.Web.Services.WebService
        {
    
            [SoapDocumentMethod(OneWay = true)]
            [WebMethod]
    
            public void RegisterLogisticInvoiceResult(
                [System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] string CorrelationId)
                [System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] int ResultStatus,
                [System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] RegisterLogisticInvoiceResultResult[] Results,
                [System.Xml.Serialization.XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] WSGerfip.Client_IlcrCallback.Messages[] GeneralMessages)
            {
                //CorrelationId = this.CorrelationId;
                 string linhaA_Escrever;
                 string path_escrita;
                path_escrita = "c:\\Temp\\Log_Fatura.txt";
    
                StreamWriter streamWriter = new StreamWriter(path_escrita, true, System.Text.Encoding.GetEncoding("ISO-8859-1"));
    
                try
                {
    
                    linhaA_Escrever = "--------------------------------------------------" + Environment.NewLine;
                    linhaA_Escrever = linhaA_Escrever + "Data: " + DateTime.Now + Environment.NewLine;
                    linhaA_Escrever = linhaA_Escrever + "IdCorrela��o: " + CorrelationId + Environment.NewLine;
    
    
                    //Results = new Result[1];
    
                    linhaA_Escrever = linhaA_Escrever + "0" + Environment.NewLine;
    
                    //Results[0] = new Result();
    
                    linhaA_Escrever = linhaA_Escrever + "00" + Environment.NewLine;
    
                    //Results[] = Results[];
    
                    //Results[0].PDF = new PDF();
                    //Results[0].PDF.InvoicePdf = new byte[10000000];
    
                    linhaA_Escrever = linhaA_Escrever + "1" + Environment.NewLine;
    
    
                    //Ws_Tesouraria.RegisterLogisticInvoiceResult RegisterLogisticInvoiceResult = new Ws_Tesouraria.RegisterLogisticInvoiceResult();
    
                    //RegisterLogisticInvoiceResult.CorrelationId = CorrelationId;
                    //RegisterLogisticInvoiceResult.ResultStatus = ResultStatus;
                    //RegisterLogisticInvoiceResult.Results = Results;
                    //RegisterLogisticInvoiceResult.GeneralMessages = GeneralMessages;
    
    
    
                    //linhaA_Escrever = linhaA_Escrever + "Pdf:2 " + Results[0].PDF.InvoicePdfName + Environment.NewLine;
    
                    ////if (Results[0].PDF != null)
                    //linhaA_Escrever = linhaA_Escrever + "Pdf:3 " + Results[0].PDF.InvoicePdfName + Environment.NewLine;
    
    
    
                    //linhaA_Escrever = linhaA_Escrever + "Pdf4: " + Results[0].PDF.InvoicePdf.Length + Environment.NewLine;
    
                    //linhaA_Escrever = linhaA_Escrever + "2" + Environment.NewLine;
    
    
                    ////linhaA_Escrever = linhaA_Escrever + "Nr Fatura: " + Results[0].InvoiceResultNumber + Environment.NewLine;
    
                    ////linhaA_Escrever = linhaA_Escrever + "3" + Environment.NewLine;
    
    
                    //linhaA_Escrever = linhaA_Escrever + "Resultado: " + ResultStatus;
    
                    streamWriter.WriteLine(linhaA_Escrever);
    
                    //Ws_Tesouraria.RegisterLogisticInvoiceResult RegisterLogisticInvoiceResult = new Ws_Tesouraria.RegisterLogisticInvoiceResult();
    
                    //RegisterLogisticInvoiceResult.CorrelationId = CorrelationId;
                    //RegisterLogisticInvoiceResult.ResultStatus = ResultStatus;
                    //RegisterLogisticInvoiceResult.Results = Results;
                    //RegisterLogisticInvoiceResult.GeneralMessages = GeneralMessages;
    
                    //Ws_Tesouraria.WS_NotasCobranca WS = new Ws_Tesouraria.WS_NotasCobranca();
    
                    //WS.RespostaFatura(RegisterLogisticInvoiceResult);
                }
                catch (Exception ex)
                {
                    //linhaA_Escrever = linhaA_Escrever + Environment.NewLine + " Erro: " + ex;
                    //streamWriter.WriteLine(linhaA_Escrever);
                }
                finally
                {
                    streamWriter.Close();
                    streamWriter.Dispose();
                }
    
            }
        }
    }

    and one of the generated WSDL's:

    <wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="urn:espap.gerfip.ilcr.v1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:espap.gerfip.ilcr.v1">
    <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="urn:espap.gerfip.ilcr.v1">
    <s:element name="RegisterLogisticInvoiceResult">
    <s:complexType>
    <s:attribute form="unqualified" name="CorrelationId" type="s:string"/>
    </s:complexType>
    </s:element>
    </s:schema>
    </wsdl:types>
    <wsdl:message name="RegisterLogisticInvoiceResultSoapIn">
    <wsdl:part name="parameters" element="tns:RegisterLogisticInvoiceResult"/>
    </wsdl:message>
    <wsdl:portType name="CallBackReceitaSoap">
    <wsdl:operation name="RegisterLogisticInvoiceResult">
    <wsdl:input message="tns:RegisterLogisticInvoiceResultSoapIn"/>
    </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="CallBackReceitaSoap" type="tns:CallBackReceitaSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="RegisterLogisticInvoiceResult">
    <soap:operation soapAction="urn:espap.gerfip.ilcr.v1/RegisterLogisticInvoiceResult" style="document"/>
    <wsdl:input>
    <soap:body use="literal"/>
    </wsdl:input>
    </wsdl:operation>
    </wsdl:binding>
    <wsdl:binding name="CallBackReceitaSoap12" type="tns:CallBackReceitaSoap">
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="RegisterLogisticInvoiceResult">
    <soap12:operation soapAction="urn:espap.gerfip.ilcr.v1/RegisterLogisticInvoiceResult" style="document"/>
    <wsdl:input>
    <soap12:body use="literal"/>
    </wsdl:input>
    </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="CallBackReceita">
    <wsdl:port name="CallBackReceitaSoap" binding="tns:CallBackReceitaSoap">
    <soap:address location="http://srvsicofdv/wsgerfip/callbackReceita.asmx"/>
    </wsdl:port>
    <wsdl:port name="CallBackReceitaSoap12" binding="tns:CallBackReceitaSoap12">
    <soap12:address location="http://srvsicofdv/wsgerfip/callbackReceita.asmx"/>
    </wsdl:port>
    </wsdl:service>
    </wsdl:definitions>

    We kinda tried everyhing and we are not able to find a solution for this... everytime our method is being called we dont have nothing in the input parameters... and when the cliend send us the WSDL that they used to send to our method infact the attributes are there. This is the WSDL the client wants to send to us, so our WSDL must accept this:

    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">SaveLogisticInvoiceResult</a:Action><h:ContextHeader xmlns:h="urn:GeRAP.Services.GSE.ContextHeaderExtension" xmlns="urn:GeRAP.Services.GSE.ContextHeaderExtension" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><BusinessAxis><CompanyCode>5983</CompanyCode><OrganizationalUnit>ADSE</OrganizationalUnit><Entity xsi:nil="true" /><ProcessActivity xsi:nil="true" /><ProcessId xsi:nil="true" /></BusinessAxis><ChannelAxis><ComunicationChannel>www</ComunicationChannel><Security>SSL</Security></ChannelAxis><IdentityAxis><Group xsi:nil="true" /><User>pp\service.pp.adse</User></IdentityAxis><SubscriprionAxis><Application>ADSE</Application><ApplicationContext>ILCR</ApplicationContext></SubscriprionAxis></h:ContextHeader><GseInternalHeader xmlns="urn:eSPap.Services.GSE.Internal" /><dnh0:DynamicChannelHeader xmlns:dnh0="urn:eSPap.Services.GSE.DynamicChannelExtension"><dnh0:CorrelationToken>ILCR_SERVICE.PP.ADSE_5983</dnh0:CorrelationToken></dnh0:DynamicChannelHeader><a:MessageID>urn:uuid:8886fa85-367b-48f5-a37f-232f57376875</a:MessageID><a:To s:mustUnderstand="1">https://pp-gseb2b.gerall.pt/TimeKeepingCallbacks</a:To></s:Header><s:Body><RegisterLogisticInvoiceResult xmlns="urn:espap.gerfip.ilcr.v1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <CorrelationId xmlns="">1721027</CorrelationId>
      <ResultStatus xmlns="">1</ResultStatus>
      <Results xmlns="">
        <Result>
          <DocumentId>1</DocumentId>
          <SaleOrderResultNumber>3151100234</SaleOrderResultNumber>
          <InvoiceResultNumber>3155000183</InvoiceResultNumber>
          <PDF>
            <InvoicePdfName>DFLOG3155000183201801181901.pdf</InvoicePdfName>
            <InvoicePdf>A BIG SEQUENCE OF BYTES IS HERE BUT I REMOVED FOR TURNING THIS READ FRIENDLY</InvoicePdf>
          </PDF>
          <InvoiceMessages>
            <Message>
              <Type>Warning</Type>
              <Code>MW010</Code>
              <Text>Item 1 - O campo Montante da condição não está preenchido.</Text>
            </Message>
            <Message>
              <Type>Information</Type>
              <Code>MW026</Code>
              <Text>Mensagens Fatura/Ordem Venda</Text>
            </Message>
            <Message>
              <Type>Information</Type>
              <Code>V1311</Code>
              <Text>Ordem standard 3151100234 foi gravado(a)</Text>
            </Message>
            <Message>
              <Type>Information</Type>
              <Code>VF311</Code>
              <Text>Documento 3155000183 foi gravado</Text>
            </Message>
          </InvoiceMessages>
          <TotalValue>55.00</TotalValue>
        </Result>
      </Results>
      <GeneralMessages xmlns="" />
    </RegisterLogisticInvoiceResult></s:Body></s:Envelope>

    original post is here: StackOverflow original post

    Can you guys please give us some hint?

    Thanks in advance,

    VC

    Monday, January 22, 2018 4:18 PM

All replies

  • User1168443798 posted

    Hi Vincent,

    >> expose a Web Service method to another company

    Could you share us how the company call your Service? And did they get any error while calling your current service?

    In general, we create a Web Service, then client generates the client code by wsdl, and call method by generated code. It is strange to create a service to meet the client call.

    As the link below, while the default value of elementFormDefault is unqualified, the .NET Framework effectively treats the default as qualified, while still honoring the use of unqualified.

    # https://msdn.microsoft.com/en-us/library/dzssyc4x(v=vs.100).aspx?f=255&mspperror=-2147217396#Anchor_3

    It seems to be controlled by .NET Framework.

    I would suggest you make two tests below, and share us the result.

    1. Generate the client by current wsdl, is there any error while calling service?
    2. Save the current wsdl, modify the wsdl to be your expected result, generate the client code, is there any error while calling service? Best Regards,

    Edward

    Tuesday, January 23, 2018 6:23 AM