将ModelStateDictionary序列化为XML

时间:2011-11-13 16:21:20

标签: c# asp.net-mvc-3 serialization

我尝试将ModelStateDictionary序列化为XML字符串。我尝试使用.net XML序列化类,如下所示:

        XmlSerializer serializer = new XmlSerializer(typeof(ModelStateDictionary));
        TextWriter textWriter = new StreamWriter("c:\\files\\text.xml");
        serializer.Serialize(textWriter,this.ModelState);
        textWriter.Close();

结果是:

<?xml version="1.0" encoding="utf-8"?>
   <ArrayOfKeyValuePairOfStringModelState xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
   <KeyValuePairOfStringModelState />
</ArrayOfKeyValuePairOfStringModelState>

所以以不同的方式尝试使用SharpSerializer和这段代码:

SharpSerializer serializer = new SharpSerializer();
serializer.Serialize(ModelState, "c:\\files\\text.xml");

这给了我一个错误:

Unable to cast object of type 'System.Web.Mvc.ModelStateDictionary' to type 'System.Collections.ICollection'.

使用此stacktrace:

    [InvalidCastException: Unable to cast object of type 'System.Web.Mvc.ModelStateDictionary' to type 'System.Collections.ICollection'.]
   Polenter.Serialization.Serializing.PropertyFactory.parseCollectionItems(CollectionProperty property, TypeInfo info, Object value) +121
   Polenter.Serialization.Serializing.PropertyFactory.fillCollectionProperty(CollectionProperty property, TypeInfo info, Object value) +75
   Polenter.Serialization.Serializing.PropertyFactory.CreateProperty(String name, Object value) +679
   Polenter.Serialization.SharpSerializer.Serialize(Object data, Stream stream) +196
   Polenter.Serialization.SharpSerializer.Serialize(Object data, String filename) +111
   Getronics.Web.Portal.Controllers.BaseCiController`1.Create(String btnaction, TRecordType dto) in C:\projects\Getronics\Getronics.Web.Portal\Controllers\BaseCiController.cs:58
   lambda_method(Closure , ControllerBase , Object[] ) +228
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +208
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
   System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +55
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263
   System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263
   System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +191
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
   System.Web.Mvc.Controller.ExecuteCore() +116
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8963149
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

所以这里没有运气。虽然我真的很想序列化模型状态。有谁知道如何使SharpSerializer与Dictionary对象一起使用?或者可能是一个不同的序列化器?

1 个答案:

答案 0 :(得分:0)

以下是如何使用以下Dictionary包装器序列化ModelStateDictionary的片段。

XmlSerializer serializer = new XmlSerializer(typeof(SerializableDictionaryWrapper<string, ModelState>));
TextWriter textWriter = new StreamWriter("c:\\files\\text.xml");
serializer.Serialize(textWriter,new SerializableDictionaryWrapper<string, ModelState>(this.ModelState));
textWriter.Close();

这是一个Dictionary包装类,它将使字典与XmlSerializer兼容。

/// <summary>
/// The XmlSerializer doesn't know how to serialize dictionaries and will refuse
/// to serialize anything that implements IDictionary.  This class can be used
/// to temporarily wrap a dictionary for the serialization process.
/// </summary>
[XmlRoot("DICTIONARY")]
public class SerializableDictionaryWrapper<TKey, TValue> : IXmlSerializable
{
  #region Data

  private IDictionary<TKey, TValue> m_dictionary = null;

  #endregion

  #region Properties

  /// <summary>
  /// Gets or sets the wrapped dictionary.
  /// </summary>
  /// <value>The wrapped dictionary.</value>
  public IDictionary<TKey, TValue> WrappedDictionary
  {
    get { return m_dictionary; }
    set { m_dictionary = value; }
  }

  #endregion

  #region Constructors

  /// <summary>
  /// 
  /// </summary>
  public SerializableDictionaryWrapper()
  {

  }

  /// <summary>
  /// 
  /// </summary>
  /// <param name="dict"></param>
  public SerializableDictionaryWrapper(IDictionary<TKey, TValue> dict)
  {
    m_dictionary = dict;
  }

  #endregion

  #region IXmlSerializable Members

  /// <summary>
  /// This property is reserved, apply the <see cref="T:System.Xml.Serialization.XmlSchemaProviderAttribute"></see> to the class instead.
  /// </summary>
  /// <returns>
  /// An <see cref="T:System.Xml.Schema.XmlSchema"></see> that describes the XML representation of the object that is produced by the <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)"></see> method and consumed by the <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)"></see> method.
  /// </returns>
  public System.Xml.Schema.XmlSchema GetSchema()
  {
    return null;
  }

  /// <summary>
  /// Generates an object from its XML representation.
  /// </summary>
  /// <param name="reader">The <see cref="T:System.Xml.XmlReader"></see> stream from which the object is deserialized.</param>
  public void ReadXml(System.Xml.XmlReader reader)
  {
    XmlSerializer key_serializer = new XmlSerializer(typeof(TKey));
    XmlSerializer value_serializer = new XmlSerializer(typeof(TValue));

    bool was_empty = reader.IsEmptyElement;

    m_dictionary = null;
    string type_name = reader.GetAttribute("type");
    if (type_name != null)
    {
      Type type = Type.GetType(type_name, false);
      if (type != null)
      {
        m_dictionary = Activator.CreateInstance(type) as IDictionary<TKey, TValue>;
      }
    }

    if (m_dictionary == null)
    {
      m_dictionary = new Dictionary<TKey, TValue>();
    }

    reader.Read();

    if (was_empty)
    {
      return;
    }

    while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
    {
      reader.ReadStartElement("item");

      reader.ReadStartElement("key");
      TKey key = (TKey)key_serializer.Deserialize(reader);
      reader.ReadEndElement();

      reader.ReadStartElement("value");
      TValue value = (TValue)value_serializer.Deserialize(reader);
      reader.ReadEndElement();

      m_dictionary.Add(key, value);

      reader.ReadEndElement();
      reader.MoveToContent();
    }
    reader.ReadEndElement();
  }

  /// <summary>
  /// Converts an object into its XML representation.
  /// </summary>
  /// <param name="writer">The <see cref="T:System.Xml.XmlWriter"></see> stream to which the object is serialized.</param>
  public void WriteXml(System.Xml.XmlWriter writer)
  {
    XmlSerializer key_serializer = new XmlSerializer(typeof(TKey));
    XmlSerializer value_serializer = new XmlSerializer(typeof(TValue));

    writer.WriteAttributeString("type", m_dictionary.GetType().AssemblyQualifiedName);

    foreach (TKey key in m_dictionary.Keys)
    {
      writer.WriteStartElement("item");

      writer.WriteStartElement("key");
      key_serializer.Serialize(writer, key);
      writer.WriteEndElement();

      writer.WriteStartElement("value");
      TValue value = m_dictionary[key];
      value_serializer.Serialize(writer, value);
      writer.WriteEndElement();

      writer.WriteEndElement();
    }
  }

  #endregion
};