473,383 Members | 1,742 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

Serializing value types

When a class contains a TimeSpan property, XmlSerializer doesn't work. A
TimeSpan property is serialized like:

<MySpan />

I've read a number of posts that talk about why this happens and how to work
around it. My question is from a slightly different angle. What can I do
to my value type structures so that XmlSerializer can serialize them
properly?

For example, I have a TimeOfDay structure, what can I do to my TimeOfDay
structure so that XmlSerializer works? I've already discovered that I can
add a public property to TimeOfDay like this:

[XmlAttribute]
public string value
{
get { ...return the time of day as a string...}
set { ...set the time of day from a string...}
}

so, if another object has a TimeOfDay property named StartTime, it is
serialized like:

<StartTime value="14:30" />

which isn't too bad but, it breaks if the consumer puts [XmlAttribute] on
their property. And, I have this strange "value" property hanging around
that I have to tell people to ignore.

Any suggestions?

Thanks,

John Vottero

Nov 12 '05 #1
4 5372
Hi John,

First of all, I would like to confirm my understanding of your issue. From
your description, I'm still not quite sure what you get. Do you mean that
adding a [XmlAttribute] on a property that returns TimeOfDay type will make
the serialized data look bad?

Could you please paste some repro code here and show us the desired result?
Thanks!

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Nov 12 '05 #2

"Kevin Yu [MSFT]" <v-****@online.microsoft.com> wrote in message
news:6O**************@cpmsftngxa06.phx.gbl...
Hi John,

First of all, I would like to confirm my understanding of your issue. From
your description, I'm still not quite sure what you get. Do you mean that
adding a [XmlAttribute] on a property that returns TimeOfDay type will
make
the serialized data look bad?
Not exactly. The issue is, XmlSerializer can't serialize value types. If
someone uses my TimeOfDay type like this:

public TimeOfDay StartTime
{
get { return m_StartTime;}
set { m_StartTIme = value; }
}

When the containing class is serialized by XmlSerializer they get:

<StartTime />

Note that there's no data. What I want, is something like:

<StartTime>08:00</StartTime>

If the consumer class adds [XmlAttribute] to the StartTime property, they
get this error:

There was an error reflecting property 'StartTime'.
Cannot serialize member 'StartTime'. XmlAttribute/XmlText cannot be used to
encode complex types.

when they try to serialize with XmlSerializer.

What I want is something like:

<ConsumerClass StartTime="08:00">
What can I do to my TimeOfDay type to make it work with XmlSerializer?


Could you please paste some repro code here and show us the desired
result?
Thanks!


I will work up a short but complete example.
Nov 12 '05 #3
"Kevin Yu [MSFT]" <v-****@online.microsoft.com> wrote in message
news:6O**************@cpmsftngxa06.phx.gbl...
Hi John,

First of all, I would like to confirm my understanding of your issue. From
your description, I'm still not quite sure what you get. Do you mean that
adding a [XmlAttribute] on a property that returns TimeOfDay type will
make
the serialized data look bad?

Could you please paste some repro code here and show us the desired
result?
Thanks!


Here's a short console program that reproduces the problem followed by the
code for the TimeOfDay type.
using System;
using System.Xml.Serialization;

namespace XmlSample
{
/// <summary>
/// The Consumer class is just a simple example of a class that consumes
/// the TimeOfDay object. This is used to illustrate a problem with
XmlSerializer,
/// the StartTime property isn't serialized correctly. The real
question is:
///
/// What can be done to the TimeOfDay type to make XmlSerializer work?
///
/// </summary>
public class Consumer
{
public Consumer()
{
}

public string Name
{
get
{
return m_Name;
}
set
{
m_Name = value;
}
}

public TimeOfDay StartTime
{
get
{
return m_StartTime;
}
set
{
m_StartTime = value;
}
}

//
// Private property backers
//
private string m_Name;
private TimeOfDay m_StartTime;
}

/// <summary>
/// Class1 contains the Main method.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// Create and populate a Consumer object
//
Consumer co = new Consumer();

co.Name = "John";
co.StartTime = new TimeOfDay("10:30");

//
// Create the XmlSerializer
//
XmlSerializer serializer = new XmlSerializer(co.GetType());

//
// Serialize!!
//
serializer.Serialize(Console.Out, co);

//
// Pause
//
Console.WriteLine();
Console.WriteLine("StartTime should be {0}", co.StartTime);
Console.WriteLine("Press Return to continue");
Console.ReadLine();
}
}
}

/////// TimeOfDay.cs

using System;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Xml.Serialization;

namespace XmlSample
{
/// <summary>
/// TimeOfDayConverter is a TypeConverter for the TimeOfDay type.
/// </summary>
public class TimeOfDayConverter : TypeConverter
{
/// <summary>
/// Returns true if the passed source Type can be converted into a
TimeOfDay.
/// </summary>
/// <param name="context"></param>
/// <param name="sourceType">THe Type to be converted.</param>
/// <returns>True if the conversion can be done.</returns>
public override bool CanConvertFrom(
ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
else
{
return base.CanConvertFrom(context, sourceType);
}
}

/// <summary>
/// Converts the passed value into a TimeOfDay.
/// </summary>
/// <param name="context"></param>
/// <param name="culture"></param>
/// <param name="value">The value to convert into a
TimeOfDay.</param>
/// <returns>The new TimeOfDay.</returns>
public override object ConvertFrom(
ITypeDescriptorContext context, CultureInfo culture, object
value)
{
if (value is string)
{
return TimeOfDay.Parse((string)value);
}
else
{
return base.ConvertFrom(context, culture, value);
}
}

/// <summary>
/// Converts the passed TimeOfDay into the passed destination Type.
/// </summary>
/// <param name="context"></param>
/// <param name="culture"></param>
/// <param name="value">The TimeOfDay</param>
/// <param name="destinationType">The destination Type</param>
/// <returns>The new object created from the TimeOfDay.</returns>
public override object ConvertTo(
ITypeDescriptorContext context, CultureInfo culture, object
value, Type destinationType)
{
if ((destinationType == typeof(string))
&& (value is TimeOfDay))
{
return
((TimeOfDay)value).ToString(culture.DateTimeFormat .ShortTimePattern);
}
else
{
return base.ConvertTo(context, culture, value,
destinationType);
}
}
}

/// <summary>
/// The TimeOfDay represents a time of day.
/// </summary>
[Serializable,
TypeConverter(typeof(TimeOfDayConverter)),
XmlType("time")]
public struct TimeOfDay : IComparable, IFormattable, ISerializable
{
private int timeOfDay; // The number of seconds since midnight (-1
means NULL)

/// <summary>
/// Constructs a TimeOfDay from an integer which is the seconds
since midnight.
/// </summary>
/// <param name="initial">The seconds since midnight.</param>
public TimeOfDay(int initial)
{
timeOfDay = initial;
}

/// <summary>
/// Constructs a TimeOfDay from a DateTime.
/// </summary>
/// <param name="initial">The DateTime to create the TimeOfDay
from.</param>
public TimeOfDay(DateTime initial)
{
timeOfDay = (int)(initial.TimeOfDay.Ticks /
TimeSpan.TicksPerSecond);
}

/// <summary>
/// Constructs a TimeOfDay from a string.
/// </summary>
/// <param name="initial">The string.</param>
public TimeOfDay(string initial)
{
DateTime tmpDT;

try
{
tmpDT = DateTime.Parse(initial);
timeOfDay = (int)(tmpDT.TimeOfDay.Ticks /
TimeSpan.TicksPerSecond);
}
catch
{
timeOfDay = -1;
}
}

/// <summary>
/// A TimeOfDay that is the current time.
/// </summary>
public static TimeOfDay Now
{
get
{
return new TimeOfDay(DateTime.Now);
}
}

// [XmlAttribute]
// public string value
// {
// get
// {
// if (timeOfDay < 0)
// {
// return null;
// }
// else
// {
// return "10:30";
// }
// }
// set
// {
// timeOfDay = -1;
// }
// }

/// <summary>
/// A TimeOfDay that represents a time that is not specified.
/// </summary>
public static TimeOfDay Empty
{
get
{
return new TimeOfDay(-1);
}
}

/// <summary>
/// Parse a formatted string and return it as a TimeOfDay
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static TimeOfDay Parse(string input)
{
DateTime tmpDT;
int ticks;

try
{
tmpDT = DateTime.Parse(input);
ticks = (int)(tmpDT.TimeOfDay.Ticks /
TimeSpan.TicksPerSecond);
}
catch
{
ticks = -1;
}

return new TimeOfDay(ticks);
}

/// <summary>
/// Compare two TimeOfDay objects.
/// </summary>
/// <param name="obj">The TimeOfDay to compare to.</param>
/// <returns>-1, 0 or 1.</returns>
public int CompareTo(object obj)
{
if (obj is TimeOfDay)
{
//
// We can do this
//
TimeOfDay otherTime = (TimeOfDay) obj;
return timeOfDay - otherTime.timeOfDay;
}
else
{
throw new ArgumentException();
}
}

/// <summary>
/// Compares two TimeOfDay objects to see if they represent the same
time.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
return (this.timeOfDay == ((TimeOfDay)obj).timeOfDay);
}

/// <summary>
/// Returns a hashcode for this time.
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return base.GetHashCode ();
}
/// <summary>
/// Compare two times to see if the left is less than the right.
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static bool operator <(TimeOfDay left, TimeOfDay right)
{
return (left.CompareTo(right) < 0);
}

/// <summary>
/// Compare two times to see if the left is less than or equal to
the right.
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static bool operator <=(TimeOfDay left, TimeOfDay right)
{
return (left.CompareTo(right) <= 0);
}

/// <summary>
/// Compare two times to see if the left is greater than the right.
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static bool operator >(TimeOfDay left, TimeOfDay right)
{
return (left.CompareTo(right) > 0);
}

/// <summary>
/// Compare two times to see if the left is greater than or equal to
the right.
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static bool operator >=(TimeOfDay left, TimeOfDay right)
{
return (left.CompareTo(right) >= 0);
}

/// <summary>
/// Compare two times to see if they are equal.
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static bool operator ==(TimeOfDay left, TimeOfDay right)
{
return (left.CompareTo(right) == 0);
}

/// <summary>
/// Compare two times to see if they are not equal.
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static bool operator !=(TimeOfDay left, TimeOfDay right)
{
return (left.CompareTo(right) != 0);
}

/// <summary>
/// Converts a TimeOfDay to a string.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return ToString(
CultureInfo.CurrentCulture.DateTimeFormat.ShortTim ePattern,
null);
}

/// <summary>
/// COnverts a TimeOfDay to a string using the specified
formatProvider.
/// </summary>
/// <param name="formatProvider"></param>
/// <returns></returns>
public string ToString(IFormatProvider formatProvider)
{
return ToString(
CultureInfo.CurrentCulture.DateTimeFormat.ShortTim ePattern,
formatProvider);
}

/// <summary>
/// COnverts a TimeOfDay to a string using the specified format.
/// </summary>
/// <param name="format"></param>
/// <returns></returns>
public string ToString(string format)
{
return ToString(format, null);
}

/// <summary>
/// Converts a TimeOfDay to a string using the specified format and
format provider.
/// </summary>
/// <param name="format"></param>
/// <param name="formatProvider"></param>
/// <returns></returns>
public string ToString(string format, IFormatProvider
formatProvider)
{
if ((timeOfDay < 0) || (timeOfDay >= 86400))
{
//
// The value is out of range
// We interpret this as a null time
//
return string.Empty;
}
else
{
//
// We have a valid value (number of seconds since midnight)
//
DateTime dtTmp = DateTime.Today;
dtTmp = dtTmp.AddSeconds(timeOfDay);
if (format == null)
{
return dtTmp.ToString(
CultureInfo.CurrentCulture.DateTimeFormat.ShortTim ePattern,
formatProvider);
}
else
{
return dtTmp.ToString(format, formatProvider);
}
}
}

/// <summary>
/// Returns a TimeSpan from midnight to the TimeOfDay
/// </summary>
/// <returns></returns>
public TimeSpan ToTimeSpan()
{
if (timeOfDay >= 0)
{
return new TimeSpan((TimeSpan.TicksPerSecond * timeOfDay));
}
else
{
return new TimeSpan(0);
}
}

/// <summary>
/// Returns the seconds between midnight and the time of day.
/// </summary>
public int TotalSeconds
{
get
{
return timeOfDay;
}
}
#region Implementation of ISerializable
//
// Code generated by BuildISerializable
//

/// <summary>
/// Deserialization constructor.
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
private TimeOfDay(SerializationInfo info, StreamingContext context)
{
timeOfDay = info.GetInt32("timeOfDay");
}

/// <summary>
/// Serializes a TimeOfDay.
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
// An unknown external module throws a SEHException when this line
is uncommented
//[SecurityPermission(SecurityAction.Demand,
SerializationFormatter=true)]
public void GetObjectData(SerializationInfo info, StreamingContext
context)
{
info.AddValue("timeOfDay", timeOfDay);
}
#endregion
}
}
Nov 12 '05 #4
Hi John,

Since Xml Serialization only serializes public fields, I added a public
property to the Comsumer class.

public string val
{
get
{
return m_StartTime.ToString();
}
set
{
m_StartTime = TimeOfDay.Parse(value);
}
}

As far as I can see, I don't know any better way to serialize the TimeOfDay
struct. Sorry for the inconvenience. HTH.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Nov 12 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
by: faktujaa | last post by:
Hi All, Microsoft says that structures are value types. Also primitive data types are value types. And memory for value types is allocated on the stack. Then why we need new operator to allocate...
1
by: Rafael Veronezi | last post by:
Just to fix, correct me if I am wrong... With reference types (objects), if I assign an object to another, the assignment will be the address of the object, and not a copy of it's contents right?...
2
by: Earl Teigrob | last post by:
I am saving and restoring value types such as Int32, DateTime and Boolean in strings. I was wondering if there is a mechanism build into .NET for serializing and deserializing these to string...
9
by: John | last post by:
If a value type is immutable, I guess it's threadsafe to read it? But not threadsafe to assign a new value to it (can any value type be truely immutable? Isn't assigning a totally new value to it,...
10
by: John Wood | last post by:
I was just looking at an article about using nullable value types. (value types that can effectively have no value and not be set). The syntax is to append a question-mark to the value type in...
24
by: ALI-R | last post by:
Hi All, First of all I think this is gonna be one of those threads :-) since I have bunch of questions which make this very controversial:-0) Ok,Let's see: I was reading an article that When...
5
by: Zach | last post by:
When it is being said that, "value types are created on the stack or inline as part of an object". If a value type is created in an object, and that object is being called, the value type in that...
7
by: stephan querengaesser | last post by:
hi ng, i try to invoke a webservice-method with an filter-object, that contains value types. if i donīt want to filter the return value of the method, i have to pass a new instance of the...
12
by: Edward Diener | last post by:
Given value class X { public: // Not allowed: X():i(100000),s(10000) { } // Allowed void InitializeDefaults() { i = 100000; s = 10000; } private: int i;
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.