2009-02-03 60 views
6

我有一個標誌屬性枚舉的背後是一個Web服務,如下所示:標誌與Web服務

[Serializable,Flags] 
public enum AccessLevels 
{ 
    None = 0, 
    Read = 1, 
    Write = 2, 
    Full = Read | Write 
} 

我的問題是我的web服務的消費者不具備枚舉的原始常數值。得到的代理類客戶端有一些達此:

{ 
    None = 1, 
    Read = 2, 
    Write = 4, 
    Full = 8 
} 

因此當消費者正在檢查「讀」訪問,這將是錯誤的,即使「testItem」是「全」

((testItem & Svc.Read) == Svc.Read) 

如何正確提供Web服務的標誌?

編輯:

根據this文章它可能無法做什麼,我希望做。伊萬Krivyakov指出枚舉

原來的

不完善的透明度枚舉不如 透明的,因爲我們想的那樣。 有三個粘的問題:

  1. 如果服務器端代碼聲明枚舉和具體數字 值分配給其成員,這些值 不會給客戶端可見。
  2. 如果服務器端代碼聲明具有「複合」掩碼 值(如White = Red | Green | Blue)的[Flags]枚舉,則 將不會在客戶端 上正確反映。
  3. 如果服務器或客戶端傳輸的值超出了枚舉範圍 之外的「非法」值,則會導致另一端的XML解串器發生異常。

所以我想知道這是否只是一個限制,是不可能的。

回答

3

我已經做了大量的研究,發現它不可能通過Web服務序列化枚舉常量。請注意,要實現您的目標,您不需要枚舉None或Full。這兩個枚舉可以隱含在讀/寫組合中:

如果您的AccessLevels = Read |寫 ,沒有如果你的AccessLevels = 0沒什麼]

你枚舉應該是這樣的:

[Serializable,Flags] 
public enum AccessLevels 
{ 
    Read = 1, 
    Write = 2 
} 
0

我有一個類似的問題,並通過添加另一個Web服務來返回currect標誌值。

那些成爲我在比較中使用的值。

可能不是最乾淨的解決方案,但它的工作原理。

編輯:

我原來的答覆建議值跨過去了作爲一個單獨的Web服務,而不是一個枚舉內。

但是,四處漫遊時,看起來遍及Web服務映射到1,2,4的枚舉0,1,2(即使設置了[Flags]屬性)也是一個常見問題。

許多人提出的解決方案是修改原始枚舉定義,並從1開始而不是從0開始。

+0

你能否解釋一下? – Brawndo 2009-02-03 08:11:42

0

標誌應該是兩個倍數,在你的情況下你的標誌是(0,1,2,3)。 嘗試改變你的struct的定義:

[Serializable,Flags] 
public enum AccessLevels{  
None = 1,  
Read = 2,  
Write = 4,  
Full = Read | Write} 

,看看它是否效果更好。

(我希望我不是做出醜,其後期和IM在我的方式向牀..)

+0

這仍然不起作用。我以前見過這個問題。隨着編號,你提到你的消費者仍然會看到以下內容: 公共枚舉AccessLevels { 無= 1, 讀= 2, 寫= 4, 全部= 8, } – Rorzilla 2009-02-03 00:55:21

+0

@Rorzilla是的,這的確是案件仍然。 @Stefan我可以通過刪除「Full」和「None」來「修復」它,然後代理類將變爲Read = 1和Write = 2,但我仍然希望爲用戶提供none選項,因此它們不會必須「知道」的東西,而不必使用值0 – Brawndo 2009-02-03 08:25:42

0

一種選擇是提供一個更詳細的類,而不是如枚舉

[Serializable] 
public class AccessPermission{ 
public boolean None{get;set;} 
public boolean Read{get;set;} 
public boolean Write{get;set;} 
public boolean Full{get;set;} 

public AccessPermission(AccessLevels level){ 
    None = false; 
    Read = false; 
    Write = false; 
    Full = false; 

    switch(level){ 
    case AccessLevels.None: 
    break; 
    case AccessLevels.Read: 
    Read = true; 
    break; 
    case AccessLevels.Write: 
    Write = true; 
    break; 
    case AccessLevels.Full: 
    Read = true; 
    Write = true; 
    Full = true; 
    break; 
    } 
} 
} 

另一種選擇,我可以看到的是提供在他們使用成功地進行互操作要發送的整數什麼都語言的方法。該標誌運營商意味着C#不找位掩碼如果個別標誌標

 
0001 -> None 
0010 -> Read 
0100 -> Write 
0110 -> Full 

所以要檢查,如果該位被設置


public static boolean CanRead(int accessLevel){ 
return (accessLevel | 2) > 0 // return true if read bit set, using bitwise or 
} 

public static boolean CanWrite(int accessLevel){ 
return (accessLevel | 4) > 0 // return true of write bit set. 
} 

請注意,這第二個解決方案,您應該看到的任何許可更脆弱,如果你改變accessLevels的定義,你的客戶端會默默地錯過行爲。