2017-10-01 2 views
-1

Ich habe einen benutzerdefinierte user control erstellt und enthält ein Privateigentum und eine öffentliche Methode wie folgt:Wie kann man den Lambda-Ausdruck in ViewState speichern und zurückholen?

private dynamic OptionalPredicate { get;set; } 

public void SetOptionalPredicate<T>(Expression<Func<T, bool>> value) 
{ 
      OptionalPredicate = value; 
} 

Ich habe ein Webformular, die zwei Instanzen von meinem benutzerdefinierten Benutzersteuerelement enthält. In einem Klickereignis in meinem Webformular rufe ich die SetOptionalPredicate-Methode auf, um ein Standardprädikat für eines der Benutzersteuerelemente festzulegen, da Sie sehen können, was die Methode im obigen Code bewirkt.

Ich habe folgendes Problem:

Nach einem Postbacks in der zweiten Usercontrol, die ich die SetOptionalPredicate Methode für sie aufgerufen haben, wird der Wert für OptionalPredicatenull wird.

Ich weiß, dass nach postback alle Variablen null werden. Die Antwort könnte ViewState verwenden. Ich suchte im Internet und fand keine Antwort darauf, wie Sie lambda expression in und von ViewState speichern und abrufen können.

habe ich versucht, den folgenden Code, aber es funktioniert nicht:

private dynamic OptionalPredicate 
     { 
      get 
      { 
       if (this.ViewState[this.ClientID + "OptionalPredicate"] != null) 
       { 
        return this.ViewState[this.ClientID + "OptionalPredicate"] as dynamic; 
       } 
       else 
       { 
        return default(dynamic); 
       } 
      } 
      set 
      { 
       this.ViewState[this.ClientID + "OptionalPredicate"] = value; 
      } 
     } 

und ich erhalte die folgende Ausnahme:

Type 'System.Linq.Expressions.Expression`1[[System.Func`2[[APA.Model.Models.APAProjectComponent, APA.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' in Assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable. 
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Runtime.Serialization.SerializationException: Type 'System.Linq.Expressions.Expression`1[[System.Func`2[[APA.Model.Models.APAProjectComponent, APA.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' in Assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable. 

mir jemand helfen könnte, mit wie richtige getter und setter für die schreiben OptionalPredicate um ViewState zum Speichern der lamda exression zu verwenden und die Schnittstelle der Eigenschaft und die SetOptionalPredicate Methode nicht zu ändern?

Vielen Dank im Voraus

+0

Ich bekomme Ihre Frage nicht. Wenn Sie einen Viewstatus für eine Instanz speichern, wie kann sich dies auf eine andere Instanz auswirken? Wenn instance1.something auf viewstate gesetzt wird, wird instance2 nicht erstellt.etwas bekommen diesen Wert –

+0

@Ray H Ich habe meine Frage bearbeitet. – Karamafrooz

+3

Ausnahme ist ziemlich klar: ein Ausdruck ist nicht serialisierbar, also viel Glück, wenn Sie es über den Draht senden möchten. Es gab einige Versuche von Drittanbietern, dies zu erreichen, aber ich habe keine Ahnung, ob das alles gut funktioniert. Aber warum macht es so schwer? Warum verwenden Sie keinen Schlüsselwert, um das Prädikat aus einem Wörterbuch in Ihrem C# -Code zu finden? –

Antwort

-1

Ich konnte endlich einen Workaround finden und ich werde es mit jedem teilen, der das gleiche Problem haben könnte. I installiert, um das Paket linq serializer

und von der Bibliothek unter Verwendung von I den Getter und Setter für die OptionalPredicate neu geschrieben wie folgt und serialized das Prädikat, bevor es in den Ansichtszustand speichern und deserialized es, nachdem es von Ansichtszustand Abrufen:

private dynamic OptionalPredicate 
     { 
      get 
      { 
       if (this.ViewState[this.ClientID + "OptionalPredicate"] != null) 
       { 
        var expressionSerializer = new Serialize.Linq.Serializers.ExpressionSerializer(new Serialize.Linq.Serializers.XmlSerializer()); 
        return expressionSerializer.DeserializeText(this.ViewState[this.ClientID + "OptionalPredicate"].ToString()) as dynamic; 
       } 
       else 
       { 
        return default(dynamic); 
       } 
      } 
      set 
      { 
       var expressionSerializer = new Serialize.Linq.Serializers.ExpressionSerializer(new Serialize.Linq.Serializers.XmlSerializer()); 
       this.ViewState[this.ClientID + "OptionalPredicate"] = expressionSerializer.SerializeText(value); 
      } 
     } 

und alles funktioniert gut :)

+0

@Downvoter Pflege Kommentar? – Karamafrooz

+0

interessanter Ansatz. Im Wesentlichen baut die Bibliothek den Ausdrucksbaum neu als Baum von serialisierbaren Objekten und andersherum auf – devio

-1

Sie können nicht.

Sie müssen Ihre Vorgehensweise ändern, um die Bedingungen für SetOptionalPredicate zu definieren, die aufgerufen werden, und eine Darstellung der Bedingungen in ViewState speichern.

Wenn die Lambda-Ausdrücke für den Aufruf komplexer sind, können Sie eine Klasse SetOptionalPredicateBuilder definieren, die einen SetOptionalPredicate-Parameter nur auf der Grundlage von Eingabewerten erstellt.

Dann würde ViewState alle diese Eingabewerte speichern. Das Formular (oder Benutzersteuerelement) ruft den Builder mit den in ViewState enthaltenen Werten auf.

Verwandte Themen