2016-12-11 4 views
1

많은 사람들이 동일한 문제를 가지고 있지만 해결 방법을 찾지 못했습니다.List (Of OtherClass)가 포함 된 클래스를 직렬화 할 때 오류가 발생했습니다.

내가 2 개 클래스 EmployeeDepartment

직원이 있다고 가정 나는 다음과 같은 코드를 실행

Imports System.ComponentModel 
Public Class Employee 
    Public Property Name As String 
    Public Property LastName As String 
    Public Property MotherName As String 

    Public Sub New(ByVal str1, ByVal str2, ByVal str3) 
     Name = str1 
     LastName = str2 
     MotherName = str3 
    End Sub 
End Class 

부서 클래스

Public Class Department 
    Public Property Employees As List(Of Employee) 

    Public Sub New() 
     Employees = New List(Of Employee) 
    End Sub 

    Public Sub WriteToXml(ByVal strXmlFilePath As String, 
          Optional ByVal encrypted As Boolean = False) 
     Dim xs As New Serialization.XmlSerializer(GetType(Department)) 
     Dim sr As New StringWriter 
     Dim strObject As String = String.Empty 

     xs.Serialize(sr, Me) 

     If encrypted Then 
      Dim wrapper As Simple3Des = New Simple3Des("123") 
      strObject = wrapper.EncryptData(sr.ToString) 
     Else 
      strObject = sr.ToString 
     End If 

     Using sw As New StreamWriter(strXmlFilePath) 
      sw.Write(strObject) 
      sw.Close() 
     End Using 
    End Sub 

    Public Sub ReadFromXml(ByVal strXmlFilePath As String, 
          Optional ByVal encrypted As Boolean = False) 
     Dim xs As New Serialization.XmlSerializer(GetType(Department)) 
     Dim strObject As String = String.Empty 
     Dim micResult As New Department 

     Using sr As New StreamReader(strXmlFilePath) 
      strObject = sr.ReadToEnd 

      If encrypted Then 
       Dim wrapper As Simple3Des = New Simple3Des("123") 
       strObject = wrapper.DecryptData(strObject) 
      End If 

      sr.Close() 
     End Using 

     micResult = DirectCast(xs.Deserialize(New StringReader(strObject)), Department) 
     Me.Employees.AddRange(micResult.Employees) 
     micResult.Dispose() 
    End Sub 

,363,210
 Dim m As New Employee("A", "B", "C") 
     Dim m1 As New Employee("D", "E", "F") 
     Dim ml1 As New Department 
     Dim ml2 As New Department 

     ml1.Employees.Add(m) 
     ml1.Employees.Add(m1) 

     ml1.WriteToXml("1.xml") 

나는 유형을 반영하는 오류가 발생했습니다

ml1.WriteToXml("1.xml")에 예외를 가지고 'SerializerTest.Department'

문제는 Department 클래스 내가 발견 List(of Employee)

포함되어 있다는 것입니다 많은 기사가이 문제에 대해 이야기하고 있지만 지금은이를 달성하는 방법이 없습니다.

Public Class Employee 

    Public Property Name As String 
    Public Property LastName As String 
    Public Property MotherName As String 

    Public Sub New() 

    End Sub 
    ... 

그러나 직렬화 방법은 약간의 낭비입니다

+1

XML 직렬화만을 다루는 경우에는 'Serializable' 속성이 필요 없습니다. 이진 직렬화에 사용됩니다. –

+2

Employee 클래스는 간단한 ctor가 없으므로 직렬화 할 수 없습니다. Departement를 직렬화 할 이유가 없습니다. Dept 소품 (예 : Name과 같은)이있는 경우 Employee 목록을 직렬화합니다. 내부 객체를 생성하고 요소를 Me에 복사합니다. 그냥 Department 객체를 반환하는 공유 메서드로 만들고 ... CrytoStream은 해당 암호화 메서드보다 더 좋거나 더 쉬울 수 있습니다. – Plutonix

+2

@VisualVincent 디자이너 직렬화에도 필요합니다. – Plutonix

답변

1

으뜸가는 문제는 Employee이 매개 변수가없는 생성자가 없다는 것입니다. 역 직렬화 할 때, Me에 내부, 임시 객체의 모든 데이터를 복사하는 대신, 앱 사용할 수 있도록 그것을 객체를 생성하고 반환하는 Shared 방법을 만들 수 있습니다

Public Class Department 
    ... 
    Public Shared Function Load(strXmlFilePath As String) As Department 
     Dim xs As New Serialization.XmlSerializer(GetType(Department)) 
     ' ToDo: return Nothing if file DNE 
     Using fs As New FileStream(strXmlFilePath, FileMode.Open) 
      Dim d As Department 
      d = xs.Deserialize(fs) 
      Return d 
     End Using 

    End Function 

그런 다음 생성 /를로드 부 객체 메소드를 사용하여 :

Dim d As New Department 
d.Employees.Add(New Employee("ziggy", "jones", "")) 
d.Employees.Add(New Employee("zoey", "smith", "")) 
d.Employees.Add(New Employee("hoover", "greene", "q")) 

d.WriteToXml("C:\Temp\Depts.xml") 

Dim d2 = Department.Load("C:\Temp\Depts.xml") 
'd2.ReadFromXml("C:\Temp\Depts.xml") 

For Each emp In d2.Employees 
    Console.WriteLine(emp.Name) 
Next 

내 모든 직원은 왕복했다 :

서버 ziggy을
zoey
후버