2009-06-16 9 views
4

Ich habe eine E-Commerce-ASP.NET (C# Code hinter) Web-Anwendung geerbt. Wir sind kürzlich Server umgezogen und es erweist sich als etwas problematisch. Ich habe sehr wenig Erfahrung mit IIS-Server-Konfiguration und Umgang mit großen Projekten wie diesem. Die meisten Probleme sind jetzt behoben, aber wir haben Probleme mit einem entscheidenden Teil, da ein Kunde versucht, eine Zahlung zu leisten.
Da der Kunde die Zahlung bestätigt, trifft die Anwendung die folgende Fehlermeldung:Serialisierung Ausnahme in kompilierte DLL

Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET 
will serialize the session state objects, and as a result non-serializable objects or 
MarshalByRef objects are not permitted. The same restriction applies if similar 
serialization is done by the custom session state store in 'Custom' mode. 

Stack Trace:

[SerializationException: Type 'PayerAuthentication.PayerAuthenticationServicePost' in Assembly 'PayerAuthentication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.] 
    System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +7733643 
    System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +258 
    System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +111 
    System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) +161 
    System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) +51 
    System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +410 
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +134 
    System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1577 

Google-Suchergebnisse anzuzeigen, ich [Serializable] zu der Klassendeklaration betroffen hinzufügen sollte, aber dies ist in eine kompilierte DLL, zu der ich kein csproj habe. Der Code funktionierte auf dem vorherigen Server einwandfrei, und ich glaube nicht, dass Änderungen am Code vorgenommen wurden, nur an web.config - was kann ich tun?

Der session Abschnitt von web.config liest <sessionState mode="StateServer" />

UPDATE1: Mit Reflektor, ich die Klasse oben ausgeführt, machte es serializable, neu kompiliert und ersetzt die DLL. Der Bestellvorgang ging einen Schritt weiter, woraufhin ich für eine andere dll-kompilierte Klasse den gleichen Fehler fand. Wieder einmal konnte ich Reflector verwenden, um den Code zu sehen und ihn dann zu exportieren, zu bearbeiten und neu zu kompilieren.
Jetzt habe ich die gleichen Fehler auftreten, in:

SerializationException: Type 'System.Runtime.Remoting.Messaging.AsyncResult' in Assembly 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.] 

Ich bin nicht sicher, ob ich etwas dagegen tun kann, da dieser Teil der .net-Systemdateien sein muss! Irgendwelche weiteren Ideen?

UPDATE2: Ha, auch ich habe später entdeckt es die Verarbeitung der Zahlungen korrekt, aber dann auf System.Runtime.Remoting.Messaging.AsyncResult die oben Unable to serialize the session state Fehler zu werfen, bevor der Benutzer Erhalt der Transaktion erhält. Nicht gut. Nicht sicher, wie vorwärts jetzt bewegen ...

UPDATE3: Ich habe versucht, eine Kopie der System.Runtime.Remoting.Messaging.AsyncResult Klasse erstellen, und es serializable machen, aber das wird dann zu einem uneinheitlichen Zugangsproblemen führen.

using System; 
using System.Runtime.InteropServices; 
using System.Threading; 
using System.Security.Permissions; 
using System.Runtime.Remoting.Messaging; 

    [Serializable, ComVisible(true)] 
    public class myAsyncResult : IAsyncResult, IMessageSink 
    { 
     // Fields 
     private AsyncCallback _acbd; 
     private Delegate _asyncDelegate; 
     private object _asyncState; 
     private ManualResetEvent _AsyncWaitHandle; 
     private bool _endInvokeCalled; 
     private bool _isCompleted; 
     private IMessageCtrl _mc; 
     private IMessage _replyMsg; 

     // Methods 
     internal myAsyncResult(Message m); 
     //[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] 
     public virtual IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink); 
     private void FaultInWaitHandle(); 
     public virtual IMessage GetReplyMessage(); 
     public virtual void SetMessageCtrl(IMessageCtrl mc); 
     //[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] 
     public virtual IMessage SyncProcessMessage(IMessage msg); 

     // Properties 
     public virtual object AsyncDelegate { get; } 
     public virtual object AsyncState { get; } 
     public virtual WaitHandle AsyncWaitHandle { get; } 
     public virtual bool CompletedSynchronously { get; } 
     public bool EndInvokeCalled { get; set; } 
     public virtual bool IsCompleted { get; } 
     public IMessageSink NextSink { [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] get; } 
    } 

Insbesondere dass error CS0122: 'System.Runtime.Remoting.Messaging.Message' is inaccessible due to its protection level. Ich kann sehen, das ist, weil Nachricht eine interne Klasse ist. Aber ich kann die Barrierefreiheitsebene nicht ändern, da sie Teil des Namespaces System.Runtime ist. Und eine Kopie zu machen und sie umzubenennen, wird das gleiche Problem noch einmal verursachen.
Kann mir jetzt jemand helfen?

FINAL UPDATE Sieht aus wie, nach all dem, dass es das SSL-Zertifikat (siehe meine Antwort unten) war

+0

Wie sieht der bperreault

Antwort

1

Ich glaube jetzt, dass dieses Problem auftrat, als wir ein neues SSL-Zertifikat installierten.

Das neue Zertifikat hatte Postleitzahlenerweiterungen, die unser Zahlungspartner HSBC nicht über sein CPI-Zahlungsgateway akzeptiert.

Das richtige SSL-Zertifikat zu installieren, scheint dieses Problem endgültig gelöst zu haben.

1

Sie werden, wenn benötigen, um herauszufinden, der neue Server eine neuere Version als die alte ist oder ein älterer. Wenn es eine ältere Version ist, dann aktualisieren Sie es auf die neuere Version, und die Dinge sollten funktionieren.

Wenn es neuer ist, dann ist es Ihr Code (dem Sie eine Quelle zuweisen), der diese nicht serialisierbaren Objekte in den Sitzungszustand versetzt? Wenn ja, können Sie vielleicht Ihre eigene Klasse erstellen, um die Eigenschaften der alten Klasse zu spiegeln. Machen Sie Ihre Klasse serialisierbar und setzen Sie eine Instanz Ihrer Klasse in den Sitzungszustand.Erstellen Sie eine Instanz der alten Klasse, wenn Sie Ihre Sitzung beenden.

+0

Die Serverversion ist identisch: 2.0.50727.3082 – fearoffours

0

Wenn der Code zuvor nur den In-Memory-State-Provider verwendet hat, könnte dies ... knifflig sein. Es ist ein Schwachpunkt, dass der Serialisierungsprozess (über BinaryFormatter, den der Datenbank-State-Provider verwendet) das [Serializable]-Attribut erfordert, wenn der Standardanbieter dies nicht tut.

Wie viel des Codes können Sie bearbeiten? Irgendwas davon? Können Sie beispielsweise den Code ändern, der Dinge in den/aus dem Status versetzt? Sie könnten vielleicht ein separates (serialisierbares) DTO mit den notwendigen Eigenschaften verwenden und zwischen ihnen mit Ihrem eigenen Code übersetzen.

Weitere Optionen:

  • gehen zurück auf die In-Memory-Provider (und winken zu einem Cluster)
  • einen Anbieter schreiben, die nicht BinaryFormatter

Ich habe nicht verwendet einige Gedanken zu letzterem, aber ich bezweifle, dass es trivial wäre

2

Wenn Sie wirklich den Code wollten, könnten Sie versuchen, Reflector's Class View zu verwenden. Zumindest könnte es Ihnen helfen zu überprüfen, ob [Serializable] Teil der Problemklassendefinition war oder nicht.

+0

Das war brillant. Ich habe Reflector verwendet, um den Code zu exportieren, '[Serializable]' zur Klasse hinzuzufügen, ihn zu kompilieren, die vorhandene DLL mit der neuen zu überschreiben und das unmittelbare Problem zu lösen, obwohl eine andere Klasse jetzt den gleichen Fehler auslöst. Ich wiederhole das Verfahren für diese Klasse (und alle anderen). – fearoffours

+0

Ich bin froh, dass es geholfen hat. Das war genau das, was ich dachte, wenn das fehlende Attribut das Problem war. –

+0

Yup, defiitely löste das sofortige Problem (zweimal, tatsächlich) aber bin jetzt wie per Updates im ursprünglichen Post stecken) – fearoffours

0

Wenn die Frage nur ist, wie Sie die Anwendung ohne diesen Fehler ausführen, ist die schnelle Lösung, das Modusattribut des sessionState-Elements auf "InProc" zu setzen.

+0

Nein, ich brauche die Anwendung, um richtig zu funktionieren, nicht nur ohne den Fehler ausgeführt werden. Wenn Sie den seeisionState in "InProc" ändern, wird der Warenkorb nicht aktualisiert, wenn Produkte hinzugefügt werden! – fearoffours

Verwandte Themen