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
Related
I am building an API using the WebAPI in ASP.NET MVC 4.0. I have built model classes based on sample XML supplied by my Business Analyst using the new, super smart Paste XML as Classes feature.
The problem is, when my client Accepts application/xml, the serialized response doesn't look like the original XML.
I have manually deserialized and serialized some XML (roundtrip) using the XMLSerializer, and although its better, closer to the original, it still lacks some namespace prefixes.
How can I ensure the output is exactly on spec.?
Firstly, you'll need to ensure the WebAPI is using the XmlSerializer to format your WebAPI responses, or at least use the XmlSerializer just for this resource/API.
In the WebApiConfig.cs file you'll find the route registration stuff and also some commented-out code.
Add under that chunk, add the following:
var xmlSerializer = new XmlSerializer(typeof(FruitXmlModel));
config.Formatters.XmlFormatter.SetSerializer<FruitXmlModel>(xmlSerializer);
This will specify the old XmlSerializer be used when serializing the FruitXmlModel CLR type. Note that you'll probably need to reference the XML serialization assemblies.
Next, you'll need to add this code to the class in your model that represents the element in your XML that begins the new namespace.
...
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces Namespaces = new XmlSerializerNamespaces();
public FruitXmlModel() // ctor for one of my models
{
this.Namespaces.Add("banana", "http://www.fruitschema.org/banana");
}
...
If you've used the Paste XML as Classes feature, then this class should already be annotated with the correct attributes XmlTypeAttribute with the correct namespace set.
All being well, this simple change will provide the WebAPI and the XmlSerializer all that's needed to produce the properly prefixed XML output.
I wish you good luck, Luke, hope to meet again soon.
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 used sudzc to access web services. However the jboss server side didn't like the soap message generated by sudzc. I suspect that this issue is about namespace... Have anybody exprienced this before?
I had the same problem and was able to fix it by removing the default namespace (xmlns=) altogether and search/replacing all method names, adding an explicit namespace as prefix
to all names.
The main differences I see is Sudzc not including an empty header, and uses different namespaces such as soap instead of soapenv as well as set the default namespace of the document. I have no experience with JBoss but it may not be able to handle these differences (although I would think it would) but you can first try including an empty header. SudzC is open source if you want to check out what is happening.
Check the response from web service. Then modify the source code according to the response error. Check this post as an example.
sudzC SOAP web service namespace problem
I want to remove the default xmlns (namespace) added to my service's response (see image below)
Is there a way to do this? This because in order to consume this service from a C# windows app, I have to add the namespace to every data object's header - DataContract that I will be serializing.
I think if you just use
[DataContract(Namespace="")]
on the Bookmarks class, that should do it.
I just tried this and got the following:
<CompositeType xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<BoolValue>true</BoolValue>
<StringValue>Hello </StringValue>
</CompositeType>
Actually, WCF REST Contrib proved to be the perfect solution using their PoxDataContract.
Expanding on #Tawani's answer, if you want to support attributes or otherwise customize your XML serialization you can easily extend WcfRestContrib by creating a custom IWebFormatter. Here's my answer to a similar question explaining how to do this using an XmlSerializer.