2010-06-11 9 views
5

Trong môi trường sản xuất của chúng tôi, các dịch vụ WCF của chúng tôi được tuần tự hóa với XMLSerializer. Để làm như vậy, các giao diện dịch vụ của chúng ta có thuộc tính [XMLSerializerFormat]. Bây giờ, chúng ta cần phải thay đổi thành DataContractSerializer nhưng chúng ta phải tương thích với các máy khách hiện tại của chúng ta. Vì vậy, chúng ta phải trưng ra từng dịch vụ với cả hai serializers.Làm thế nào để hỗ trợ cả DataContractSerializer và XMLSerializer cho cùng một hợp đồng trên cùng một máy chủ?

Chúng tôi có một hạn chế: chúng tôi không muốn để xác định lại mỗi giao diện hợp đồng hai lần, chúng tôi có giao diện hợp đồng 50 dịch vụ và chúng tôi không muốn có

IIncidentServiceXml 
IIncidentServiceDCS 
IEmployeeServiceXml 
IEmployeeServiceDCS 
IContractServiceXml 
IContractServiceDCS 

Làm thế nào chúng ta có thể làm điều đó?


thông tin

Đây là một mô tả về những gì chúng tôi đã cố gắng cho đến nay nhưng tôi sẵn sàng thử các cách tiếp cận hoàn toàn khác nhau thêm:

Chúng tôi đã cố gắng để tạo ra tất cả các thiết bị đầu cuối theo mã trong lớp ServiceHostFactory của chúng ta. Về cơ bản chúng tôi tạo ra mỗi điểm cuối hai lần. Vấn đề là ở thời gian chạy, WCF phàn nàn rằng dịch vụ có hai điểm cuối với cùng một tên liên lạc nhưng với các cá thể ContractDescription khác nhau. Thông báo cho biết chúng ta nên sử dụng các tên hợp đồng khác nhau hoặc sử dụng lại cùng một cá thể ContractDescription.

Các nỗ lực khác:

Chúng tôi cũng đã cố gắng thực hiện việc này bằng cách sử dụng các không gian tên khác nhau cho mỗi phiên bản ContractDescription. Bằng cách đó, chúng tôi sẽ giữ giao diện hợp đồng tương tự (IIncidentService) nhưng với hai không gian tên khác nhau:

http://ourcompany/XML/IIncidentService 
http://ourcompany/DCS/IIncidentService 

Với điều đó, chúng tôi đã có thể để có được xa hơn nhưng dịch vụ đâm với một ngoại lệ kỳ lạ:

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: 
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.XmlSerializerOperationBehavior 
contract: http://ourcompany.cs/XML:IUserServiceWCF ----> System.NullReferenceException: Object reference not set to an instance of an object. 
    at System.ServiceModel.Description.XmlSerializerMessageContractExporter.ExportFaults(Object state) 
    at System.ServiceModel.Description.MessageContractExporter.ExportMessageContract() 
    at System.ServiceModel.Description.XmlSerializerOperationBehavior.System.ServiceModel.Description.IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext contractContext) 
    at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension) 

Trả lời

1

Ngắn câu trả lời là, bạn không thể, vì chính xác lý do thông báo lỗi của bạn cho biết, bạn không thể có quá điểm cuối với cùng tên mà bạn đang cố gắng thực hiện. Tôi nghĩ bạn sẽ phải làm chính xác những gì bạn nói bạn không muốn.

This might be your only option

Vấn đề là phải xác định một dịch vụ là sử dụng XmlSerializer bạn cần phải khai báo [XmlSerializerFormat] thuộc tính trên dịch vụ hoặc hợp đồng. Kể từ khi chúng tôi muốn sử dụng giống nhau cho cả hai thiết bị đầu cuối , chúng tôi không thể đặt nó ở đó, vì vậy chúng tôi còn lại với việc đặt nó trên hợp đồng . Tuy nhiên, khi nó rơi xuống với nó, cả hai thiết bị đầu cuối đang sử dụng cùng một dịch vụ và gián tiếp cùng một hợp đồng ?

Vâng, nó không phải như vậy. Bạn có thể có hợp đồng A lấy từ hợp đồng số B, sau đó có dịch vụ thực hiện hợp đồng A sao cho tất cả mọi thứ trong cả hai hợp đồng là là một phần của dịch vụ.Tuy nhiên, với ví dụ này, , hợp đồng B sẽ là hợp đồng tiêu chuẩn của chúng tôi và hợp đồng A sẽ là là giao diện chỉ định thuộc tính [XmlSerializerFormat].

Nhưng tôi không thể hứa với bạn rằng sẽ làm việc với mã khách hàng hiện tại của bạn mà không có thay đổi.

+0

Tôi đã cập nhật câu hỏi của mình ở trên với một nỗ lực khác – Sylvain

0

Còn hai dịch vụ thực hiện cùng một hợp đồng thì sao?

Giống như:

class DcsService : Service 
{} 

[XmlSerializerFormat] 
class XmlService : Service 
{} 

class Service : IServiceContract 
{} 

Không bao giờ làm việc với XmlSerializer nhưng chúng ta sử dụng cấu trúc này cho các mục đích khác.

1

Chỉ cần tạo đối tượng của bạn bằng cách sử dụng thẻ [DataContract] và [DataMember]. Các XmlSerializer và DataContractSerializer sẽ cả hai serialze đối tượng tốt. Họ cập nhật The XmlSerializer trong khuôn khổ 3.0 để xử lý tuần tự hóa datacontract. DataContractSerializer có thể xử lý các đối tượng [Serializable] nhưng hành vi không chính xác và mất một số tinh chỉnh.

Chỉ cần tạo tất cả các đối tượng của bạn bằng cách sử dụng Hợp đồng dữ liệu. Bằng cách này bạn không phải lo lắng về việc thực hiện hai cuộc gọi (một cho mỗi). Bạn có thể sử dụng XmlSerializer hoặc DataContractSerializer không có vấn đề gì.

Nếu bạn cần thêm thuộc tính hành vi, bạn luôn có thể thêm cả [Serializable] và [DataContract] nếu muốn.

[Serializable] 
[DataContract] 
public class Customer 

{ 
    [DataMember] 
    public int Age { get; set; } 

    [DataMember] 
    public string Name { get; set; } 

    [DataMember] 
    public int Number { get; set; } 

    [DataMember] 
    public string FullName { get; set; } 

    [XmlIgnore] 
    public int IgnoredNumber { get; set; } 
} 

XmlSerializer serializes như:

<?xml version="1.0" encoding="utf-16" ?> 
<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Age>88</Age> 
    <Name>Bob</Name> 
    <Number>808</Number> 
    <FullName>Bob Jones</FullName> 
    </Customer> 

DataContractSerializer serializes như:

<?xml version="1.0" encoding="utf-8" ?> 
<Customer xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication1"> 
    <Age>88</Age> 
    <FullName>Bob Jones</FullName> 
    <Name>Bob</Name> 
    <Number>808</Number> 
    </Customer> 

Bạn rõ ràng có thể Buộc Namespace để họ cả hai trận đấu chính xác. Đây chỉ là mục đích ví dụ.