views:

214

answers:

1

I have a web service that returns a simple object:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.4927")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.SoapTypeAttribute(Namespace="urn:CHAMADO")]
public partial class STRUCCHAMADOOUT : object, System.ComponentModel.INotifyPropertyChanged {

    private string cODField;

    private string mSGField;

    /// <remarks/>
    public string COD {
        get {
            return this.cODField;
        }
        set {
            this.cODField = value;
            this.RaisePropertyChanged("COD");
        }
    }

    /// <remarks/>
    public string MSG {
        get {
            return this.mSGField;
        }
        set {
            this.mSGField = value;
            this.RaisePropertyChanged("MSG");
        }
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName) {
        System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
        if ((propertyChanged != null)) {
            propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
}

this class was generated by wsdl.exe, based on a wsdl file provided by the client. This is the web method:

[WebMethod(MessageName="CHAMADORequest")]
[SoapRpcMethod(
 Action = "urn:CHAMADO#CHAMADO",
 RequestNamespace = "urn:CHAMADO",
 RequestElementName = "CHAMADO",
 ResponseNamespace = "",
 ResponseElementName = "return",
 Use = SoapBindingUse.Literal
)]
[return: XmlElement("return")]
public STRUCCHAMADOOUT CHAMADO(STRUCCHAMADOIN ENTRADA)
{
    STRUCCHAMADOOUT result = new STRUCCHAMADOOUT();
    try {
        string str = Util.GetRequestXML();
        persist(getResult<Entidades.Chamado>(str, "ENTRADA", string.Empty));

        result.COD = "1";
        result.MSG = "Operação realizada com sucesso";
    } catch (Exception ex) {
        result.COD = "0";
        result.MSG = ex.Message + Environment.NewLine + ex.StackTrace;
    }

    return result;
}

The client is saying that his system is raising an error because the service response has namespaces declaration, just like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<CHAMADOResponse xmlns="urn:CHAMADO" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
    <return xmlns="">
        <COD xmlns="urn:CHAMADO">1</COD> 
        <MSG xmlns="urn:CHAMADO">Operação realizada com sucesso</MSG> 
    </return>
</CHAMADOResponse>

Now, I managed to remove the namespaces from COD and MSG by applying the attriute WebServiceBinding(ConformsTo = WsiProfiles.None) to the service's class and setting ResponseNamespace to an empty string. But CHAMADOResponse still have the namespaces declaration. I'm pretty sure that it should not be done like that. In fact, I don't believe that the namespaces are the problem at all. This project has been hard since the begining, as we had to create services that matched legacy wsdl.

My question is: is there a way that I could remove all that namespaces declaration from the web service response?

Edit

I've logged the server's response and got this:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
    <soap:Body>
        <CHAMADOResponse>
            <return>
                <COD>1</COD>
                <MSG>Operação realizada com sucesso</MSG>
            </return>
        </CHAMADOResponse>
    </soap:Body>
</soap:Envelope>

There's no namespace declaration in the message's body. But the client says that he received this:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!-- Request Message Mapping --> 
<CHAMADOResponse xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'&gt;
    <return>
        <COD>1</COD>
        <MSG>Operação realizada com sucesso</MSG>
    </return>
</CHAMADOResponse>

Am I missing something here?

A: 

Fernando,

I have run into a similar situtation with one our legacy systems (UniVerse) in which it does not have a true XML parser but a homegrown system that works via raw string matching. The solution we found to work is to implement IXmlSerializable in the classes that will be transmitted to the system and when writing out to the XmlWriter we can control what namespaces get added. An example of one of these implementations is below.

/// <summary>
/// Serialize the state to XML
/// </summary>
/// <param name="writer">The writer to write the state</param>
public void WriteXml(XmlWriter writer)
{
    writer.WriteElementString("TERMINATION_STATUS", Status);
    writer.WriteElementString("TRANS_SEQ_NUM", Sequence.ToString());
    writer.WriteElementString("INTRN_SEQ_NUM", Id.ToString());
    writer.WriteElementString("CMRCL_FLAG", IsCommercialCard.ToString());
    writer.WriteElementString("AUTH_CODE", Authorization);
    writer.WriteElementString("CMRCL_TYPE", CommericalFlag.ToString());
    writer.WriteElementString("RESULT_CODE", ResultCode.ToString());
    writer.WriteElementString("TROUTD", RoutingId.ToString());
    writer.WriteElementString("RESPONSE_TEXT", Message);
    writer.WriteElementString("REFERENCE", ProcessorReferenceCode);
    writer.WriteElementString("PAYMENT_MEDIA", PaymentMedia);
    writer.WriteElementString("RESULT", Result.ToString().ToUpper());
    if (Error != null)
    {
        writer.WriteStartElement("ERROR");
        writer.WriteElementString("ERROR_CODE", Error.Code);
        writer.WriteElementString("ERROR_DESCRIPTION", Error.Description);
        writer.WriteEndElement();
    }
}

Again since it is a custom situtation it my not help but it is easy enough to try.

Tedford