Chris Allison
Chris Allison

Reputation: 73

Returning Raw XML From a WCF Service

I am trying to get my webservice to reply with a particular form of XML, which I thought I could do with just putting the data in a string and returning this to the webpage.

I am trying to return:

<tradeHistory><trade TradeId="1933" ExtId="1933" instrument="EUA" quantity="1500" setType="Escrow" TradeDate="12/02/2010" DeliveryDt="13/02/2010" PaymentDt="12/02/2010" type="BUY" pricePerUnit="6.81" GrossConsid="10320" currency="EUR"/></tradeHistory>

But when I return the string I'm getting:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">&lt;tradeHistory&gt;&lt;trade tradeid="1933" ExtId="1933" Instrument="EUA" quantity"1500" setType="Escrow" TradeDate="24/05/2011" DeliveryDt="25/05/2011" PaymentDt="25/05/2011" type"BUY" pricePerUnit="6.81" GrossConsid="10320" currency="EUR" /&gt;&lt;tradeHistory&gt</string>

Any ideas on how I can achieve this goal? It would be nice not to have the tag but I can live with that but the issue I have is that its not formatting the string correctly its reading the opening and closing tags as special characters

My Service is:

<ServiceContract(Namespace:="")>
Public Interface ITradePortal

<WebGet(UriTemplate:="Reporting/GetClientTrades/{ClientID}")>
    <OperationContract()>
    Function GetClientTrades(ByVal ClientID As String) As String
End Interface

My implementation is:

<ServiceBehavior(ConcurrencyMode:=System.ServiceModel.ConcurrencyMode.Multiple, InstanceContextMode:=InstanceContextMode.Single, _
Namespace:="")>
<XmlSerializerFormat()>

and my config file:

<services>
            <service behaviorConfiguration="Default" name="CFP_Web_Lib.TradePortal">
              <host>
                <baseAddresses>
                  <add baseAddress="http://localhost:8686/TradePortal"/>
                </baseAddresses>
              </host>
                <endpoint address="" binding="webHttpBinding"
                     contract="CFP_Web_Lib.ITradePortal"
                          behaviorConfiguration="web"
                     />
              <endpoint address="Operations/" binding="wsDualHttpBinding"
                   contract="CFP_Web_Lib.ITradeOperations"/>
                   </service>
        </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Default">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
        </endpointBehaviors>
    </behaviors>
    <bindings>
      <wsDualHttpBinding>
        <binding name="WSDualHttpBinding_IPubSubService" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
          maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
          textEncoding="utf-8" useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00" />
          <security mode="Message">
            <message clientCredentialType="Windows" negotiateServiceCredential="true"
              algorithmSuite="Default" />
          </security>
        </binding>
      </wsDualHttpBinding>
      <mexHttpBinding>
        <binding name="NewBinding0" />
      </mexHttpBinding>
    </bindings>

Upvotes: 2

Views: 5710

Answers (1)

carlosfigueira
carlosfigueira

Reputation: 87218

The default return format is XML, so when your operation returns String, it will be formatted as XML - with the string content inside the element. The easiest way to return anything would be to use the raw programming model. Your operation would look something like this:

<WebGet(UriTemplate:="Reporting/GetClientTrades/{ClientID}")> _
<OperationContract()> _
Function GetClientTrades(ByVal ClientID As String) As Stream

And the implementation:

Function GetClientTraces(ByVal ClientID As String) As Stream Implements ITradePortal.GetClientTraces
    Dim result as String = "<tradeHistory>...</tradeHistory>"
    WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml" ' or anything you need
    return new MemoryStream(Encoding.UTF8.GetBytes(result))
End Function

Another option, if you don't want to deal with Streams, is to change the return type to XmlElement (or XElement). That is written out "as is", so you can return arbitrary XML.

Yet another option is to create classes to hold that data. The TradeHistory class would hold a reference to a "Trade" instance, and the Trade class would have many fields declared with the attribute. The operation would then have a return type of TradeHistory.

Upvotes: 4

Related Questions