2013-03-06 15 views
25

Tôi đang tuần tự hóa dữ liệu trong ứng dụng Mono For Android và gửi nó bằng REST tới máy chủ .NET đang nghe bằng WCF. Cho đến nay điều này đã làm việc tốt, tuy nhiên, với hợp đồng dữ liệu cụ thể này, mặc dù máy chủ không có lỗi, Danh sách bên trong hợp đồng dữ liệu hiển thị dưới dạng trống.Đầu ra của DataContractSerializer khác giữa .NET và Mono

Sử dụng Fiddler và tạo hai dự án có cùng mã, tôi đã có thể so sánh đầu ra .NET DataContractSerializer bình thường với đầu ra từ việc triển khai DataContractSerializer của Mono.

NET đầu ra:

<VisitDataContractEx xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts"> 
    <_isDirty xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">true</_isDirty> 
    <_id xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.Domain" xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:internalValue>a7b97b48-d3a9-419d-9f4e-330ffc7a01ee</d2p1:internalValue> 
    </_id> 
    <_key xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">false</_key> 
    <_keyIdentifier xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">SurrogateKey</_keyIdentifier> 
    <ChecklistComplete>false</ChecklistComplete> 
    <Date>2013-03-05T15:43:49.5008406+02:00</Date> 
    <GpsAccuracy>1</GpsAccuracy> 
    <GpsLatitude>1</GpsLatitude> 
    <GpsLongitude>1</GpsLongitude> 
    <OrderComplete>false</OrderComplete> 
    <PhotoComplete>false</PhotoComplete> 
    <StockComplete>false</StockComplete> 
    <Sync>2013-03-05T15:43:49.5468406+02:00</Sync> 
    <checkListAnswers xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_list> 
     <d2p1:IdentityDataReferenceOfCheckListAnswerDataContractExX8I0_S_SPU> 
     <d2p1:_dataContract z:Id="i2"> 
      <d2p1:_isDirty>true</d2p1:_isDirty> 
      <d2p1:_id xmlns:d6p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
      <d6p1:internalValue>95ae919b-a389-4ea7-a009-af1b91890c36</d6p1:internalValue> 
      </d2p1:_id> 
      <d2p1:_key>false</d2p1:_key> 
      <d2p1:_keyIdentifier>SurrogateKey</d2p1:_keyIdentifier> 
      <Answer>false</Answer> 
      <checkListQuestion> 
      <d2p1:_dataContract i:nil="true" /> 
      <d2p1:_description i:nil="true" /> 
      <d2p1:_hasDataContract>false</d2p1:_hasDataContract> 
      <d2p1:_id xmlns:d7p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
       <d7p1:internalValue>176cbb31-7df2-4966-baa9-4e3cd2a0c6d5</d7p1:internalValue> 
      </d2p1:_id> 
      </checkListQuestion> 
     </d2p1:_dataContract> 
     <d2p1:_description i:nil="true" /> 
     <d2p1:_hasDataContract>true</d2p1:_hasDataContract> 
     <d2p1:_id xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
      <d5p1:internalValue>95ae919b-a389-4ea7-a009-af1b91890c36</d5p1:internalValue> 
     </d2p1:_id> 
     </d2p1:IdentityDataReferenceOfCheckListAnswerDataContractExX8I0_S_SPU> 
    </d2p1:_list> 
    </checkListAnswers> 
    <comments xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_list /> 
    </comments> 
    <directSalesAgent xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_dataContract i:nil="true" /> 
    <d2p1:_description i:nil="true" /> 
    <d2p1:_hasDataContract>false</d2p1:_hasDataContract> 
    <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
     <d3p1:internalValue>6f99f86a-5b1b-4f73-bdc3-388e0b7cf417</d3p1:internalValue> 
    </d2p1:_id> 
    </directSalesAgent> 
    <directSalesAgentSuperVisor xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_dataContract i:nil="true" /> 
    <d2p1:_description i:nil="true" /> 
    <d2p1:_hasDataContract>false</d2p1:_hasDataContract> 
    <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
     <d3p1:internalValue>d57db20d-9b3a-4345-849e-d5a0d0d88f70</d3p1:internalValue> 
    </d2p1:_id> 
    </directSalesAgentSuperVisor> 
    <photos xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_list> 
     <d2p1:IdentityDataReferenceOfPhotoDataContractExX8I0_S_SPU> 
     <d2p1:_dataContract z:Id="i3"> 
      <d2p1:_isDirty>true</d2p1:_isDirty> 
      <d2p1:_id xmlns:d6p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
      <d6p1:internalValue>3db431e9-3338-4c96-aea9-d833eb0dc8ae</d6p1:internalValue> 
      </d2p1:_id> 
      <d2p1:_key>false</d2p1:_key> 
      <d2p1:_keyIdentifier>SurrogateKey</d2p1:_keyIdentifier> 
      <Content i:nil="true" /> 
      <Taken>2013-03-05T15:43:49.4748406+02:00</Taken> 
     </d2p1:_dataContract> 
     <d2p1:_description i:nil="true" /> 
     <d2p1:_hasDataContract>true</d2p1:_hasDataContract> 
     <d2p1:_id xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
      <d5p1:internalValue>3db431e9-3338-4c96-aea9-d833eb0dc8ae</d5p1:internalValue> 
     </d2p1:_id> 
     </d2p1:IdentityDataReferenceOfPhotoDataContractExX8I0_S_SPU> 
    </d2p1:_list> 
    </photos> 
    <salesPoint xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_dataContract i:nil="true" /> 
    <d2p1:_description i:nil="true" /> 
    <d2p1:_hasDataContract>false</d2p1:_hasDataContract> 
    <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
     <d3p1:internalValue>692a294a-2d1b-4026-9693-0c0ce552a2fb</d3p1:internalValue> 
    </d2p1:_id> 
    </salesPoint> 
    <stockCounts xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts" i:nil="true" /> 
</VisitDataContractEx> 

Mono Output:

<VisitDataContractEx xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts"> 
    <_isDirty xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">true</_isDirty> 
    <_id xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.Domain" xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:internalValue>9297eea9-82af-4981-ab9d-40aa0ac0fa0d</d2p1:internalValue> 
    </_id> 
    <_key xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">false</_key> 
    <_keyIdentifier xmlns="http://schemas.datacontract.org/2004/07/Organization.DataContracts">SurrogateKey</_keyIdentifier> 
    <ChecklistComplete>false</ChecklistComplete> 
    <Date>2013-03-05T17:49:06.362243+02:00</Date> 
    <GpsAccuracy>1</GpsAccuracy> 
    <GpsLatitude>1</GpsLatitude> 
    <GpsLongitude>1</GpsLongitude> 
    <OrderComplete>false</OrderComplete> 
    <PhotoComplete>false</PhotoComplete> 
    <StockComplete>false</StockComplete> 
    <Sync>2013-03-05T17:49:06.438934+02:00</Sync> 
    <checkListAnswers xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_list> 
     <d2p1:IdentityDataReferenceOfCheckListAnswerDataContractEx> 
     <d2p1:_dataContract xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" z:Id="i2"> 
      <d2p1:_isDirty>true</d2p1:_isDirty> 
      <d2p1:_id xmlns:d6p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
      <d6p1:internalValue>75083457-9714-4971-b60c-f28fa43167ad</d6p1:internalValue> 
      </d2p1:_id> 
      <d2p1:_key>false</d2p1:_key> 
      <d2p1:_keyIdentifier>SurrogateKey</d2p1:_keyIdentifier> 
      <Answer>false</Answer> 
      <checkListQuestion xmlns:d6p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
      <d6p1:_dataContract xmlns:d7p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" i:nil="true" /> 
      <d6p1:_description i:nil="true" /> 
      <d6p1:_hasDataContract>false</d6p1:_hasDataContract> 
      <d6p1:_id xmlns:d7p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
       <d7p1:internalValue>176cbb31-7df2-4966-baa9-4e3cd2a0c6d5</d7p1:internalValue> 
      </d6p1:_id> 
      </checkListQuestion> 
     </d2p1:_dataContract> 
     <d2p1:_description i:nil="true" /> 
     <d2p1:_hasDataContract>true</d2p1:_hasDataContract> 
     <d2p1:_id xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
      <d5p1:internalValue>75083457-9714-4971-b60c-f28fa43167ad</d5p1:internalValue> 
     </d2p1:_id> 
     </d2p1:IdentityDataReferenceOfCheckListAnswerDataContractEx> 
    </d2p1:_list> 
    </checkListAnswers> 
    <comments xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_list /> 
    </comments> 
    <directSalesAgent xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_dataContract xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" i:nil="true" /> 
    <d2p1:_description i:nil="true" /> 
    <d2p1:_hasDataContract>false</d2p1:_hasDataContract> 
    <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
     <d3p1:internalValue>6f99f86a-5b1b-4f73-bdc3-388e0b7cf417</d3p1:internalValue> 
    </d2p1:_id> 
    </directSalesAgent> 
    <directSalesAgentSuperVisor xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_dataContract xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" i:nil="true" /> 
    <d2p1:_description i:nil="true" /> 
    <d2p1:_hasDataContract>false</d2p1:_hasDataContract> 
    <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
     <d3p1:internalValue>d57db20d-9b3a-4345-849e-d5a0d0d88f70</d3p1:internalValue> 
    </d2p1:_id> 
    </directSalesAgentSuperVisor> 
    <photos xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_list> 
     <d2p1:IdentityDataReferenceOfPhotoDataContractEx> 
     <d2p1:_dataContract xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" z:Id="i3"> 
      <d2p1:_isDirty>true</d2p1:_isDirty> 
      <d2p1:_id xmlns:d6p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
      <d6p1:internalValue>507f45d1-ce3a-4ec2-a343-d0b83cfb7bc8</d6p1:internalValue> 
      </d2p1:_id> 
      <d2p1:_key>false</d2p1:_key> 
      <d2p1:_keyIdentifier>SurrogateKey</d2p1:_keyIdentifier> 
      <Content i:nil="true" /> 
      <Taken>2013-03-05T17:49:06.294006+02:00</Taken> 
     </d2p1:_dataContract> 
     <d2p1:_description i:nil="true" /> 
     <d2p1:_hasDataContract>true</d2p1:_hasDataContract> 
     <d2p1:_id xmlns:d5p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
      <d5p1:internalValue>507f45d1-ce3a-4ec2-a343-d0b83cfb7bc8</d5p1:internalValue> 
     </d2p1:_id> 
     </d2p1:IdentityDataReferenceOfPhotoDataContractEx> 
    </d2p1:_list> 
    </photos> 
    <salesPoint xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts"> 
    <d2p1:_dataContract xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Project.DataContracts" i:nil="true" /> 
    <d2p1:_description i:nil="true" /> 
    <d2p1:_hasDataContract>false</d2p1:_hasDataContract> 
    <d2p1:_id xmlns:d3p1="http://schemas.datacontract.org/2004/07/Organization.Domain"> 
     <d3p1:internalValue>692a294a-2d1b-4026-9693-0c0ce552a2fb</d3p1:internalValue> 
    </d2p1:_id> 
    </salesPoint> 
    <stockCounts xmlns:d2p1="http://schemas.datacontract.org/2004/07/Organization.DataContracts" i:nil="true" /> 
</VisitDataContractEx> 

Việc điều chỉnh XML sử dụng Fiddler và đệ trình thử nghiệm, tôi đã thu hẹp xuống vấn đề với tên nguyên tố dưới _list yếu tố:

NET:

<d2p1:_list> 
     <d2p1:IdentityDataReferenceOfCheckListAnswerDataContractExX8I0_S_SPU> 

Mono:

<d2p1:_list> 
     <d2p1:IdentityDataReferenceOfCheckListAnswerDataContractEx> 

Đây là mã của tôi mà serializes dữ liệu:

public string Serialize<TDataContract>(object obj) 
{ 
    var builder = new StringBuilder(); 
    var serializer = new DataContractSerializer(typeof(TDataContract)); 
    var xmlWriter = XmlWriter.Create(builder); 
    serializer.WriteObject(xmlWriter, obj); 
    xmlWriter.Close(); 

    return builder.ToString().Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", string.Empty); 
} 

Đây có phải là một lỗi mà phải được giải quyết bằng các Đội Mono hoặc ai đó có thể đề xuất giải pháp khả thi?

Edit:

Tôi đã thu hẹp vấn đề này xuống thấp hơn nữa và nó không phải về danh sách, đó là khoảng cách mỗi thi chọn tên phần tử XML.

IdentityDataReference có loại chung và trong trường hợp này là loại CheckListAnswerDataContractEx.

IdentityDataReference cũng xảy ra trong một DLL được phân phối (mà tôi có mã nguồn), vì vậy sự nghi ngờ của tôi là DataContractSerializer đang sử dụng sự phản chiếu để tự động đặt tên, và có lẽ vì nó là một DLL phân tán riêng biệt, .NET được thêm X8I0_S_SPU vào cuối, tuy nhiên, Mono thì không.

Tôi cũng đã phát hiện ra rằng tôi có thể thêm một tên tham số cho DataContractAttribute như sau: [DataContract(Name = "IdentityDataReference")] sẽ ghi đè tên được tạo thành chỉ IdentityDataReference, thậm chí không thử thêm Loại khi được chỉ định.

Thật không may là một thử nghiệm nhanh cho thấy Mono đang bị ngoại lệ thời gian chạy khi tôi chỉ định tên và nó cố gắng deserialize dữ liệu.

Bây giờ tôi đã hiểu vấn đề này tốt hơn, tôi đang cố gắng tạo một dự án riêng biệt sao chép vấn đề.

Edit - Đánh dấu như giải quyết:

tôi chuyển về từ dự án này từ nhiều năm trước bây giờ, nhưng đã quyết định đóng cửa này là trả lời bằng cách Katulus kể từ khi tôi sẽ cảm thấy như vậy ngày nay gặp phải cùng một vấn đề. Đó là hy vọng của chúng tôi tại thời điểm chúng tôi có thể nhận được "miễn phí" không đau nền tảng hội nhập không có thêm công việc cho một dịch vụ WCF hiện có, mà hóa ra là ngây thơ.

Hôm nay nếu trình bày cùng một yêu cầu, thay vào đó, tôi sẽ chọn giao thức giao tiếp thân thiện với nền tảng chéo hơn. Nếu tôi không thể thay thế cơ sở hạ tầng WCF hiện có, thì tôi sẽ tạo ra một số loại facade và/hoặc adapter (có thể trong một giải pháp khác) để hiển thị dịch vụ trên WebAPI bằng cách sử dụng JSON serialization, nói chuyện với dịch vụ WCF gốc trong lý lịch.

+5

Nếu bạn phát hiện ra đây là lỗi, bạn có thể báo cáo lỗi đó cho Xamarin tại https://bugzilla.xamarin.com/. – Dandy

+3

Chúng tôi đã thấy cùng một vấn đề. Xamarin không thêm một băm vào tên hợp đồng dữ liệu cho các kiểu generic, như .NET. Cách giải quyết của chúng tôi là sử dụng một DataContractResolver, vì chúng tôi hỗ trợ nhiều nền tảng và không thể sửa đổi tên, ví dụ. '[DataContract (Name =" IdentityDataReferenceOf {0} ")]' trong chúng do khả năng xảy ra xung đột tên. –

+0

Tại sao bạn sẽ biên dịch một ứng dụng dịch vụ bằng mono? Tôi đoán bạn đã làm điều đó. – danish

Trả lời

3

Nếu bạn đang giao tiếp giữa các nền tảng khác nhau (mặc dù .NET và Mono cố gắng để được như vậy), bạn nên tránh sử dụng DataContractSerializer. Có những vấn đề khác có thể xảy ra hơn là lỗi này. Ví dụ, nếu bạn thay đổi các lớp trên máy chủ, tất cả các máy khách có thể ngừng hoạt động và ngược lại. Trong trường hợp máy chủ-máy khách, nơi bạn không có toàn quyền kiểm soát cả hai mặt, đây có thể là một vấn đề lớn.

Tôi sẽ thay đổi DataContractSerializer thành XmlSerializer mà bạn có thể kiểm soát tốt hơn trên cả hai mặt. Hoặc thậm chí thực hiện serialization riêng đến và từ XML, nơi bạn có thể tài khoản với các nâng cấp trong tương lai. Nếu bạn thêm một số thuộc tính mới trên một máy chủ, bạn có thể cập nhật trình giải mã của bạn theo cách nó có thể xử lý nếu thuộc tính mới bị thiếu trong một số ứng dụng khách cũ.

+0

Vì vậy, chúng tôi luôn thực hiện tái tạo các đối tượng chuyển dữ liệu (DTO) một cách tự động trong quá trình xây dựng hàng đêm. Dịch vụ này xuất các hợp đồng mà khách hàng sử dụng để tái tạo các proxy của nó và cả dịch vụ lẫn khách hàng tạo ra các DTO từ cùng một XSD. Những gì chúng tôi gọi là Hợp đồng phát triển đầu tiên. – riezebosch

0

Có thể giải pháp thay thế là sử dụng ứng dụng svcutil để tạo proxy và sau đó sử dụng cùng một proxy như cũ. http://tutorials.csharp-online.net/WCF_Essentials%E2%80%94Generating_the_Proxy

Nói chung tôi nghĩ bạn nên bắt đầu sử dụng không gian tên của datacontract, vì nó đã giúp tôi nhiều lần xác định các vấn đề phiên bản tham chiếu nó rất tốt đẹp để có phiên bản mã đang chạy với proxy. Nhưng đó là một công việc khác :)

Có lẽ khi thực hiện tham chiếu, nếu bạn có thể thêm tham chiếu đến thư viện công đang giữ giao diện của mình, bạn có thể sử dụng các loại tái sử dụng của cài đặt tham chiếu dịch vụ từ hội đồng được tham chiếu. tạo các loại riêng cho cùng một phạm vi mở rộng.

Cuối cùng có, hiển thị tất cả các tệp có thể nhìn thấy Reference.svcmap trong tham chiếu dịch vụ, xml này chứa phần tử 'CollectionMappings', thường cần phải xác định danh sách của tôi để xử lý trong trường hợp này. :
http://social.msdn.microsoft.com/Forums/vstudio/en-US/09eefbbc-bf63-4aa3-a0cb-01a9dbd7f496/problem-sharing-custom-collection-types-between-service-and-client

Đó là năm tôi cent gợi ý gỡ lỗi,
Cheers