Ich habe eine Datenzugriffsebene, eine Serviceebene und eine Präsentationsebene. Der Präsentations-Layer ist ASP.NET MVC2 RTM (Web) und der Service-Layer ist WCF (Services). Es ist alles .NET 3.5 SP1.Verwenden von WCF DataContract in MVC SessionState mit AppFabric-Cache
Das Problem besteht darin, dass in den Diensten die zurückgegebenen Objekte mit dem Attribut [DataContract]
gekennzeichnet sind. Das Web verwendet den SessionStateProvider von AppFabric Cache (a.k.a Velocity), um den Sitzungsstatus zu speichern. Aus diesem Grund muss alles, was ich in der Sitzung speichere, serialisierbar sein.
Hier kommt das Problem: die DataContracts sind nicht mit [Serializable]
markiert und soweit ich mich erinnern kann, treten bei Einführung in eine Klasse, die bereits mit [DataContract]
gekennzeichnet ist, Probleme auf, und ich glaube nicht, dass dies eine Lösung ist .
Ich plante ursprünglich, die DataContracts direkt in der Webschicht zu verwenden und sie als Modelle für Ansichten zu verwenden, die sich auf das Rendern der DataContracts beziehen (wahrscheinlich in einer höheren ViewModel-Klasse verschachtelt). Da jedoch der Sitzungszustandsanbieter alle darin gespeicherten Objekte serialisieren muss, überlege ich, diese Strategie zu überdenken. Es wäre jedoch nett, dies zu tun, da sie eine Validierungslogik unter Verwendung der IDataErrorInfo
Schnittstelle enthalten und dieselbe Validierungslogik in MVC als Teil der Modellbindung wiederverwendet werden könnte.
Was glauben Sie, ist der beste Weg, um die Arbeit zu reduzieren?
ich zur Zeit habe gedacht, die folgenden verschiedenen Möglichkeiten:
A. Erstellen Sie einen ‚ServiceIntegration‘ an dem Web-Projekt.
Das wäre ein Mittelmann zwischen meinen Controllern und meiner WCF-Dienstschicht. Der ServiceIntegration-Teil würde mit DataContracts mit der Service-Schicht und mit ViewModels mit der Web-Schicht kommunizieren, müsste jedoch zwischen den DataContracts und ViewModels mit einem bidirektionalen Transformer transformieren.
Da die IDataErrorInfo-Validierung nicht wiederverwendbar wäre, müsste auch ein Validator pro DataContract erstellt werden, der Transformer zum Konvertieren von ViewModel in DataContract verwendet, die Validierung mit IDataErrorInfo durchführt und die Ergebnisse zurückgibt. Dies würde dann in Aktion Methoden des Controller verwendet werden (zB if (!MyValidator.IsValid(viewModel)) return View();
)
Verschiedene Klassen benötigt: xDataContract, xViewModel, xTransformer, xValidator
B. erstellen 'SessionIntegration' an dem Web-Projekt
Dies wäre ein Mittelmann zwischen den Controllern (oder jedem, der auf die Sitzung zugreift) und der Sitzung selbst. Alles, was Zugriff auf die Sitzung erfordert, würde diese Klasse durchlaufen. DataContracts werden in der gesamten Anwendung verwendet, sofern sie nicht in der Sitzung gespeichert werden. Der SessionIntegration-Teil würde die Verantwortung übernehmen, den DataContract in eine ISerializable-Form und zurück zu transformieren. Aufgrund der Verwendung der IDataErrorInfo-Schnittstelle auf dem DataContract ist kein zusätzlicher Validator erforderlich.
Verschiedene Klassen benötigt: xDataContract, xTransformer, xSerializableForm
Hinweis: es würden immer noch Viewmodel sein um in beiden Szenarien, aber mit (B) ich in der Lage sein würde Viewmodel von Datacontracts zu komponieren.
(B) hat den Vorteil, dass kein zusätzlicher Validator benötigt wird.
Bevor ich ausgehe und (A)/(B) vollständig implementiere, möchte ich ein Feedback geben. Im Moment fange ich an, mich zu (B) zu neigen, aber (A) könnte flexibler sein. So oder so, es scheint viel zu viel Arbeit für das, was es wert ist. Ist jemand anderes auf dieses Problem gestoßen, stimmen Sie mir zu oder haben Sie eine andere Möglichkeit, das Problem zu lösen?
Danke,
James
Ich könnte AutoMapper als Teil der Tr verwenden Ansager, und so sind die Mapping-Details möglicherweise nicht so ein Overhead. Manuelles Zuordnen der ViewModels zu DataContracts und umgekehrt ist definitiv eine Menge Arbeit für das, was es wert ist, IMHO – jamiebarrow