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文档映射到实体框架对象?