2013-01-06 7 views
9

Mam klasy SearchError która dziedziczy Exception, a kiedy tylko próbuję deserializowania ją z ważnego json pojawia się następujący wyjątek:Json.net nie powiedzie się podczas próby deserializacji klasy, która dziedziczy z Exception

ISerializable type 'SearchError' does not have a valid constructor. To correctly implement ISerializable a constructor that takes SerializationInfo and StreamingContext parameters should be present. Path '', line 1, position 81. 

Próbowałem implementacji sugerowanego brakującego konstruktora, a to nie pomogło.

Jest to klasa po wdrożeniu zaproponowanej konstruktora:

public class APIError : Exception 
{ 
    [JsonProperty("error")] 
    public string Error { get; set; } 

    [JsonProperty("@http_status_code")] 
    public int HttpStatusCode { get; set; } 

    [JsonProperty("warnings")] 
    public List<string> Warnings { get; set; } 

    public APIError(string error, int httpStatusCode, List<string> warnings) : base(error) 
    { 
     this.Error = error; 
     this.HttpStatusCode = httpStatusCode; 
     this.Warnings = warnings; 
    } 

    public APIError(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) 
     : base(info, context) 
    { 
     Error = (string)info.GetValue("error", typeof(string)); 
     HttpStatusCode = (int)info.GetValue("@http_status_code", typeof(int)); 
     Warnings = (List<string>)info.GetValue("warnings", typeof(List<string>)); 
    } 
} 

Teraz dostaję następujący wyjątek (również w kodzie Json.NET):

Member 'ClassName' was not found. 

Próbowałem też wdrażającego takie samo rozwiązanie jak w przypadku this related question, również otrzymałem ten sam błąd powyżej.

+0

Podziel kod z ludźmi .. –

+0

To pytanie zostało tutaj odpowiedział: http://stackoverflow.com/a/3423037/504836 – joelnet

Odpowiedz

7

To pytanie zostało tutaj odpowiedział: https://stackoverflow.com/a/3423037/504836

Dodanie nowego konstruktora

public Error(SerializationInfo info, StreamingContext context){} 

rozwiązać mój problem.

Oto kompletny kod:

[Serializable] 
public class Error : Exception 
{ 

    public string ErrorMessage { get; set; } 

    public Error(SerializationInfo info, StreamingContext context) { 
     if (info != null) 
      this.ErrorMessage = info.GetString("ErrorMessage"); 
    } 
    public override void GetObjectData(SerializationInfo info,StreamingContext context) 
    { 
     base.GetObjectData(info, context); 

     if (info != null) 
      info.AddValue("ErrorMessage", this.ErrorMessage); 
    } 
} 
+2

Ta odpowiedź jest bezużyteczna, ponieważ nie zawsze możesz dodać członka do klasy, której nie jesteś właścicielem. Na przykład, mam ten błąd, próbując serializować wyjątek DbUpdateConcurrencyException zgłaszany przez Entity Framework. Nie mam kontroli nad tą klasą lub jej członkami ani nad tym, jaka instancja jest rzucana. – Triynko

+0

@ Łukasz Lysik ma rację, że odpowiedź wymaga poprawy, ale najlepsza poprawa jest w istocie uproszczeniem. Potwierdziłem, przechodząc przez kod i zapisując cały obiekt i jego właściwości, że jedyne oświadczenie, które musi znajdować się w GetObjectData, jest pierwszym, base.GetObjectData (info, context); Potwierdziłem, że wszystkie zaludnienia są zapełnione, w tym HRESULT, który jest chroniony w .NET 2.0. To samo dotyczy konstruktora. –

2

Jak mówi błędu brakuje konstruktora serializacji:

public class SearchError : Exception 
{ 
    public SearchError(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) 
    { 

    } 
} 
+0

Próbowałem swoje sugestie, które Próbowałem już wcześniej, a teraz otrzymuję inny wyjątek (patrz wyżej). –

+2

": base (info, context)" zgłasza wyjątek "Member" ClassName "nie został znaleziony." – joelnet

+0

@joelnet: to jest problem z kodem, a nie odpowiedzią. Zobacz link MSDN na przykład: http://msdn.microsoft.com/en-us/library/tz6bzkbf.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2 –

Powiązane problemy