2010-01-22 33 views
20

Tôi đang cố gắng sử dụng dịch vụ web RESTful bằng WCF. Tôi không có quyền kiểm soát định dạng của dịch vụ web, vì vậy tôi phải thực hiện một vài cách giải quyết ở đây và ở đó. Tuy nhiên, một vấn đề lớn mà tôi dường như không thể xoay xở là làm thế nào để làm cho WCF deserialize một enum như một chuỗi.wcf deserialize enum dưới dạng chuỗi

Đây là mã của tôi (tên đã thay đổi, rõ ràng):

[DataContract] 
public enum Foo 
{ 
    [EnumMember(Value = "bar")] 
    Bar, 

    [EnumMember(Value = "baz")] 
    Baz 
} 

[DataContract] 
public class UNameIt 
{ 
    [DataMember(Name = "id")] 
    public long Id { get; private set; } 

    [DataMember(Name = "name")] 
    public string Name { get; private set; } 

    [DataMember(Name = "foo")] 
    public Foo Foo { get; private set; } 
} 

Và đây là dữ liệu trả về mà không deserialization:

{ 
    "id":123456, 
    "name":"John Doe", 
    "foo":"bar" 
} 

Cuối cùng, ném ngoại lệ:

Đã xảy ra lỗi khi deserializing đối tượng của loại Service.Foo. Không thể phân tích cú pháp giá trị 'thanh' thành loại 'Int64'.

Tôi không muốn chuyển sang sử dụng XmlSerializer, bởi vì, trong số nhiều thiếu sót khác, nó sẽ không cho phép tôi cài đặt riêng tư trên các thuộc tính.

Làm cách nào để tạo WCF (hoặc, tốt, DataContractSerializer) xử lý enum của tôi dưới dạng giá trị chuỗi?

EDIT: Làm điều này có vẻ là không thể, và hành vi là cách nó được thiết kế. Cảm ơn bạn Microsoft, vì không cho chúng tôi lựa chọn, phải nghỉ mát để hack. Làm theo cách mà somori gợi ý có vẻ là cách duy nhất để có được chuỗi enums với JSON và WCF.

+0

Bạn đã thử xây dựng một đối tượng UNameIt trong mã và sử dụng DataContractSerializer để tuần tự hóa (và sau đó deserialize nó) để xem nếu có thể serialization không phù hợp với thông điệp bạn nhận được? – GaussZ

+0

Vấn đề là, tôi không phải là người thực hiện tuần tự hóa. JSON này xuất phát từ một bên thứ ba. Tôi không thể kiểm soát bất cứ điều gì về nó, điều duy nhất tôi có quyền kiểm soát là deserialization, ngoại trừ tôi đoán không, bởi vì tôi không thể có được WCF deserialize một enum cách những kẻ thiết lập enums. Tôi muốn DataContractSerializer linh hoạt hơn. – Alex

+0

Có, tôi hiểu rằng bạn không có quyền kiểm soát nó, nó có thể gợi ý vấn đề mặc dù nếu bạn có thể so sánh một đối tượng tự tuần tự với những gì bạn nhận được từ bên thứ ba để hiểu tại sao serializer không thích nó. – GaussZ

Trả lời

7

Đây có thể là một câu hỏi ngớ ngẩn.

gì xảy ra nếu bạn làm

[DataMember(Name = "foo")] 
private string foo { get; private set; } 

public Foo Foo 
{ 
    get 
    { 
    return Foo.Parse(foo); 
    } 
} 

?

+3

Tôi đã thử điều đó rồi, và nó hoạt động, nhưng nó là một hack, và nếu nó có thể tránh được, tôi muốn tránh nó. – Alex

+1

Thực ra, đây có vẻ là cách duy nhất để làm điều đó, xem http://stackoverflow.com/questions/794838/datacontractjsonserializer-and-enums/794962#794962 – Alex

+0

Bạn cũng sẽ cần một người đặt cược, phải không? –

0

Er ..? Không phải là enums số nguyên? Ngoại lệ là hợp lệ. Tôi không biết nếu điều này giúp: http://msdn.microsoft.com/en-us/library/aa347875.aspx

+0

Không, không phải. Bạn đã tự mình đọc bài viết đó chưa? Dưới đây là một đoạn trích thú vị: Nói chung, hợp đồng dữ liệu bao gồm tên thành viên liệt kê, không phải là giá trị số. Tuy nhiên, khi sử dụng mô hình hợp đồng dữ liệu, nếu bên nhận là một khách hàng WCF, lược đồ đã xuất sẽ giữ nguyên các giá trị số. Vấn đề là, tôi là khách hàng WCF. Tuy nhiên, máy chủ sử dụng chuỗi enums. Tôi hơi bối rối ... – Alex

+0

Mã máy chủ có thể bị lỗi không? Có thể sử dụng cấu trúc dữ liệu trong trường hợp này không? –

+0

Máy chủ không phải là dịch vụ WCF, tôi nghĩ rằng nó chạy Python. Tôi không thể thay đổi cách họ làm mọi thứ, tôi chỉ là một người tiêu dùng trong kịch bản này, và tôi phải đi theo quy tắc của họ. – Alex

1

Tôi biết đây là một bài đăng cũ, nhưng tôi nghĩ điều đó đáng nói đến.

Tôi đã nhận được lỗi tương tự trong đó quá trình deserialization của chuỗi json không thành công, dường như deserialize cho các loại sai.

Việc sửa chữa cho tôi là chỉ cần URL mã hóa chuỗi json trước khi gửi nó đến máy chủ. Một sai lầm đơn giản nhưng dễ thực hiện.

HttpUtility.UrlEncode(JSONInstruction) /*remember to encode the string*/ 
0

Điều này có thể xảy ra do thiết lập riêng tư và lỗi được báo cáo là gây hiểu nhầm. Foo là tài sản đầu tiên được deserialized và vì không có setter công cộng có sẵn nó ném một ngoại lệ.

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