Deserialize xml element attributes - c#

I'm admittedly learning here, and have made progress in serializing and deserialzing xml.
Question that I have is, how do I access the URI in the XML below?
<address href="/api/juniper/sd/address-management/addresses/98677"
uri="/api/juniper/sd/address-management/addresses/98677">
<name>Any-IPv4</name>
<address-type>ANY_IPV4</address-type>
<description>Predefined any-ipv4 address</description>
<host-name />
<id>98677</id>
</address>
Really not sure how to set that up in my class to deserialize it?
My class right now looks like:
[XmlRoot("address", Namespace = "")]
public class address
{
string _name;
string _editVersion;
string _addressType;
string _ipAddress;
string _description;
string _hostName;
string _zone;
string _addressVersion;
string _definitionType;
string _createdByUserName;
string _lastModifiedByUser;
string _createdTime;
string _lastModifiedTime;
string _id;
[XmlElement(ElementName = "name")]
public string name
{
get { return _name; }
set { _name = value; }
}
[XmlElement(ElementName = "edit-version")]
public string editversion
{
get { return _editVersion; }
set { _editVersion = value; }
}
[XmlElement(ElementName = "address-type")]
public string addresstype
{
get { return _addressType; }
set { _addressType = value; }
}
[XmlElement(ElementName = "ip-address")]
public string ipaddress
{
get { return _ipAddress; }
set { _ipAddress = value; }
}
[XmlElement(ElementName = "description")]
public string description
{
get { return _description; }
set { _description = value; }
}
[XmlElement(ElementName = "host-name")]
public string hostname
{
get { return _hostName; }
set { _hostName = value; }
}
}
Thanks in advance!

Use the XmlAttributeAttribute attribute*
[XmlAttribute]
public string uri
{
get { return _uri; }
set { _uri = value; }
}
If you want to have it serialize it as System.Uri, you'll have to do it with a separate property as Uri is non-serializable.
[XmlAttribute("uri")]
public string SerializedUri
{
get
{
return uri.ToString();
}
set
{
uri = new Uri(value, UriKind.RelativeOrAbsolute);
}
}
[XmlIgnore]
public Uri uri { get; set; }
With this usage, in-code you would read/write directly to the Uri uri property and ignore the SerializedUri property. When passed through the serializer it will ignore that property and instead use the SerializedProperty which will in turn manually serialize/deserialize the Uri uri property.
* (say that 3 times fast)

Related

How to deserialize element that can be single or array?

Got XML that i want to deserialize to Object.
There is no questions if i deserialize only non-multiple value element, but i got no idea what to do with an array of value elements in value element.
There is always UnknownNode with LocalName = #text,
XML to deserialize
<?xml version="1.0" encoding="UTF-8"?>
<issue>
<custom_fields type="array">
<custom_field id="11" name="Version">
<value>7.9.18.31</value>
</custom_field>
<custom_field id="89" name="Tags" multiple="true">
<value type="array">
<value>Tag1</value>
<value>Tag3</value>
<value>Tag6</value>
</value>
</custom_field>
<custom_field id="90" name="started_on">
<value>2017-08-25</value>
</custom_field>
</custom_fields>
</issue>
class i get with xsd.exe
using System.Xml.Serialization;
[XmlRoot(IsNullable=false)]
public partial class issue
{
private object[] itemsField;
[XmlElement("custom_fields", typeof(issueCustom_fields))]
[XmlElement("value", typeof(Value))]
public object[] Items
{
get { return itemsField; }
set { itemsField = value; }
}
}
public class Value
{
private Value[] valueField;
private string typeField;
[XmlElement("value")]
public Value[] value
{
get { return valueField; }
set { valueField = value; }
}
[XmlAttribute]
public string type
{
get { return typeField; }
set { typeField = value; }
}
}
public class issueCustom_fields
{
private issueCustom_fieldsCustom_field[] custom_fieldField;
private string typeField;
[XmlElement("custom_field")]
public issueCustom_fieldsCustom_field[] custom_field
{
get { return custom_fieldField; }
set { custom_fieldField = value; }
}
[XmlAttribute]
public string type
{
get { return typeField; }
set { typeField = value; }
}
}
public class issueCustom_fieldsCustom_field
{
private Value[] valueField;
private string idField;
private string nameField;
private string multipleField;
[XmlElement("value")]
public Value[] value
{
get { return valueField; }
set { valueField = value; }
}
[XmlAttribute]
public string id
{
get { return idField; }
set { idField = value; }
}
[XmlAttribute]
public string name
{
get { return nameField; }
set { nameField = value; }
}
[XmlAttribute]
public string multiple
{
get { return multipleField; }
set { multipleField = value; }
}
}
Deserializing code
var ser = new XmlSerializer(typeof(issue));
var issue = new issue();
using (var sr = new StreamReader("testIssues.xml"))
issue = (issue)ser.Deserialize(sr);
i can get data using:
ser.UnknownNode += (s, ea) =>
{
if (ea.LocalName == "#text" && ea.ObjectBeingDeserialized is Value)
{
Value val = (Value)ea.ObjectBeingDeserialized;
if (val.value == null)
{
val.Val = ea.Text;
}
}
};
but is there a way to get it more smoothe way using just deserialization?
Have you tried to use XmlArrayAttribute?
[XmlArray("value")]
public Value[] Items
{
get { return itemsField; }
set { itemsField = value; }
}
[XmlType("Value")]
public class Value
{
....
}
Check out this question.

DataContractJsonSerializer: Deserialize to different type based on JSON property

I'm using DataContractJsonSerializer to deserialize JSON from a Webservice.
[{"id":2947,"type":"PdfDocument","name":"test.pdf"},
{"id":2945,"type":"ImageDocument","name":"test.jpg", "color": "green"}]
Based on their type, JSON entities can have different properties (for example a color). Currently i use a single model Document for deserialization and PagedCollectionViews to filter what i need to show in the UI.
public class Document : EntityBase
{
private string name;
private string type;
private string color;
public Document()
{
}
[DataMember(Name = "name")]
public string Name
{
get
{
return this.name;
}
set
{
if (this.name != value)
{
this.name = value;
this.OnPropertyChanged("Name");
}
}
}
[DataMember(Name = "type")]
public string Type
{
get
{
return this.type;
}
set
{
if (this.type != value)
{
this.type = value;
this.OnPropertyChanged("Type");
}
}
}
[DataMember(Name = "color")]
public string Color
{
get
{
return this.color;
}
set
{
if (this.color != value)
{
this.color= value;
this.OnPropertyChanged("Color");
}
}
}
}
public class DocumentsViewModel : ViewModelBase
{
public ObservableCollection<Document> Documents { get; set; }
public PagedCollectionView ImageDocuments;
public PrintProjectDetailsViewModel()
{
this.Documents = new ObservableCollection<Document>();
this.ImageDocuments = new PagedCollectionView(Documents);
this.ImageDocuments.Filter = (o) => ((Document)o).Type == "ImageDocument";
}
}
However, that feels "smelly" to me. Is it possible to automatically deserialize to a subclass of Document depending of the JSON value of type?

my error message reads expected class, delegate, enum. interface, or struct [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
namespace MyNamespace
{
class Student
{
private string _name;
private int _phoneNo;
private string _address;
private string _occupation;
private string _courseOfStudy;
private int _duration;
private string _uploadPicture;
}
public string Name
{
get { return _name;}
set { _name = value;}
}
public int PhoneNumber
{
get { return _phoneNo;}
set { _phoneNo = value;}
}
public string Address
{
get { return _address;}
set { _address = value;}
}
public string Occupation
{
get { return _occupation;}
set { _occupation = value;}
}
public string CourseOfStudy
{
get { return _courseOfStudy;}
set { _courseOfStudy = value;}
}
public int Duration
{
get { return _duration;}
set { _duration = value;}
}
public string Uploadpicture
{
get { return _uploadpicture;}
set { _uploadpicture = value;}
}
public Student()
{
_name = "";
_phoneNo = "";
_address = "";
_occupation = "";
_courseOfStudy = "";
_duration = "";
_uploadPicture = "";
System.Windows.Forms.MessageBox.Show("Called Constructor")
}
public Student (String name, int phoneNo, string address, string occupation, string courseOfStudy, int duration, string uploadPicture)
{
_name = name;
_phoneNo = phoneNo;
_address = address;
_occupation = occupation;
_courseOfStudy = courseOfStudy;
_duration = duration;
_uploadPicture = uploadPicture;
}
}
You cannot declare methods outside of a class in C#.
Remove that first }
it is causing the properties below it to appear outside of the class.
As others have pointed out, you have put all your properties and constructors outside the class. Also you have large amounts of unnecessary code for handling the properties, as you are not encapsulating the field values in any way. So they can be rewritten to use auto properties. Try the following rewrite:
namespace MyNamespace
{
class Student
{
public string Name { get; set; }
public int PhoneNumber { get; set; }
public string Address { get; set; }
public string Occupation { get; set; }
public string CourseOfStudy { get; set; }
public int Duration { get; set; }
public string UploadPicture { get; set; }
public Student() : this("", 0, "", "", "", 0, "")
{
MessageBox.Show("Called Constructor");
}
public Student(String name, int phoneNo, string address, string occupation, string courseOfStudy, int duration, string uploadPicture)
{
Name = name;
PhoneNumber = phoneNo;
Address = address;
Occupation = occupation;
CourseOfStudy = courseOfStudy;
Duration = duration;
UploadPicture = uploadPicture;
}
}
}
The members are courrently not inside your class. The curly bracket behind _uploadPicture; } shuld be at the end.
Also, there a some other mistakes:
_uploadpicture should be _uploadPicture in public string Uploadpicture
you are trying to initialise an int with an string (_phoneNo = "";)
Here is the corrected class:
namespace MyNamespace {
class Student {
private string _name;
private int _phoneNo;
private string _address;
private string _occupation;
private string _courseOfStudy;
private int _duration;
private string _uploadPicture;
public string Name {
get {
return _name;
}
set {
_name = value;
}
}
public int PhoneNumber {
get {
return _phoneNo;
}
set {
_phoneNo = value;
}
}
public string Address {
get {
return _address;
}
set {
_address = value;
}
}
public string Occupation {
get {
return _occupation;
}
set {
_occupation = value;
}
}
public string CourseOfStudy {
get {
return _courseOfStudy;
}
set {
_courseOfStudy = value;
}
}
public int Duration {
get {
return _duration;
}
set {
_duration = value;
}
}
public string Uploadpicture {
get {
return _uploadPicture;
}
set {
_uploadPicture = value;
}
}
public Student() {
_name = "";
_phoneNo = 0;
_address = "";
_occupation = "";
_courseOfStudy = "";
_duration = 0;
_uploadPicture = "";
System.Windows.Forms.MessageBox.Show("Called Constructor");
}
public Student(string name, int phoneNo, string address, string occupation, string courseOfStudy, int duration, string uploadPicture) {
_name = name;
_phoneNo = phoneNo;
_address = address;
_occupation = occupation;
_courseOfStudy = courseOfStudy;
_duration = duration;
_uploadPicture = uploadPicture;
}
}
}

How to use the Same Class on Client as on the Service?

How can I pass an entire defined class through a WCF service? I have the class defined on both the service and client side. I keep getting an error:
Best overloaded method match has some invalid arguments.
The whole class was copied from the client-side to the service-side.
Client side calling:
TransferProxy.PutTransferOnService(Transfer);
Defined on service:
[OperationContract]
bool PutTransferOnService(TypeTransfer Transfer);
I don't want to access individual items on the class from the client, I just want to move the WHOLE populated object through and do processing on the server side.
[DataContract]
public class TypeTransfer
{
private string userID;
private string transferNum;
private DateTime effectiveDate;
private int unitCount;
private int skuCount;
private string reason;
private string localStatus;
private string destStatus;
private string carrier;
private string sourceStore;
private string destinationStore;
private string inSeal;
private string outSeal;
[DataMember]
private List<TypeSOQ> correspondingSOQ = new List<TypeSOQ>();
[DataMember]
private List<TypeProductList> ProductList = new List<TypeProductList>();
public TypeTransfer() { }
// Function adds single item to transfer object
public void AddItem(int ProductID, string SKU, string PrimarySKU, string SCC, string ProductDescription, int TransferQty)
{
ProductList.Add(new TypeProductList
{
productID = ProductID,
sku = SKU,
primaryUPC = PrimarySKU,
scc = SCC,
description = ProductDescription,
transferQty = TransferQty
});
}
// Add SOQ to transfer object (can support multiple SOQ's)
public void AddSOQ(TypeSOQ soq)
{
correspondingSOQ.Add(soq);
}
// Function returns number of skus in Product List
public int GetSKUTotal()
{
return ProductList.Count();
}
// Function returns total number of items in transfer
public int GetItemTotal()
{
int itemtotal = 0;
for (int i = 0; i < ProductList.Count(); i++)
{
itemtotal += ProductList[i].transferQty;
}
return itemtotal;
}
// Return entire SOQ list
public List<TypeSOQ> GetSOQs()
{
return correspondingSOQ;
}
// Returns full product list in transfer object
public List<TypeProductList> GetProductList()
{
return ProductList;
}
[DataMember]
public string UserID
{
get { return userID; }
set { userID = value; }
}
[DataMember]
public string TransferNum
{
get { return transferNum; }
set { transferNum = value; }
}
[DataMember]
public DateTime EffectiveDate
{
get { return effectiveDate; }
set { effectiveDate = value; }
}
[DataMember]
public int UnitCount
{
get { return unitCount; }
set { unitCount = value; }
}
[DataMember]
public string Reason
{
get { return reason; }
set { reason = value; }
}
[DataMember]
public string LocalStatus
{
get { return localStatus; }
set { localStatus = value; }
}
[DataMember]
public string DestStatus
{
get { return destStatus; }
set { destStatus = value; }
}
[DataMember]
public string Carrier
{
get { return carrier; }
set { carrier = value; }
}
[DataMember]
public string SourceStore
{
get { return sourceStore; }
set { sourceStore = value; }
}
[DataMember]
public string DestStore
{
get { return destinationStore; }
set { destinationStore = value; }
}
[DataMember]
public string InSeal
{
get { return inSeal; }
set { inSeal = value; }
}
[DataMember]
public string OutSeal
{
get { return outSeal; }
set { outSeal = value; }
}
[DataMember]
public int SKUCount
{
get { return skuCount; }
set { skuCount = value; }
}
}
You said - The whole class was copied from the client-side to the service-side.
You don't need to copy your class to server side. just define your class in a separate library and give reference of that same library to both client and server.

How to get value from element attribute, XML Serialization

I want to get an attribute from vimeo xml.. here is structure of xml document
<?xml version="1.0" encoding="UTF-8" ?>
- <rsp generated_in="0.6533" stat="ok">
- <videos on_this_page="15" page="1" perpage="15" total="329">
- <video allow_adds="1" embed_privacy="anywhere" id="3475223" is_hd="0" is_transcoding="0" license="0" privacy="anybody">
<title>AxDroid - Android on Dell Axim x51v</title>
<description>This is my first attempt at installing and running Android on my Dell Axim x51v. Touchscreen and buttons are working! For details please visit: http://axdroid.blogspot.com/</description>
<upload_date>2009-03-04 16:14:19</upload_date>
<modified_date>2012-07-14 07:03:32</modified_date>
<number_of_likes>2</number_of_likes>
<number_of_plays>43422</number_of_plays>
<number_of_comments>1</number_of_comments>
<width>320</width>
<height>240</height>
<duration>320</duration>
- <owner display_name="Ertan D." id="1387509" is_plus="0" is_pro="0" is_staff="0" profileurl="http://vimeo.com/user1387509" realname="Ertan D." username="user1387509" videosurl="http://vimeo.com/user1387509/videos">
- <portraits>
<portrait height="30" width="30">http://a.vimeocdn.com/images_v6/portraits/portrait_30_yellow.png</portrait>
<portrait height="75" width="75">http://a.vimeocdn.com/images_v6/portraits/portrait_75_yellow.png</portrait>
<portrait height="100" width="100">http://a.vimeocdn.com/images_v6/portraits/portrait_100_yellow.png</portrait>
<portrait height="300" width="300">http://a.vimeocdn.com/images_v6/portraits/portrait_300_yellow.png</portrait>
</portraits>
</owner>
- <tags>
<tag author="1387509" id="8397224" normalized="android" url="http://vimeo.com/tag:android">android</tag>
<tag author="1387509" id="8397225" normalized="dell" url="http://vimeo.com/tag:dell">dell</tag>
<tag author="1387509" id="8397226" normalized="axim" url="http://vimeo.com/tag:axim">axim</tag>
<tag author="1387509" id="8397227" normalized="linux" url="http://vimeo.com/tag:linux">linux</tag>
<tag author="1387509" id="8397228" normalized="google" url="http://vimeo.com/tag:google">google</tag>
<tag author="1387509" id="8397229" normalized="pda" url="http://vimeo.com/tag:pda">pda</tag>
<tag author="1387509" id="8397230" normalized="ppc" url="http://vimeo.com/tag:ppc">ppc</tag>
</tags>
- <cast>
<member display_name="Ertan D." id="1387509" role="" username="user1387509" />
</cast>
- <urls>
<url type="video">http://vimeo.com/3475223</url>
</urls>
- <thumbnails>
<thumbnail height="75" width="100">http://b.vimeocdn.com/ts/347/807/3478071_100.jpg</thumbnail>
<thumbnail height="150" width="200">http://b.vimeocdn.com/ts/347/807/3478071_200.jpg</thumbnail>
<thumbnail height="480" width="640">http://b.vimeocdn.com/ts/347/807/3478071_640.jpg</thumbnail>
</thumbnails>
</video>
- <video allow_adds="1" embed_privacy="anywhere" id="28665952" is_hd="1" is_transcoding="0" license="0" privacy="anybody">
<title>Duygu + Ertan Şıkır Şıkır by DÜĞÜNHİKAYEMİZ</title>
<description />
<upload_date>2011-09-06 10:54:49</upload_date>
<modified_date>2012-07-14 06:41:33</modified_date>
<number_of_likes>3</number_of_likes>
<number_of_plays>26214</number_of_plays>
and I want to get username attribute from owner element. Here is serialization code.
[XmlTypeAttribute(AnonymousType = true)]
[XmlRootAttribute(Namespace = "", IsNullable = false, ElementName = "rsp")]
public partial class VimeoSearchResponse
{
private SearchResponseVideosWrapper _videos;
private string _generated_in;
private string _stat;
[XmlElementAttribute("videos", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public SearchResponseVideosWrapper videos
{
get { return _videos; }
set { _videos = value; }
}
[XmlAttributeAttribute()]
public string generated_in
{
get { return _generated_in; }
set { _generated_in = value; }
}
[XmlAttributeAttribute()]
public string stat
{
get { return _stat; }
set { _stat = value; }
}
}
[SerializableAttribute]
[XmlTypeAttribute(AnonymousType = true)]
public partial class SearchResponseVideosWrapper
{
private SearchResponseVideosWrapperVideo[] _video;
private string _on_this_page;
private string _page;
private string _perpage;
private string _total;
[XmlElementAttribute("video", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public SearchResponseVideosWrapperVideo[] video
{
get { return _video; }
set { _video = value; }
}
[XmlAttributeAttribute()]
public string on_this_page
{
get { return _on_this_page; }
set { _on_this_page = value; }
}
[XmlAttributeAttribute()]
public string page
{
get { return _page; }
set { _page = value; }
}
[XmlAttributeAttribute()]
public string perpage
{
get { return _perpage; }
set { _perpage = value; }
}
[XmlAttributeAttribute()]
public string total
{
get { return _total; }
set { _total = value; }
}
}
[SerializableAttribute]
[XmlTypeAttribute(AnonymousType = true)]
public partial class SearchResponseVideosWrapperVideo
{
private string _title;
private string _id;
private string _username;
[XmlElement()]
public string title
{
get { return _title; }
set { _title = value; }
}
[XmlAttributeAttribute()]
public string id
{
get { return _id; }
set { _id = value; }
}
[XmlElementAttribute("owner")]
public string username
{
get { return _username; }
set { _username = value; }
}
}
problem is here i think
[XmlElementAttribute("owner")]
public string username
{
get { return _username; }
set { _username = value; }
}
- <owner display_name="Ertan D." id="1387509" is_plus="0" is_pro="0" is_staff="0" profileurl="http://vimeo.com/user1387509" realname="Ertan D." username="user1387509" videosurl="http://vimeo.com/user1387509/videos">
how can I get attribute from owner..
here is exception detail
I get an exception that is There is an error in XML document (1,
1005).
{"Unexpected node type Element. ReadElementString method can only be
called on elements with simple or empty content. Line 1, position
1005."}
System.InvalidOperationException was caught
You need an 'owner' class. You also might consider adding the 'portrait' class with a collection in the 'owner' class.
public class owner
{
[XmlAttributeAttribute]
public string username { get; set; }
}
[SerializableAttribute]
[XmlTypeAttribute(AnonymousType = true)]
public partial class SearchResponseVideosWrapperVideo
{
private string _title;
private string _id;
private string _username;
[XmlElement()]
public string title
{
get { return _title; }
set { _title = value; }
}
[XmlAttributeAttribute()]
public string id
{
get { return _id; }
set { _id = value; }
}
[XmlElementAttribute("owner")]
public owner owner { get; set; }
}
You are annotating username with an XmlElementAttribute for "owner."
That implies that the owner element should be deserialized into the string property username.
If you want to get at username, you first have to deserialize owner into some object.
For example, you could add an Owner class, in the same manner as you created VimeoSearchResponse.
public class Owner
{
private string _owner;
[XmlAttribute]
public string username
{
get { return _owner; }
set { _owner = value; }
}
}

Categories