Сериализация ModelStateDictionary в XML - PullRequest
1 голос
/ 13 ноября 2011

Я пытаюсь сериализовать 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'.

С помощью этой трассировки стека:

    [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 голосов
/ 13 ноября 2011

Ниже приведен фрагмент использования следующей обертки словаря для сериализации 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
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...