How to avoid html codes in wcf xml response? - wcf

i wrote one method for getting details.in rest client getting response like this.
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/"><Meetings>
<Meeting>
<Id>1</Id>
<Name>Meeting1</Name>
<Place>SR Nagar</Place>
<Time>12/4/12 12:30pm</Time>
</Meeting>
<Meeting>
<Id>2</Id>
<Name>Meeting2</Name>
<Place>Begumpet</Place>
<Time>12/4/12 1:00pm</Time>
</Meeting>
</Meetings>
</string>
in rendered html getting proper.
<Meetings> <Meeting> <Id>1</Id> <Name>Meeting1</Name> <Place>SR Nagar</Place> <Time>12/4/12 12:30pm</Time> </Meeting> <Meeting> <Id>2</Id> <Name>Meeting2</Name> <Place>Begumpet</Place> <Time>12/4/12 1:00pm</Time> </Meeting> </Meetings>
How to handle it in code in wcf to avoid <

Your service operation returns string and you are writing XML to that string. It will always look like that and browser shows it correctly only because it hides string tag and unescapes the content.
To return real XML you must not use string as return value. Try to use for example XElement.

In your [OperationContract] method, instead of returning a string, return an array of Meeting objects. The Meeting class should contain the properties you'd like to return:
[DataContract]
public class Meeting
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Place { get; set; }
// etc...
}
If you're using .NET 4.0 and up, the [DataContract] and [DataMember] attributes are not required.

Related

Entity Design for web service

My client will be sending the request as described below in SOAP format.
<RequestTimestamp>2014-08-22T11:28:00Z</RequestTimestamp>
<SystemID>TestProcessor</SystemID>
<Version>1<Version>
<QWID>201507080000001</QWID>
<QWID>201507080000010</QWID>
<QWID>201507080000001</QWID>
<QWID>201507080000010</QWID>
<QWID>201507080000001</QWID>
<QWID>201507080000010</QWID>
<CHL>201507080000010</CHL>
In every request, QWID should come as batch and I proposed below entity design to adopt above data.
public class APIRequest
{
[DataMember]
public DateTime RequestTimestamp;
[DataMember]
public string SystemID;
[DataMember]
public int Version;
[DataMember]
public string[] QWID;
[DataMember]
public string CHL;
}
With above entity design, SOAP request generated as
<request xmlns:a="http://schemas.datacontract.org/2004/07/QWID.Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:RequestTimestamp>0001-01-01T00:00:00</a:RequestTimestamp>
<a:SystemID>WireSystem_001</a:SystemID>
<a:Version>0</a:Version>
<a:QWID xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<b:string>20141023010232_ORG99000002_CTR.fedwire</b:string>
<b:string>20141023010842_ORG99000001_CTR.fedwire</b:string>
</a:QWID>
</request>
My client expecting the SOAP request in the form of <QWID>201507080000001</QWID> instead of coming under <QWID><b:string>20141023010232_ORG99000002_CTR.fedwire</b:string> </QWID> as string tag.
How do i do the entity design (without grouping of QWID) to achieve client expectation as described above? Please help me on this?

How can I bind sample data from a variable of type List<string> inside a class to the XAML (design) page

I've been making use of binding to sample data so that I can get a feel of what the app is going to look like during runtime.
Things have been going great until I had to bind to a List<>. I made a sample application to demonstrate the problem.
Person.cs
public string FullName { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
public List<string> Friends { get; set; }
MainViewModelSampleData.xaml
<vm:MainViewModel
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:StackoverflowQuestion.ViewModels">
<vm:MainViewModel.Items>
<vm:Person FullName="Homer Simpson" Age="45" Sex="Male" />
<vm:Person FullName="Bruce Wayne" Age="32" Sex="Male" Friends="" />
</vm:MainViewModel.Items>
I can get the design view to correctly shows the string FullName, int Age, and string Sex.
What I don't know and can't figure out is how to bind data from List<string> Friends so that I can view it on the design view.
The solution is 'extracting' the Friends value
<vm:Person FullName="Bruce Wayne" Age="32" Sex="Male">
<vm:Person.Friends>
<x:String>First</x:String>
<x:String>Second</x:String>
</vm:Person.Friends>
Depending on the version of App x:String is necessary or the literal directly
<vm:Person FullName="Bruce Wayne" Age="32" Sex="Male">
<vm:Person.Friends>
First
Second
</vm:Person.Friends>
And the last option is add the following namespace
xmlns:System="clr-namespace:System;assembly=mscorlib"
<phone:PhoneApplicationPage.DataContext>
<local:Person Name="ww">
<local:Person.Friends>
<System:String>one</System:String>
<System:String>one</System:String>
</local:Person.Friends>
</local:Person>

how to set attributes in soap format WCF

how to set attributes for soap message:
for example my soap messg look like following
<doPaymentResult xmlns:a="http://schemas.datacontract.org/2004/07/MemoService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:errors i:nil="true"/>
<a:messages>
<a:MessageEntity>
<a:codeField>Payment Request Successful</a:codeField>
<a:textField i:nil="true" xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
</a:MessageEntity>
</a:messages>
<a:requestTrackCode>20130430T125904R14646</a:requestTrackCode>
<a:status i:nil="true"/>
</doPaymentResult>
</doPaymentResponse>
but i need a soap message which take attributes not elements
like following
<doPaymentResult xmlns:a="http://schemas.datacontract.org/2004/07/MemoService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:errors i:nil="true"/>
<a:messages>
<a:MessageEntity codeField="Payment Request Successful">
some text here
</a:MessageEntity>
</a:messages>
<a:requestTrackCode>20130430T125904R14646</a:requestTrackCode>
<a:status i:nil="true"/>
</doPaymentResult>
</doPaymentResponse>
I am using datacontract in class.
It’s a common problem – you want to return an object from a WCF service as XML, but you either want, or need, to deliver some or all of the property values as XML Attributes instead of XML Elements; but you can’t because the DataContractSerializer doesn’t support attributes (you’re most likely to have seen this StackOverflow QA if you’ve done a web search). Most likely you’ve then migrated all your WCF service code to using the XmlSerializer (with all the XmlElement/XmlAttribute/XmlType attributes et al) – and you’ve cursed loudly.
Well, I’m here to rescue you, because it is possible – and the answer to the problem is actually inferred from the MSDN article entitled ‘Types supported by the Data Contract Serializer’.
The example I’m going to give is purely for illustration purposes only. I don’t have a lot of time, so work with me!
•Create a new Asp.Net WCF service application, you can use Cassini as your web server (probably easier – otherwise you might have to enable Asp.Net compatibility mode).
•Open the web.config and delete the element that was created for the new service.
•The interface and implementation model for this example is overkill. Move the [ServiceContract] and [OperationContract] declarations from the interface that was created for you new service to the class that was also created. Delete the interface.
•Open the .svc markup file and add the following at the end: Factory="System.ServiceModel.Activation.WebServiceHostFactory" – this enables the zero-configuration WCF model for this service (we’re going to create a RESTful service).
•Paste the following class declarations into your svc codebehind:
public interface IExampleData
{
string Description { get; set; }
string Name { get; set; }
int ID { get; set; }
}
public class ExampleData : IExampleData
{
public string Description { get; set; }
public string Name { get; set; }
public int ID { get; set; }
}
public class ExampleDataAttributed : ExampleData, IXmlSerializable
{
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
//implement if remote callers are going to pass your object in
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteAttributeString("id", ID.ToString());
writer.WriteAttributeString("name", Name);
//we'll keep the description as an element as it could be long.
writer.WriteElementString("description", Description);
}
#endregion
}
Just to demonstrate the point, the class that will be part-serialized to attributes simply derives from one that will be serialized as normal.
•Now add the following two methods to your service class:
[OperationContract]
[WebGet(UriTemplate = "/test1")]
public ExampleData Test1()
{
return new ExampleData() { ID = 1,
Name = "Element-centric",
Description =
"The contents of this item are entirely serialized to elements - as normal" };
}
[OperationContract]
[WebGet(UriTemplate = "/test2")]
public ExampleDataAttributed Test2()
{
return new ExampleData_Attributed() { ID = 2,
Name = "Mixed",
Description =
"Everything except this description will be serialized to attributes" };
}
Cover, and bake for 40 minutes (that is – Build it).
If you left your service as Service1.svc, then run it and open up IE and browse to http://localhost:[port of cassini]/test1
The result should look something like this:
<JSLabs.ExampleData
xmlns="http://schemas.datacontract.org/2004/07/ExampleNamespace"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Description>
The contents of this item are entirely serialized to elements - as normal
</Description>
<ID>
1
</ID>
<Name>
Element-centric
</Name>
</JSLabs.ExampleData>
Now browse to http://localhost:[port of cassini]/test2
<JSLabs.ExampleDataAttributed id="2" name="Mixed"
xmlns="http://schemas.datacontract.org/2004/07/JobServe.Labs.Web">
<description>Everything except this description will be
serialized to attributes</description>
</JSLabs.ExampleDataAttributed>
It’s made a little less impressive by that nasty ‘orrible “xmlns=” attribute that the WCF data contract serializer automatically puts on the type – but, as you can see, the ‘ID’ and ‘Name’ properties have indeed been pushed out as attributes!
We could have made both methods return IExampleData and then used the KnownType attribute on that interface in order to get it to support either (according to what the code of the methods returned).
To support deserializing an object from the attributes, all you have to do is to implement the IXmlSerializable.ReadXml method.
Finally, as the aforementioned MSDN article says about the supported types – you should also be able to use XmlElement/XmlNode types as a way of representing XML directly – the DataContractSerializer, like in this case, take the short route and simply gets the Xml.
This also shouldn’t affect JSON formatting if you’re dual-outputting objects for either XML or JSON clients.
Check the source of this article

DataContractSerializer: preserve string member that happens to be raw xml?

I'm a little inexperienced with the DataContract paradigm, and I'm running into a deserialization problem. I have a field that's a string, but it contains xml and it's not being deserialized correctly. I have a feeling that it's because the DCS is treating it as input to the serializer and not as an opaque string object.
Is there some way to mark a DataMember in code to say "This thing is a string, don't treat its contents as xml" similar to XmlIgnore?
Thanks!
Well, the equivalent to [XmlIgnore] is just not putting a [DataMember] on your property/field - if you're decorating everything with [DataMember] otherwise.
But I don't see how you could tell the DataContractSerializer to treat the property as an opaque string and nothing else.
You could try to have a separate property which adds <![CDATA[ before and ]]> after your content string, and serialize that property instead of your raw XML property (by decorating that new property with the [DataMember] attribute).
Something like this:
public string XmlContent { get; set; }
[DataMember]
public string XmlContentSafe
{
get { return "<![CDATA[" + XmlContent + "]]>"; }
}
Maybe that way you can trick the DCS ? (never tried it myself - just guessing....)
Turns out the easiest way to do this was just to cast the xml field coming from sql server to a varchar(max) when retrieving it from the database.
CAST(CONVERT(XML,[RawXml],0) AS VARCHAR(MAX)) AS RawXml
In this case, the serializer seems to be ignoring it as desired.
Thanks for the help though!
There is an easy way to do, just declare the property with raw XML as XmlElement
[DataMember]
public XmlElement RawXML { private get; set; }

WCF Deserializing Problem

My "Location" object isnt getting serialized in my WCF datacontract, however, all other variables are being set properly. When I try to output a variable in the location object I get the "Object reference not set to an instance of an object" error
My DataContract:
[DataContract(Namespace = "")]
public class CalcRequest : BaseRequest
{
[DataMember(Name = "Products")]
public List<Product> products;
[DataMember(Name = "Location")]
public Location location;
[DataMember(Name = "ShippingMethod")]
public string shippingMethod;
[DataMember(Name = "SystemPromotionCode")]
public string systemPromotionCode;
[DataMember(Name = "UserPromotionCode")]
public string userPromotionCode;
}
The "Location" object:
[DataContract(Name = "Location", Namespace = "")]
public class Location
{
public Location()
{
// do nothing
}
[DataMember(Name = "Country")]
public string country;
[DataMember(Name = "StateProvince")]
public string stateProvince;
[DataMember(Name = "PostalCode")]
public string postalCode;
}
my XML request (version, msgtype, processorID, and customerid are in my "BaseRequest"):
<root>
<Version>1.0</Version>
<MsgType>type</MsgType>
<ProcessorId>28000</ProcessorId>
<CustomerId>28000</CustomerId>
<Products>
<Product>
<SKU>1</SKU>
<Price>2999</Price>
<ProductName>name1</ProductName>
<Quantity>1</Quantity>
</Product>
<Product>
<SKU>2</SKU>
<Price>1999</Price>
<ProductName>name2</ProductName>
<Quantity>1</Quantity>
</Product>
</Products>
<Location>
<Country>US</Country>
<StateProvince>OH</StateProvince>
<PostalCode>44060</PostalCode>
</Location>
<ShippingMethod>USPS-NextDay</ShippingMethod>
<SystemPromotionCode>CD1244578</SystemPromotionCode>
<UserPromotionCode>2FDGRR</UserPromotionCode>
</root>
... Not sure why this isn't working... any help would be appreciated.
I don't understand what you think is missing, really....
(stuff deleted - not relevant)
UPDATE: to make sure the order of the elements in the XML is correct and interpreted in the right order, you might want to add Order=xxx statement to the data member attributes-
Otherwise, the data contract serializer will serialize (and deserialize) in alphabetical order (other than the XmlSerializer which serializes in the order the fields appear).
Alphabetical order is case-sensitive,i.e. any upper case characters are considered before any low-case characters.
If you have multiple elements of the same order (that's not a problem), then they'll be serialized alphabetically within their order (e.g. all elements of Order=1 will be serialized in an alphabetical fashion - then all elements with Order=2 and so on).
For derived classes, properties of base class will be serialized first(in alphabetical order) and properties of derived class later(also in alphabetical order).