I am trying to serialize an object & save it into a Sql server 2008 xml field. I also have some deserialization code that re-hydrates the object. I am able to serialize & save the object into the db, but get a "Root element missing" exception.
[XmlRoot("Patient")]
public class PatientXml
{
private AddressXml _address = null;
private EmergencyContactXml _emergencyContact = null;
private PersonalXml _personal = null;
[XmlElement]
public PersonalXml Personal
{
get { return _personal; }
set { _personal = value; }
}
[XmlElement]
public AddressXml Address
{
get { return _address; }
set { _address = value; }
}
[XmlElement]
public EmergencyContactXml EmergencyContact
{
get { return _emergencyContact; }
set { _emergencyContact = value; }
}
public PatientXml(){}
public PatientXml(Patient patient)
{
_address = new AddressXml(patient.Address);
_emergencyContact = new EmergencyContactXml(patient.EmergencyInfo);
_personal = new PersonalXml(patient);
}
}
public class PersonalXml
{
private string _firstName = string.Empty, _lastName = string.Empty, _dateOfBirth = string.Empty, _phone = string.Empty;
[XmlAttribute]
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
[XmlAttribute]
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
[XmlAttribute]
public string DateOfBirth
{
get { return _dateOfBirth; }
set { _dateOfBirth = value; }
}
[XmlAttribute]
public string Phone
{
get { return _phone; }
set { _phone = value; }
}
public PersonalXml(){}
public PersonalXml(Patient patient)
{
_firstName = patient.FirstName;
_lastName = patient.LastName;
_dateOfBirth = patient.DateOfBirth.ToShortDateString();
_phone = patient.Phone;
}
}
public class AddressXml
{
private string _address1 = string.Empty, _address2 = string.Empty, _city = string.Empty, _state = string.Empty, _zip = string.Empty;
[XmlAttribute]
public string Address1
{
get { return _address1; }
set { _address1 = value; }
}
[XmlAttribute]
public string Address2
{
get { return _address2; }
set { _address2 = value; }
}
[XmlAttribute]
public string City
{
get { return _city; }
set { _city = value; }
}
[XmlAttribute]
public string State
{
get { return _state; }
set { _state = value; }
}
[XmlAttribute]
public string Zip
{
get { return _zip; }
set { _zip = value; }
}
public AddressXml(){}
public AddressXml(Address address)
{
_address1 = address.Address1;
_address2 = address.Address2;
_city = address.City;
_state = address.State;
_zip = address.ZipCode;
}
}
public class EmergencyContactXml
{
private string _name = string.Empty, _phone = string.Empty, _relationship = string.Empty;
[XmlAttribute]
public string Name
{
get { return _name; }
set { _name = value; }
}
[XmlAttribute]
public string Phone
{
get { return _phone; }
set { _phone = value; }
}
[XmlAttribute]
public string Relationship
{
get { return _relationship; }
set { _relationship = value; }
}
public EmergencyContactXml(){}
public EmergencyContactXml(EmergencyContact contact)
{
_name = contact.ContactName;
_phone = contact.Phone;
_relationship = contact.Relationship;
}
}
Serialized Xml output:
<Patient
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Personal FirstName="Test" LastName="User 1" DateOfBirth="3/13/1966" Phone="6304449866" />
<Address Address1="123 Some St" City="Bartlett" State="CT" Zip="60111" />
<EmergencyContact Name="Dr Chanduwarthana" Phone="6309769484" Relationship="Father" />
</Patient>
Serization & Deserialization code:
public static class XmlSerializer
{
public static string Serialize<T>(T item)
{
MemoryStream memStream = new MemoryStream();
using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode))
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
serializer.Serialize(textWriter, item);
memStream = textWriter.BaseStream as MemoryStream;
}
if (memStream != null)
return Encoding.Unicode.GetString(memStream.ToArray());
else
return null;
}
public static T Deserialize<T>(string xmlString)
{
if (string.IsNullOrWhiteSpace(xmlString))
return default(T);
using (MemoryStream memStream = new MemoryStream())
{
using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode))
{
memStream.Position = 0;
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
return (T)serializer.Deserialize(memStream);
}
}
}
}
In your deserialization code you're creating a MemoryStream and XmlTextWriter but you're not giving it the string to deserialize.
using (MemoryStream memStream = new MemoryStream())
{
using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode))
{
// Omitted
}
}
You can pass the bytes to the memory stream and do away with the XmlTextWriter altogether.
using (MemoryStream memStream = new MemoryStream(Encoding.Unicode.GetBytes(xmlString)))
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
return (T)serializer.Deserialize(memStream);
}
Looks like you got a handle on serializing to XML, so take my advice, store the XML in a string field (varchar, nvarchar, text, ntext) and not a specialized field.
If you do that little switch you will be ready to go... no further modification required.
XML field is subject to validations, and more than a few headaches, and if your application is only producer and consumer of that field, you might as well take that shortcut.
SQL2008 (even 2005) is strong enough to compensate for the resources you might save by it compiling the xml field.
HOWEVER ,
I would optimize your code a bit, looks like you wrote way more code than you had to.
For example, you no longer need to create a private field to store the data from your property, for example :
public PersonalXml Personal
{
get { return _personal; }
set { _personal = value; }
}
will work just fine if you wrote it like :
public PersonalXml Personal { get ; set ; }
there's more fat you could have cut...
I believe that you need to add the XML header:
<?xml version="1.0" encoding="utf-8" ?>
You could modify your serialize method to accept an optional parameter that would cause this to be added:
public static string Serialize<T>(T item, bool includeHeader = false)
{
MemoryStream memStream = new MemoryStream();
using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode))
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
serializer.Serialize(textWriter, item);
memStream = textWriter.BaseStream as MemoryStream;
}
if (memStream != null)
if (includeHeader)
{
return #"<?xml version=""1.0"" encoding=""utf-8"" ?>" + Environment.NewLine + Encoding.Unicode.GetString(memStream.ToArray());
}
else
{
return Encoding.Unicode.GetString(memStream.ToArray());
}
else
return null;
}
Related
The following code in my program serializes, encrypts and writes the byte array to disk. From the looks of it, the encryption works fine. The issue arises when the program decrypts and then deserializes the file.
Visual Studio displays the following error:
'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.dll
Additional information: There was an error deserializing the object of type Test.Store. The data at the root level is invalid.
I've been stuck on this one for two days, so any help would be greatly appreciated!
The following code has been trimmed down from its original form:
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Text;
namespace Test
{
public class K
{
#region Non-Public Data Members
private string _n = string.Empty;
private string _u = string.Empty;
private string _p = string.Empty;
private string _u2 = null;
private string _n2 = string.Empty;
public K()
{
}
public string T
{
get { return _n; }
set { _n = value; }
}
public string U
{
get { return _u; }
set { _u = value; }
}
public string P
{
get { return _p; }
set { _p = value; }
}
public string U2
{
get { return _u2; }
set { _u2 = value; }
}
public string N2
{
get { return _n2; }
set { _n2 = value; }
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
//stuff
return sb.ToString();
}
#endregion
}
public class Group
{
private string _text = string.Empty;
private int _imageIndex = 0;
private List<K> _credentials = new List<K>();
public Group()
{
}
public Group(string text, int imageIndex)
{
_text = text;
_imageIndex = imageIndex;
}
public string Text
{
get { return _text; }
set { _text = value; }
}
public int ImageIndex
{
get { return _imageIndex; }
set { _imageIndex = value; }
}
public List<K> Ks
{
get { return _credentials; }
set { _credentials = value; }
}
public override string ToString()
{
return Text;
}
}
public class Store
{
private List<Group> _groups = new List<Group>();
private string _docname = string.Empty;
private bool _dirtyBit = false;
public bool DirtyBit
{
get { return _dirtyBit; }
set { _dirtyBit = value; }
}
public List<Group> Groups
{
get { return _groups; }
set { _groups = value; }
}
public string DocName
{
get { return _docname; }
set { _docname = value; }
}
}
public class Crypto
{
public static string secretKey = "abcdefgh";
[System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
public static extern bool ZeroMemory(ref string Destination, int Length);
static string GenerateKey()
{
DESCryptoServiceProvider desCrypto = (DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
}
public static byte[] PerformCrypto(ICryptoTransform cryptoTransform, byte[] data)
{
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
return memoryStream.ToArray();
}
}
}
public static byte[] Decrypt(byte[] cipherTextBytes)
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(secretKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(secretKey);
using (var decryptor = DES.CreateDecryptor(DES.Key, DES.IV))
{
return PerformCrypto(decryptor, cipherTextBytes);
}
}
public static byte[] Encrypt(byte[] plainTextBytes)
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(secretKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(secretKey);
using (var encryptor = DES.CreateEncryptor(DES.Key, DES.IV))
{
return PerformCrypto(encryptor, plainTextBytes);
}
}
}
public static class StoreMgr
{
private static Store _doc = new Store();
public static void FileSaveAs(string fn)
{
using (MemoryStream ms = new MemoryStream())
{
DataContractSerializer serializer = new DataContractSerializer(typeof(Store));
serializer.WriteObject(ms, _doc);
byte[] byteArrayInput = ms.GetBuffer();
byte[] encryptedBuffer = Crypto.Encrypt(byteArrayInput);
File.WriteAllBytes(fn, encryptedBuffer);
}
}
public static void OpenFile(string fn)
{
StoreMgr._doc = new Store();
using (MemoryStream ms = new MemoryStream(Crypto.Decrypt(File.ReadAllBytes(fn))))
{
DataContractSerializer deserializer = new DataContractSerializer(typeof(Store));
StoreMgr._doc = (Store)new DataContractSerializer(typeof(Store)).ReadObject(ms);
}
}
}
}
I've been stuck on this for quite some time. Any help is greatly appreciated!
If you configure System.Diagnostics.XmlWriterTraceListener in your web.config, you may find more helpful information in *.svclog
The issue was in the FileSaveAs method. byte[] byteArrayInput = ms.GetBuffer() was returning unused bytes. After switching it to byte[] byteArrayInput = ms.ToArray() program ran fine. Thanks for everyone's help.
I am trying to deserialize an XML String into my class which is derived from another class but I am having a problem in doing so, I am getting the following error:
{"The specified type is abstract: name='DeviceRequest', namespace='', at <DeviceRequest xmlns=''>."}
I assume i am missing some decorator attribute that will inform the serializer how to deserialize this xml into the class?
Here is my code:
//Usage
DeviceRequest dreq = DeviceRequest.ParseRequest(e.XML);
//Base Class
public abstract class IFSFRequestBase
{
private string m_ApplicationSender = "";
private int m_WorkStationID = 0;
private string m_RequestID = "";
[XmlAttribute()]
public abstract string RequestType { get; set; }
public abstract byte[] Message();
[XmlAttribute()]
public string ApplicationSender
{
get
{
return m_ApplicationSender;
}
set
{
m_ApplicationSender = value;
}
}
[XmlAttribute()]
public int WorkStationID
{
get
{
return m_WorkStationID;
}
set
{
m_WorkStationID = value;
}
}
[XmlAttribute()]
public string RequestID
{
get
{
return m_RequestID;
}
set
{
m_RequestID = value;
}
}
}
//Derived Class
public abstract class DeviceRequest : IFSFRequestBase
{
private string m_TerminalID = "";
private string m_SequenceID = "";
private Output m_OutputField = null;
[XmlAttribute(), DefaultValue("")]
public string TerminalID
{
get
{
return m_TerminalID;
}
set
{
m_TerminalID = value;
}
}
[XmlAttribute(), DefaultValue("")]
public string SequenceID
{
get
{
return m_SequenceID;
}
set
{
m_SequenceID = value;
}
}
[XmlElement("Output")]
public Output OutputField
{
get
{
return m_OutputField;
}
set
{
m_OutputField = value;
}
}
public static DeviceRequest ParseRequest(string sXML)
{
XmlSerializer serializer = new XmlSerializer(typeof(DeviceRequest));
StringReader sr = new StringReader(sXML);
NamespaceIgnorantXmlTextReader XMLWithoutNamespace = new NamespaceIgnorantXmlTextReader(sr);
return (DeviceRequest)serializer.Deserialize(XMLWithoutNamespace);
}
}
// helper class to ignore namespaces when de-serializing
public class NamespaceIgnorantXmlTextReader : XmlTextReader
{
public NamespaceIgnorantXmlTextReader(System.IO.TextReader reader) : base(reader) { }
public override string NamespaceURI
{
get { return ""; }
}
}
UPDATE:
OK based on the answers here. I have updated the code, I now have a class Display that derives from DeviceRequest. I now get the following error:
{"There is an error in XML document (2, 2)."}, {"<DeviceRequest xmlns=''> was not expected."}
public class Display : DeviceRequest
{
public static Display ParseRequest(string sXML)
{
XmlSerializer serializer = new XmlSerializer(typeof(Display));
StringReader sr = new StringReader(sXML);
NamespaceIgnorantXmlTextReader XMLWithoutNamespace = new NamespaceIgnorantXmlTextReader(sr);
return (Display)serializer.Deserialize(XMLWithoutNamespace);
}
[XmlAttribute()]
public override string RequestType
{
get { return "Output"; } set { }
}
public override byte[] Message()
{
throw new NotImplementedException();
}
}
DeviceRequest dreq = Display.ParseRequest(e.XML);
As DeviceRequest is an abstract type, it cannot be instantiated directly. It is impossible to directly deserialize into instances of Device-Request. That said, if there are some non-abstract classes derived from it, please show some of them.
OK, I have resolved this issue now. Thanks for the input guys.
I needed to add:
[System.Xml.Serialization.XmlRootAttribute(ElementName = "DeviceRequest")]
to the Display Class
[System.Xml.Serialization.XmlRootAttribute(ElementName = "DeviceRequest")]
public class Display : DeviceRequest
{
public static Display ParseRequest(string sXML)
{
XmlSerializer serializer = new XmlSerializer(typeof(Display));
StringReader sr = new StringReader(sXML);
NamespaceIgnorantXmlTextReader XMLWithoutNamespace = new NamespaceIgnorantXmlTextReader(sr);
return (Display)serializer.Deserialize(XMLWithoutNamespace);
}
[XmlAttribute()]
public override string RequestType
{
get { return "O"; } set { }
}
public override byte[] Message()
{
throw new NotImplementedException();
}
}
I have a serialization method as follows:
public string SerializeObject(object obj, Type type)
{
var setting = new XmlWriterSettings() { OmitXmlDeclaration = true, Indent = true };
var xml = new StringBuilder();
using (var writer = XmlWriter.Create(xml, setting))
{
var nsSerializer = new XmlSerializerNamespaces();
nsSerializer.Add(string.Empty, string.Empty);
var xmlSerializer = new XmlSerializer(type);
xmlSerializer.Serialize(writer, obj, nsSerializer);
}
return xml.ToString();
}
Which I call as follows:
requestXML = serializer.SerializeObject(InboundIterate, typeof(INBOUND));
The output is as expected for any field I have defined in my structure as a string, but all the decimal values are missing.
For example my output will look like:
<PRODUCT_EXTENSION>
<DIMENSION_UOM>IN</SD_DIMENSION_UOM>
<SALES_UOM>CS</SD_SALES_UOM>
</PRODUCT_EXTENSION>
when I am expecting
<PRODUCT_EXTENSION>
<DIMENSION_UOM>IN</DIMENSION_UOM>
<DIMENSION>15.83</DIMENSION>
<SALES_UOM>CS</SALES_UOM>
<SALES>24</SALES>
</PRODUCT_EXTENSION>
any help would be appreciated, thank you.
class below
public partial class PRODUCT_EXTENSION {
private System.Nullable<decimal> LENGTHField;
private bool LENGTHFieldSpecified;
private System.Nullable<decimal> NET_WEIGHTField;
private bool NET_WEIGHTFieldSpecified;
private string SALES_UOMField;
private string WEIGHT_UOMField;
private List<PRODUCT_EXTENSIONSOURCE_SYSTEM> SOURCE_SYSTEMField;
public PRODUCT_EXTENSION() {
this.SOURCE_SYSTEMField = new List<PRODUCT_EXTENSIONSOURCE_SYSTEM>();
}
public System.Nullable<decimal> LENGTH {
get {
return this.LENGTHField;
}
set {
this.LENGTHField = value;
}
}
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool SD_LENGTHSpecified {
get {
return this.LENGTHFieldSpecified;
}
set {
this.LENGTHFieldSpecified = value;
}
}
public System.Nullable<decimal> NET_WEIGHT {
get {
return this.NET_WEIGHTField;
}
set {
this.NET_WEIGHTField = value;
}
}
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool NET_WEIGHTSpecified {
get {
return this.NET_WEIGHTFieldSpecified;
}
set {
this.NET_WEIGHTFieldSpecified = value;
}
}
public string SALES_UOM {
get {
return this.SALES_UOMField;
}
set {
this.SALES_UOMField = value;
}
}
public string SD_WEIGHT_UOM {
get {
return this.WEIGHT_UOMField;
}
set {
this.WEIGHT_UOMField = value;
}
}
public List<PRODUCT_EXTENSIONSOURCE_SYSTEM> SOURCE_SYSTEM {
get {
return this.SOURCE_SYSTEMField;
}
set {
this.SOURCE_SYSTEMField = value;
}
}
}
I've tried your code snippet, and it works fine for me fine with public properties, but if i change the property protection to protected or private. These properties are missing from the XML.
Check your properties.
I want to serialize like this
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
</urlset>
But wrong result generated.
My class is here
[Serializable]
[XmlRoot("urlset")]
public class GoogleSiteMap
{
public GoogleSiteMap() {
xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9";
xmlnsNews = "http://www.google.com/schemas/sitemap-news/0.9";
Urls = new List<gUrlBase>();
}
[XmlAttribute]
public string xmlns { get; set; }
[XmlAttribute("news",Namespace="xmlns")]
public string xmlnsNews { get; set; }
[XmlElement("url")]
public List<gUrlBase> Urls { get; set; }
}
Serializer is here
public static void GenerateGoogle(GoogleSiteMap smap,string filePath) {
XmlSerializer ser = new XmlSerializer(typeof(GoogleSiteMap));
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
ser.Serialize(fs, smap);
fs.Close();
}
}
Then result is here
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:d1p1="xmlns" d1p1:news="http://www.google.com/schemas/sitemap-news/0.9"/>
What's wrong on my class declaration?
Another QUESTION 2
How can i declare like this
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
<url>
<loc>http://www.example.org/business/article55.html</loc>
<news:news></news:news>
</url>
<url>
<loc>http://www.example.org/business/page1.html</loc>
<lastmod>2010-10-10</lastmod>
<changefreq>weekly</changefreq>
</url>
</urlset>
my declaration is here
[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
public class GoogleSiteMap
{
public GoogleSiteMap()
{
Urls = new List<gUrlBase>();
}
//[XmlElement("url")]
[XmlElement("url",Type = typeof(gNormalUrl))]
[XmlElement("url",Type = typeof(gNewsUrl))]
public List<gUrlBase> Urls { get; set; }
}
This is return error
The XML element 'url' from namespace 'http://www.sitemaps.org/schemas/sitemap/0.9' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.
How can i declare Same root name "url"?
You need to use the right namespace:
[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
you can take away xmlns and xmlnsNews properties - they do something else. Likewise, any data in ""http://www.google.com/schemas/sitemap-news/0.9" will need to be marked as such. Whether the namespace alias is news is irrelevant (it is only an alias), but that can be controlled via XmlSerializerNamespaces if you like. You do not need [Serializable].
For example, if each <url> needs to be in the "http://www.google.com/schemas/sitemap-news/0.9" namespace, and you want to use "http://www.sitemaps.org/schemas/sitemap/0.9" as the overall namespace and "http://www.google.com/schemas/sitemap-news/0.9" aliased as "news", then:
static class Program
{
static void Main()
{
var ns = new XmlSerializerNamespaces();
ns.Add("", "http://www.sitemaps.org/schemas/sitemap/0.9");
ns.Add("news", "http://www.google.com/schemas/sitemap-news/0.9");
var ser = new XmlSerializer(typeof (GoogleSiteMap));
var obj = new GoogleSiteMap {Urls = new List<string> {"abc", "def", "ghi"}};
ser.Serialize(Console.Out, obj, ns);
}
}
[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
public class GoogleSiteMap
{
[XmlElement("url", Namespace = "http://www.google.com/schemas/sitemap-news/0.9")]
public List<string> Urls { get; set; }
}
This generates:
<urlset
xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<news:url>abc</news:url>
<news:url>def</news:url>
<news:url>ghi</news:url>
</urlset>
(I haven't checked what the actual content namespaces are - this is just to show the relationship between namespaces in the data, namespaces in the xml, and namespace-aliases)
Re your edit - something like:
static class Program
{
static void Main()
{
var ns = new XmlSerializerNamespaces();
ns.Add("", "http://www.sitemaps.org/schemas/sitemap/0.9");
ns.Add("news", "http://www.google.com/schemas/sitemap-news/0.9");
var ser = new XmlSerializer(typeof (GoogleSiteMap));
var obj = new GoogleSiteMap {Urls = {
new SiteUrl { Location = "http://www.example.org/business/article55.html", News = ""},
new SiteUrl { Location = "http://www.example.org/business/page1.html", LastModified = new DateTime(2010,10,10),
ChangeFrequency = "weekly"}
}};
ser.Serialize(Console.Out, obj, ns);
}
}
[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
public class GoogleSiteMap
{
private readonly List<SiteUrl> urls = new List<SiteUrl>();
[XmlElement("url")]
public List<SiteUrl> Urls { get { return urls; } }
}
public class SiteUrl
{
[XmlElement("loc")]
public string Location { get; set; }
[XmlElement("news", Namespace = "http://www.google.com/schemas/sitemap-news/0.9")]
public string News { get; set; }
[XmlElement("lastmod")]
public DateTime? LastModified { get; set; }
[XmlElement("changefreq")]
public string ChangeFrequency { get; set; }
public bool ShouldSerializeLastModified() { return LastModified.HasValue; }
}
which generates:
<urlset xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.example.org/business/article55.html</loc>
<news:news />
</url>
<url>
<loc>http://www.example.org/business/page1.html</loc>
<lastmod>2010-10-10T00:00:00</lastmod>
<changefreq>weekly</changefreq>
</url>
</urlset>
Please use below full code that made by me
Please see below full code
#region GoogleNewsSiteMap Class
[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
public class GoogleNewsSiteMap
{
const string _newsSiteMapSchema = "http://www.google.com/schemas/sitemap-news/0.9";
const string _newsSiteMapPrefix = "n";
public void Create(string loc, string prioity, string language, string name, string genres, string publicationDate, string title)
{
NewsSiteMap news = new NewsSiteMap();
news.Loc = loc;
news.Priority = prioity;
news.NewsSiteMapNews.Publication.Language = language;
news.NewsSiteMapNews.Publication.Name = name;
news.NewsSiteMapNews.Genres = genres;
news.NewsSiteMapNews.PublicationDate = publicationDate;
news.NewsSiteMapNews.Title = title;
List.Add(news);
}
public string GetXMLString()
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = (" ");
settings.Encoding = new UTF8Encoding(false);
using (StringWriter str = new StringWriter())
using (XmlWriter writer = XmlWriter.Create(str, settings))
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add(_newsSiteMapPrefix, _newsSiteMapSchema);
XmlSerializer xser = new XmlSerializer(typeof(GoogleNewsSiteMap));
xser.Serialize(writer, this, ns);
return str.ToString();
}
}
private List<NewsSiteMap> _list = null;
[XmlElement("url")]
public List<NewsSiteMap> List
{
get
{
if (_list == null)
{
_list = new List<NewsSiteMap>();
}
return _list;
}
}
#region NewsSiteMap Class
public class NewsSiteMap
{
private string _loc = string.Empty;
private string _priority = string.Empty;
private NewsSiteMap_News _newsSiteMap_News = null;
[XmlElement("loc")]
public string Loc
{
get { return _loc; } set { _loc = value; }
}
[XmlElement("priority")]
public string Priority
{
get { return _priority; } set { _priority = value; }
}
[XmlElement("news", Namespace = _newsSiteMapSchema)]
public NewsSiteMap_News NewsSiteMapNews
{
get {
if (_newsSiteMap_News == null)
{
_newsSiteMap_News = new NewsSiteMap_News();
}
return _newsSiteMap_News;
}
set { _newsSiteMap_News = value; }
}
#region NewsSiteMap_News Class
public class NewsSiteMap_News
{
private NewsSiteMap_Publication _publication = null;
private string _genres = string.Empty;
private string _publicationDate = string.Empty;
private string _title = string.Empty;
private string _keywords = string.Empty;
private string _stockTickers = string.Empty;
[XmlElement("publication", Namespace = _newsSiteMapSchema)]
public NewsSiteMap_Publication Publication
{
get
{
if (_publication == null)
{
_publication = new NewsSiteMap_Publication();
}
return _publication;
}
set { _publication = value; }
}
[XmlElement("genres")]
public string Genres
{
get { return _genres; }
set { _genres = value; }
}
[XmlElement("publication_date")]
public string PublicationDate
{
get
{
try
{
return string.Format("{0:s}", Convert.ToDateTime(_publicationDate)) + string.Format("{0:zzz}", Convert.ToDateTime(_publicationDate));
}
catch (Exception ex)
{
return _publicationDate;
}
}
set { _publicationDate = value; }
}
public string Title
{
set { _title = value; }
}
[XmlElement("title")]
public XmlCDataSection CTitle
{
get
{
XmlDocument doc = new XmlDocument();
return doc.CreateCDataSection(_title);
}
set { _title = value.Value; }
}
[XmlElement("keywords")]
public string Keywords
{
get { return _keywords; } set { _keywords = value; }
}
[XmlElement("stock_tickers")]
public string StockTickers
{
get { return _stockTickers; } set { _stockTickers = value; }
}
#region NewsSiteMap_Publication Class
public class NewsSiteMap_Publication
{
private string _name = string.Empty;
private string _language = string.Empty;
[XmlElement("name")]
public string Name
{
get { return _name; }
set { _name = value; }
}
[XmlElement("language")]
public string Language
{
get { return _language; }
set { _language = value; }
}
}
#endregion NewsSiteMap_Publication Class
}
#endregion NewsSiteMap_News Class
}
#endregion NewsSiteMap Class
}
#endregion GoogleNewsSiteMap Class
Usage
Response.Clear();
Response.ContentType = "text/xml";
Response.ContentEncoding = System.Text.Encoding.UTF8;
GoogleNewsSiteMap googleNewsSiteMap = new GoogleNewsSiteMap();
googleNewsSiteMap.Create(/*put ur data*/);
Response.Write(googleNewsSiteMap.GetXMLString());
When I execute the code saveXML below it generates the error above, why??
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Serialization;
using System.IO;
/// <summary>
/// Summary description for Post
/// </summary>
public class Post
{
private int postIDCounter = 0;
private String DateCreated;
public Post()
{
Author = "unknown";
Title = "unkown";
Content = "";
DateCreated = DateTime.Now.ToString();
ID = postIDCounter++;
}
public int ID
{
get { return ID; }
set
{
if (ID != value)
ID = value;
}
}
public string Author
{
get { return Author; }
set
{
if (Author != value)
Author = value;
}
}
public string Title
{
get { return Title; }
set
{
if (Title != value)
Title = value;
}
}
public string Content
{
get { return Content; }
set
{
if (Content != value)
Content = value;
}
}
public void saveXML()
{
XmlSerializer serializer = new XmlSerializer(typeof(Post));
Stream writer = new FileStream("..'\'App_Data'\'posts'\'" + new Guid(ID.ToString()).ToString() + ".xml", FileMode.Create);
serializer.Serialize(writer, this);
writer.Close();
}
}
All your variables are circular reference, that loops for ever and eventually your system stops / crash.
public string Content
{
get { return Content; }
For example, you say here, that get, return the Content, but the return is again the get Content, and get Content, and you understand ? is loop for ever in this line... and in all lines that you have something like that.
Try to do this way.
string inside_Content;
public string Content
{
get { return inside_Content; }
set { inside_Content = value;}
}