I need to intercept the response of a service created using WCF with webHttpBinding (REST based service).
Now I want the XML emitted in a customized way. For e.g, currently a service method returns output like this:
<User xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<UserCellInfo>+91-98102239</UserCellInfo>
<UserDepartment>.NET Projects</UserDepartment>
<UserID>A10129</UserID>
<UserName>Jeff Thomson</UserName>
</User>
but I want it in a different custom way.Something like below
<?xml version="1.0" encoding="UTF-8"?>
<rsp>
<User>
<UserCellInfo>+91-98102239</UserCellInfo>
<UserDepartment>.NET Projects</UserDepartment>
<UserId>A10129</UserId>
<UserName>Jeff Thomson</UserName>
</User>
</rsp>
In MSDN, I read that I need to use IDispatchMessageInspector to intercept the XML that goes out. But I couldn't find any code reference or example for it.
Any good ideas how to achieve this?
So I assume your WCF service method returns an instance of a User object in this method call, right?
Why not just define a wrapper class called rsp that contains the User instance? Then returning the rsp object would render in the desired style. Just a nice clean wrapper - no messy XML manipulation on the fly......
Related
Coming to new to WebAPI and i am having a namespace issue
I have a POST method in my WebAPI that accepts an object as JSON or XML however the method is to be consumed by a BizTalk service which adds its own namespace to the xml.
<ns0:Person xmlns:ns0="http://Acme/Esb/DestinationSchemas/Person/v1.0">
<WorkEmail>Someemail#acme.com</WorkEmail>
<PersonId>10</PersonId>
<UserName>Shouldhaveone</UserName>
</ns0:Person>
and my WebAPI Post method is defined as follows
<Person xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersonId>10</PersonId>
<WorkEmail>Someemail#acme.com</WorkEmail>
<UserName>Shouldhaveone</UserName>
</Person>
As you can see the namespaces are different and whenever the Post called the object is null. Can someone please advise me of the best approach to ignore the namespaces of incoming requests
Many thanks
Option 1 is to switch to using XmlSerializer in GlobalConfiguration:
config.Formatters.XmlFormatter.UseXmlSerializer = true;
Option 2 is to decorate your models with
[DataContract(Namespace="")]
(and if you do so, you'd need to decorate the members with [DataMember] attributes).
original post
Remove namespace in XML from ASP.NET Web API
The answer was to add XmlMediaFormatter to ignore namespaces
all thanks to Jan Jonas
http://blog.janjonas.net/2012-09-07/asp_net-mvc_4_rc-web-api-implementing-custom-xmlmediatypeformatter-ignore-xml-namespace
My web services are rusty so I hope I'm just missing something kind of obvious.
I have a WCF service that, in part, relays calls it receives to a third party SOAP service. The service receives an object that matches the body of the SOAP message that needs to be sent.
I've added a service reference based on the SOAP service's WSDL to the project and created and instance of the service proxy class. The service method I want to call has 30+ parameters.
I could call it with MyService.TheMethod(obj.value1, obj.value2, obj.value3...), but it would be nice to just pass the original object on or XML serialize it and pass the XML as a body.
Is there something that would allow an easier approach or do I need to individually pass obj's properties onto the SOAP method?
UPDATE
Clarifying the underlying issue.
My .NET service accepts something "Group"
public class Person { string Name; int Age;}
public class Group { string Name; Person[] Individuals; }
I then need to call the third party web service (TPWS). The proxy class generated from the WSDL winds up like:
public class WSPerson { string Name; uint Age;}
public class WSGroup { string Name; WSPerson[] Individuals; }
I'd been doing earlier prototyping and working with the TPWS through SoapUI and using tags matching my original (.NET) classes' naming:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.myabc123.com" xmlns:ns="http://schemas.datacontract.org/2004/07/" xmlns:sys="http://schemas.datacontract.org/2004/07/System" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<soapenv:Header>
<ws:ServiceCredentials>
<ws:SubscriberId>ABC</ws:SubscriberId>
<ws:SubscriberUser>Joe</ws:SubscriberUser>
<ws:SubscriberPassword>12345</ws:SubscriberPassword>
<!--Optional:-->
<ws:SubscriberIdentityStore></ws:SubscriberIdentityStore>
</ws:ServiceCredentials>
</soapenv:Header>
<soapenv:Body>
<Group>
<Name>Cool People</Name>
<Individuals>
<Person>
<Name>Tom</Name>
<Age>25</Age>
</Person>
<Person>
<Name>Jane</Name>
<Age>27</Age>
</Person>
</Individuals>
</Group>
</soapenv:Body>
</soapenv:Envelope>
There's no easy way to do what you want. If the service you're calling has 30 parameters, you'll just have to call it with 30 parameters.
Perhaps this will help others. I'm pursuing the idea of calling the web service through HTTP POST.
The reason is that this general problem will be repeated in similar ways over and over. I control the incoming data contract and the format of the XML that the 3rd party mapping tool ultimately expects. But it generates its own contract for the service. If it can recognize the raw XML that I can produce through XmlSerializer I won't have to map my class just to get the 3rd party tool to in turn perform its own mapping functions.
Using WCF Restful service with XmlSerializer I get the below response.
<?xml version="1.0" encoding="utf-8"?>
<availabilityResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xyz.com/ABCService">
<availabilityResult>
<title xsi:type="Availability_1">
<titleId>0010327457</titleId>
<availability>
<purchasable>false</purchasable>
<availableCopies>0</availableCopies>
<totalCopies>0</totalCopies>
</availability>
</title>
</availabilityResult>
</availabilityResponse>
(I wish to remove xmlns:xsd, xmlns:xsi and xsi:type tags)
"Availability_1" is one my derived type i used in my code. I really do not want to show this in the response.
I am using XmlSerialzer by specifying [XmlSerializerFormat] at the service contract.
WCF is able to serialize my response properly but the only issue i have is with the extra xmlns tags. Yes, I know they are useful stuff there. But, the client is interested only in the plain xml.
By looking at various posts in stackoverflow i understood i could do this by overriding few of the methods of XmlTextWriter. But the problem I have is how to let the WCF know to use my customXmlWriter (inherited from XmlTextWriter) instead of generic XmlTextWriter while serialization.
How to pass my customXmlTextWriter to the XmlSerializer which i do not have any control at this point.
I just created my data classes and defined the service contract methods from my end but did not have to do any of the serialization stuff from my side as the WCF takes care of it on its own.
A slightly different idea, but it's in the line of separation of concerns, as writing custom serialisers to actually make the responses sort of "invalid" seen from a true compliancy principe can be seen as an anti-pattern.
My idea is to develop your own IIS custom HTTP handlers and add it to the IIS processing pipeline. Doing so, will allow you to expose both the tweaked responses and the fully compliant ones.
The custom HTTP handler could use a simple XSLT to remove the required namespaces.
Have a look at this article to get started - http://www.iis.net/learn/develop/runtime-extensibility/developing-iis-modules-and-handlers-with-the-net-framework
I am building a client in VB.net for calling webservices methods from a partner organisation.
I am following the guidelines at http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soaphttpclientprotocol%28v=VS.71%29.aspx because I can't get it to work using the Web References feature of Visual Studio 2010 (when I try to do that it turns the methods from the WSDL into classes).
I have created a proxy class and can instantiate an object of that class no problem.
However, when I try to call a method which requires arguments I get this error:
Unmarshalling Error: unexpected element (uri:"http://api.service.apimember.emailvision.com/", local:"key"). Expected elements are <{}key>,<{}login>,<{}pwd>
Does anyone have any idea why this might be? (If it's helpful I can post my code and the location of the WSDL.)
(P.S. I can get the whole thing to work fine in PHP using ZF Soap classes, but for various reasons I need to get it to work using .Net)
Edit to add: I have used Wireshark to examine the outgoing and incoming SOAP message to compare them with the messages being sent via SoapUI, where it all works fine.
What this has shown is that my VB client is sending a message where the namespace of the web service I am trying to access is declared as an attribute of the method, and not in the soap:envelope attributes.
Here is an example:
WORKS (produced by SoapUI):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:api="http://api.service.apimember.emailvision.com/">
<soapenv:Header/>
<soapenv:Body>
<api:openApiConnection>
DOESN'T WORK (produced by my VB.net code):
<?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">
<soap:body>
<openApiConnection xmlns="http://api.service.apimember.emailvision.com/">
I think I need to declare the xmlns 'api' in the envelope element, so I need to figure out how to do this in my VB.net code.
OK, turns out I was using System.Web.Services.Protocols.SoapDocumentMethodAttribute but I should have been using System.Web.Services.Protocols.SoapRpcMethodAttribute.
Using the RPC binding style produces the message body format the remote service requires. Having read up a bit about how the attributes in the MS code I was basing my code on were affecting my output I came across this page http://msdn.microsoft.com/en-us/library/k1y9z356(v=vs.80).aspx which led me to changing the binding method, and that works.
I have WCF rest service returning XML/RSS feeds. Some methods return data contracts, some Rss20FeedFormatter, and some are streams.
In all cases XML returns without any indentation. But I have requirement to return it formatted with indentations.
Is it possible to enable XML response indentation for WCF service?
You can load the xml output onto an xmlDocument and use XmlTextWriter to add "indent" settings.
Or you can use a simple xslt to transform the output xml onto the format that you want. for indent use
<xsl:output indent="yes" method="xml"/>
I'm not sure if WCF services can return formatted responses but here's a link to a nice method for formatting XML easily that you could implement from the calling source code.