"Kevin Yu [MSFT]" <v-****@online.mic rosoft.com> wrote in message
news:6O******** ******@cpmsftng xa06.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.Seri alization;
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:3 0");
//
// Create the XmlSerializer
//
XmlSerializer serializer = new XmlSerializer(c o.GetType());
//
// Serialize!!
//
serializer.Seri alize(Console.O ut, co);
//
// Pause
//
Console.WriteLi ne();
Console.WriteLi ne("StartTime should be {0}", co.StartTime);
Console.WriteLi ne("Press Return to continue");
Console.ReadLin e();
}
}
}
/////// TimeOfDay.cs
using System;
using System.Componen tModel;
using System.Globaliz ation;
using System.Runtime. Serialization;
using System.Security .Permissions;
using System.Xml.Seri alization;
namespace XmlSample
{
/// <summary>
/// TimeOfDayConver ter is a TypeConverter for the TimeOfDay type.
/// </summary>
public class TimeOfDayConver ter : TypeConverter
{
/// <summary>
/// Returns true if the passed source Type can be converted into a
TimeOfDay.
/// </summary>
/// <param name="context"> </param>
/// <param name="sourceTyp e">THe Type to be converted.</param>
/// <returns>True if the conversion can be done.</returns>
public override bool CanConvertFrom(
ITypeDescriptor Context context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
else
{
return base.CanConvert From(context, sourceType);
}
}
/// <summary>
/// Converts the passed value into a TimeOfDay.
/// </summary>
/// <param name="context"> </param>
/// <param name="culture"> </param>
/// <param name="value">Th e value to convert into a
TimeOfDay.</param>
/// <returns>The new TimeOfDay.</returns>
public override object ConvertFrom(
ITypeDescriptor Context context, CultureInfo culture, object
value)
{
if (value is string)
{
return TimeOfDay.Parse ((string)value) ;
}
else
{
return base.ConvertFro m(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">Th e TimeOfDay</param>
/// <param name="destinati onType">The destination Type</param>
/// <returns>The new object created from the TimeOfDay.</returns>
public override object ConvertTo(
ITypeDescriptor Context context, CultureInfo culture, object
value, Type destinationType )
{
if ((destinationTy pe == typeof(string))
&& (value is TimeOfDay))
{
return
((TimeOfDay)val ue).ToString(cu lture.DateTimeF ormat.ShortTime Pattern);
}
else
{
return base.ConvertTo( context, culture, value,
destinationType );
}
}
}
/// <summary>
/// The TimeOfDay represents a time of day.
/// </summary>
[Serializable,
TypeConverter(t ypeof(TimeOfDay Converter)),
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(DateT ime initial)
{
timeOfDay = (int)(initial.T imeOfDay.Ticks /
TimeSpan.TicksP erSecond);
}
/// <summary>
/// Constructs a TimeOfDay from a string.
/// </summary>
/// <param name="initial"> The string.</param>
public TimeOfDay(strin g initial)
{
DateTime tmpDT;
try
{
tmpDT = DateTime.Parse( initial);
timeOfDay = (int)(tmpDT.Tim eOfDay.Ticks /
TimeSpan.TicksP erSecond);
}
catch
{
timeOfDay = -1;
}
}
/// <summary>
/// A TimeOfDay that is the current time.
/// </summary>
public static TimeOfDay Now
{
get
{
return new TimeOfDay(DateT ime.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.Tim eOfDay.Ticks /
TimeSpan.TicksP erSecond);
}
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(objec t obj)
{
if (obj is TimeOfDay)
{
//
// We can do this
//
TimeOfDay otherTime = (TimeOfDay) obj;
return timeOfDay - otherTime.timeO fDay;
}
else
{
throw new ArgumentExcepti on();
}
}
/// <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.GetHashCod e ();
}
/// <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.Cur rentCulture.Dat eTimeFormat.Sho rtTimePattern,
null);
}
/// <summary>
/// COnverts a TimeOfDay to a string using the specified
formatProvider.
/// </summary>
/// <param name="formatPro vider"></param>
/// <returns></returns>
public string ToString(IForma tProvider formatProvider)
{
return ToString(
CultureInfo.Cur rentCulture.Dat eTimeFormat.Sho rtTimePattern,
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="formatPro vider"></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.AddSecond s(timeOfDay);
if (format == null)
{
return dtTmp.ToString(
CultureInfo.Cur rentCulture.Dat eTimeFormat.Sho rtTimePattern,
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((TimeS pan.TicksPerSec ond * 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 BuildISerializa ble
//
/// <summary>
/// Deserialization constructor.
/// </summary>
/// <param name="info"></param>
/// <param name="context"> </param>
private TimeOfDay(Seria lizationInfo info, StreamingContex t 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
//[SecurityPermiss ion(SecurityAct ion.Demand,
SerializationFo rmatter=true)]
public void GetObjectData(S erializationInf o info, StreamingContex t
context)
{
info.AddValue(" timeOfDay", timeOfDay);
}
#endregion
}
}