How to map XML document to entity framework object?
I have following entity framework object:
namespace Proj.Accounting.Entity
{
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
public partial class DocumentStatus
{
public DocumentStatus()
{
this.Documents = new HashSet<Document>();
this.DocumentsTrackings = new HashSet<DocumentsTracking>();
this.DocumentsTrackingChildDocuments = new HashSet<DocumentsTrackingChildDocument>();
}
[XmlElement("StateId")]
public int StateId { get; set; }
[XmlElement("StateName")]
public string StateName { get; set; }
[XmlElement("GroupId")]
public Nullable<int> GroupId { get; set; }
public virtual ICollection<Document> Documents { get; set; }
public virtual ICollection<DocumentsTracking> DocumentsTrackings { get; set; }
public virtual ICollection<DocumentsTrackingChildDocument> DocumentsTrackingChildDocuments { get; set; }
}
}
I have following class to map the entity with the xml fields (doesn't work like that):
using System;
using System.Collections;
using System.IO;
using System.Xml.Serialization;
namespace Proj.Accounting.Data
{
class XMLObjects
{
public static T ConvertXmlToClass<T>(string xml)
{
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(new StringReader(xml));
}
}
}
and the method I am using to map the data:
private void button1_Click(object sender, EventArgs e)
{
string xml = "";
xml += "<?xml version="1.0" encoding="UTF - 8"?>";
xml += "<root>";
xml += " <success>true</success>";
xml += " <data>";
xml += " <item>";
xml += " <StateId>0</StateId>";
xml += " <StateName>Шаблон</StateName>";
xml += " <GroupId>0</GroupId>";
xml += " </item>";
xml += "</root>";
DocumentStatus documentStatus = new DocumentStatus();
documentStatus = XMLObjects.ConvertXmlToClass<DocumentStatus>(xml);
int a = 0;
}
I am getting following exception
System.InvalidOperationException was unhandled HResult=-2146233079
Message=There was an error reflecting type 'Proj.Accounting.Entity.DocumentStatus'. Source=System.Xml
StackTrace:
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
at Proj.Accounting.Data.XMLObjects.ConvertXmlToClass[T](String xml) in c:UsersusernameDropboxDevProj.AccountingProj.Accounting.DataXMLObjects.cs:line 12
at Proj.Accounting.Data.MainForm.button1_Click(Object sender, EventArgs e) in c:UsersusernameDropboxDevProj.AccountingProj.Accounting.DataMainForm.cs:line 36
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Proj.Accounting.Data.Program.Main() in c:UsersusernameDropboxDevProj.AccountingProj.Accounting.DataProgram.cs:line 19
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart() InnerException: System.InvalidOperationException HResult=-2146233079
Message=Cannot serialize member 'Proj.Accounting.Entity.DocumentStatus.Documents' of type 'System.Collections.Generic.ICollection`1[[Proj.Accounting.Entity.Document,
Proj.Accounting.Entity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]', see inner exception for more details.
Source=System.Xml
StackTrace:
at System.Xml.Serialization.StructModel.CheckSupportedMember(TypeDesc typeDesc, MemberInfo member, Type type)
at System.Xml.Serialization.StructModel.GetPropertyModel(PropertyInfo propertyInfo)
at System.Xml.Serialization.StructModel.GetFieldModel(MemberInfo memberInfo)
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
InnerException: System.NotSupportedException
HResult=-2146233067
Message=Cannot serialize member Proj.Accounting.Entity.DocumentStatus.Documents of type
System.Collections.Generic.ICollection`1[[Proj.Accounting.Entity.Document,
Proj.Accounting.Entity, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null]] because it is an interface.
InnerException:
Everything is said in :
Cannot serialize member Proj.Accounting.Entity.DocumentStatus.Documents of type
System.Collections.Generic.ICollection1[[Proj.Accounting.Entity.Document, Proj.Accounting.Entity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] because it is an interface
Interface are not serializable. Transform all your ICollection properties to type HashSet to enable serialization of these items.
Serializable
I think the problem is that your class Document is not serializable. When you serialize an Object, all of their fields must be Serializable too. If you don't want to serialize the Documents member, mark it with [System.Xml.Serialization.XmlIgnoreAttribute]
To serialize an Object to XML, use the method Serialize and to deserialize use the method Deserialize. You don't need more than that.
More information: https://msdn.microsoft.com/es-es/library/system.xml.serialization.xmlserializer(v=vs.110).aspx
Tips
Also, change your string concatenation to use StringBuilder. If this is test code, remember that you can use += operator on strings, which results on Clean Code.
Examples:
string xml = "";
xml = xml + "<?xml version="1.0" encoding="UTF - 8"?>";
xml = xml + "<root>";
Using += operator (Same result but cleaner)
string xml = "";
xml += "<?xml version="1.0" encoding="UTF - 8"?>";
xml += "<root>";
Using StringBuilder (Best and fastest way)
StringBuilder xml = new StringBuilder();
xml.Append("<?xml version="1.0" encoding="UTF - 8"?>");
xml.Append("<root>");
链接地址: http://www.djcxy.com/p/27992.html
下一篇: 如何将XML文档映射到实体框架对象?
