2012-03-21 4 views
1

NetDataContractSerializer를 사용하고 있습니다. 내가 만들고, 추가하고 데이터 파일에 개체를 아무 문제없이 직렬화 할 수 있습니다. 파일을 GUI로 다시로드해도 아무런 문제가 없습니다.개체 제거 후 직렬화 오류 (NetDataContractSerializer)

그러나 데이터에서 개체를 삭제 (제거)하고 데이터를 다시 저장 (직렬화)하려고하면 문제가 발생합니다.

다음은 내 방 삭제 버튼입니다. 사용자가 특정 층의 방을 삭제할 것을 요청하면 프로그램은 해당 층의 특정 방에있는 객체의 목록을 생성합니다. 그런 다음 삭제하고 현재보고있는 양식을 닫고 데이터를 저장하십시오.

프로그램이 중단되지 않고 현재 방의 방 목록에서 방이 제거되면 작동하는 것처럼 보입니다. ..

"객체 직렬화 복원 오류가 발생했습니다 루트 레벨에서 데이터가 잘못되었습니다 라인 1 : 내가 (프로그램 닫기, 개방 및로드) 파일을 다시로드 할 때

그러나 나는이 오류 , 위치 1 " 여기

여기
 private void btn_deleteRoom_Click(object sender, EventArgs e) 
    { 
     var assets = getAssetsForCurrentRoom(); 
     string warningMessage = "Deleting this room will delete this room and all contained assets! Are you sure you want to do this?"; 
     string caption = "WARNING!"; 
     MessageBoxButtons buttons = MessageBoxButtons.YesNo; 
     DialogResult result; 
     //Display the MessageBox 
     result = MessageBox.Show(warningMessage, caption, buttons); 
     if (result == System.Windows.Forms.DialogResult.Yes) 
     { 
      var itemsToRemove = new ArrayList(); 
      foreach (var item in currentHouse.GetAssets()) 
      { 
       if (item.Parent.Name == currentRoom.Name) 
       { 
        itemsToRemove.Add(item); 
       } 
      } 
      foreach (var item in itemsToRemove) 
      { 
       currentHouse.deleteAsset((Asset)item); 
      } 
      currentHouse.DeleteRoom(currentRoom); 
      PersistanceController.SaveHouseWithCurrentPath(currentHouse); 
      this.Close(); 
     } 
    } 

이 방법 deleteAsset (내 CRUD) 여기

public void deleteAsset(Asset asset) 
    { 
     //is null? 
     if (asset == null) 
     { 
      throw new ArgumentNullException("asset", "Asset cannot be null."); 
     } 
     //is blank 
     if (string.IsNullOrWhiteSpace(asset.Name)) 
     { 
      throw new ArgumentNullException("asset", "Asset name cannot be blank | null."); 
     } 
     var listAsset = _assets.FirstOrDefault(existingAsset => (existingAsset.Name == asset.Name)); 
     if (listAsset != null) 
     { 
      _assets.Remove(asset); 
     } 
     else 
     { 
      throw new InvalidOperationException("Asset does not exist; thus it can not be deleted."); 
     } 
    } 

public static class PersistanceController 
{ 

    public static string LastLoadedPath { get; set; } 

    public static House LoadHouse(string path) 
    { 
     NetDataContractSerializer houseDeserializer = new NetDataContractSerializer(); 

     FileStream houseFileStream = new FileStream(path, FileMode.Open); 
     House deserialzedHouse = (House)houseDeserializer.Deserialize(houseFileStream); 

     houseFileStream.Close(); 

     LastLoadedPath = path; 

     return deserialzedHouse; 
    } 

    public static void SaveHouseWithCurrentPath(House house) 
    { 
     SaveHouse(house, LastLoadedPath); 
    } 

    public static void SaveHouse(House house, string path) 
    { 

     //save house 
     NetDataContractSerializer xmlSerializer = new NetDataContractSerializer(); 
     Stream streamWriter = new FileStream(path, FileMode.OpenOrCreate); 
     xmlSerializer.Serialize(streamWriter, house); 

     streamWriter.Close(); 
    } 
} 

답변

2

내가 생각하는 내 PersistanceController 내 deleteRoom 버튼 귀하 문제가일 수 있습니다.. 그냥 FileMode.Create으로 만들면 원래 (더 긴) 파일에서 원치 않는 꼬리가 생깁니다.

그리고, 주제는 FileStreams와 함께 작동하려면 using() {} 블록을 사용하십시오.

+0

...... 감사합니다 중위 사령관 데이터 ..... 아주 훌륭합니다! =) – Ealianis