2009-02-18 23 views
6

Tôi muốn biết cách định cấu hình các loại đã biết trong WCF. Ví dụ: tôi có một lớp học Người và một lớp học Nhân viên. Lớp học Nhân viên là một lớp con của lớp học Người. Cả hai lớp được đánh dấu bằng thuộc tính [DataContract].WCF: Định cấu hình các loại đã biết

Tôi không muốn mã hóa kiểu đã biết của một lớp, như đặt [ServiceKnownType(typeof(Employee))] ở lớp Person để WCF biết rằng Employee là một lớp con của Person.

Bây giờ, tôi thêm vào App.config cấu hình XML sau của máy chủ:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.runtime.serialization> 
    <dataContractSerializer> 
     <declaredTypes> 
     <add type="Person, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"> 
      <knownType type="Employee, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null" /> 
     </add> 
     </declaredTypes> 
    </dataContractSerializer> 
    </system.runtime.serialization> 
    <system.serviceModel> 
    ....... 
    </system.serviceModel> 
</configuration> 

tôi biên soạn nó, chạy máy chủ, bổ sung thêm một tài liệu tham khảo dịch vụ tại các khách hàng và thêm vào một số mã và chạy client. Nhưng một lỗi xảy ra:

Các định dạng ném một ngoại lệ khi cố gắng để deserialize thông điệp: Có lỗi trong khi cố gắng tham số deserialize http://www.herbertsabanal.net:person. Thông điệp InnerException là 'Lỗi trong dòng 1 vị trí 247. Yếu tố 'http://www.herbertsabanal.net:person' chứa dữ liệu của hợp đồng dữ liệu 'http://www.herbertsabanal.net/Data:Employee' . Trình gỡ bỏ không có số kiến ​​thức về bất kỳ loại nào ánh xạ tới hợp đồng này. Thêm kiểu tương ứng với 'nhân viên' cho danh sách các loại được biết đến - ví dụ, bằng cách sử dụng thuộc tính KnownTypeAttribute hoặc bằng cách thêm nó vào danh sách các tiếng loại truyền cho DataContractSerializer '.. Vui lòng xem InnerException để biết thêm chi tiết.

Dưới đây là những hợp đồng dữ liệu:

[DataContract(Namespace="http://www.herbertsabanal.net/Data", Name="Person")] 
    class Person 
    { 
     string _name; 
     int _age; 

     [DataMember(Name="Name", Order=0)] 
     public string Name 
     { 
      get { return _name; } 
      set { _name = value; } 
     } 

     [DataMember(Name="Age", Order=1)] 
     public int Age 
     { 
      get { return _age; } 
      set { _age = value; } 
     } 
    } 


[DataContract(Namespace="http://www.herbertsabanal.net/Data", Name="Employee")] 
    class Employee : Person 
    { 
     string _id; 

     [DataMember] 
     public string ID 
     { 
      get { return _id; } 
      set { _id = value; } 
     } 
    } 

Btw, tôi không sử dụng thư viện lớp (thư viện lớp WCF hoặc thư viện lớp phi WCF) cho dịch vụ của tôi. Tôi chỉ đơn giản là mã hóa nó trong dự án máy chủ.

Tôi đoán rằng phải có sự cố tại tệp cấu hình (vui lòng xem tệp cấu hình ở trên). Hoặc tôi phải thiếu một cái gì đó. Bất kỳ trợ giúp sẽ được khá nhiều đánh giá cao.

+0

tôi nghi ngờ rằng cấu hình chỉ hoạt động nếu sử dụng thư viện của bên thứ ba, tham chiếu đến dịch vụ. Tôi sẽ thử nó và tôi sẽ lấy lại cho câu hỏi này nếu tôi tìm thấy một số câu trả lời. – jerbersoft

Trả lời

8

Tôi đoán tôi đã tìm thấy câu trả lời ngay bây giờ.

Các tập tin cấu hình tôi đăng trên trông như thế này:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.runtime.serialization> 
    <dataContractSerializer> 
     <declaredTypes> 
     <add type="Person, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"> 
      <knownType type="Employee, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null" /> 
     </add> 
     </declaredTypes> 
    </dataContractSerializer> 
    </system.runtime.serialization> 
    <system.serviceModel> 
    ....... 
    </system.serviceModel> 
</configuration> 

Những gì tôi vừa mới thêm là, các Namespace của lớp Person và nhân viên lớp. Và không cần phiên bản và giá trị văn hóa dài hơn .... Cấu hình chính xác phải là:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.runtime.serialization> 
    <dataContractSerializer> 
     <declaredTypes> 
     <add type="WCFWithNoLibrary.Person, WCFWithNoLibrary"> 
      <knownType type="WCFWithNoLibrary.Employee, WCFWithNoLibrary" /> 
     </add> 
     </declaredTypes> 
    </dataContractSerializer> 
    </system.runtime.serialization> 
    <system.serviceModel> 
    ....... 
    </system.serviceModel> 
</configuration> 

Bây giờ ngắn hơn và có ý nghĩa hơn. Nhưng nếu thư viện của bên thứ ba được sử dụng, thì cần thêm phiên bản, văn hóa, publickeytokens.

+2

Upvote. Bạn có phải làm bất cứ điều gì ở phía Client .config? – granadaCoder

+1

Bạn sẽ cần sao chép cấu hình trên máy khách để có thể nhận được kiểu mới. –

5

Tôi biết điều này đã được trả lời trong một thời gian dài trước đây, nhưng, khác (có thể rõ ràng cho các lập trình viên tương lai nhiều hơn) giải pháp:

[KnownType(typeof(SubClass))] 
public class BaseClass 

Scott

+4

điều này không phải lúc nào cũng có thể nếu loại phụ nằm trong một dự án khác –

0

tôi đã thông báo lỗi dài này cũng có trong một trường hợp khác. Tôi đã sử dụng KnownTypeAttribute và đã triển khai thành công ứng dụng sử dụng WCF.RIA để sản xuất. Trong bản phát hành thứ hai, tôi đã thêm một loại phụ mới và thêm KnownTypeAttribute tương ứng cần thiết (trình biên dịch không chấp nhận nó mà không có thuộc tính này - tuyệt vời). Những gì trình biên dịch đã chấp nhận và những gì chạy trên máy tính của tôi, không chạy trong sản xuất, tuy nhiên. Chỉ trong sản xuất tôi đã nhận được lỗi được đề cập ở trên. So sánh tất cả các sử dụng của các kiểu con hiện có và cái mới tiết lộ tôi đã quên rằng WCF.RIA yêu cầu tên của kiểu con được sử dụng trong tên của một phương thức, như GetMySubTypes. Vì vậy, nếu bạn nhận được lỗi này sau khi đã thêm các thuộc tính, hãy xem liệu đó có phải là do các quy ước của WCF.RIA hay không.

Các vấn đề liên quan