2014-02-26 35 views
2

我正在創建一個ASP MVC Web API。我現在想要根據正在執行請求的用戶確定要對對象進行序列化的屬性。 ApiController知道用戶。並基於用戶,我有一個函數返回一個字符串數組與用戶有權在模型上的屬性名稱。確定要在Json.Net中基於用戶序列化的屬性

如何將用戶傳遞給ContractResolver,以便它隻影響當前的請求,而不會影響其他用戶的同時請求?

回答

5

您可以在這個例子中創建一個自定義ContractResolver

var json = JsonConvert.SerializeObject(
       new UserClass() {ID=666, Name="john", SurName="doe"}, 
       new JsonSerializerSettings() { ContractResolver = new CustomContractResolver(new[]{"ID", "SurName"}) } 
      ); 

,輸出JSON將只包括IDSurName(不Name

public class UserClass 
{ 
    public int ID { set; get; } 
    public string Name {set; get;} 
    public string SurName { set; get; } 
} 

public class CustomContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver 
{ 
    IEnumerable<string> _allowedProps = null; 

    public CustomContractResolver(IEnumerable<string> allowedProps) 
    { 
     _allowedProps = allowedProps; 
    } 

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
    { 
     return _allowedProps.Select(p=>new JsonProperty() { 
      PropertyName = p, 
      PropertyType = type.GetProperty(p).PropertyType, 
      Readable = true, 
      Writable = true, 
      ValueProvider = base.CreateMemberValueProvider(type.GetMember(p).First()) 
     }).ToList(); 
    } 
} 
+2

此解析器代碼看起來不錯,但OP正在使用Web API。藉助Web API,您可以在應用程序啓動時配置解析器,然後稍後發出請求(Web API框架使用解析器處理幕後序列化)。據我瞭解的問題,允許的屬性列表可以根據用戶的每個請求更改,所以我認爲他正在試圖弄清楚他如何能夠獲得這個列表到解析器爲每個不同的請求。 –

+1

@BrianRogers你可能是對的,在這種情況下,可以使用線程靜態變量。 '[ThreadStatic]靜態IEnumerable allowedProps;' –

+0

@ L.B這正是我所追求的,我要試試這個瞬間:)。 –

1

你不能爲你的api收到的每一個請求創建一個新的合約解析器嗎?
只要您爲每個請求創建一個新實例,合約解析器就永遠不會相互衝突。
代碼看起來是這樣的:

var resolver = new MyUserBasedResolver(userObject); 
JsonConvert.SerializeObject(
     product, 
     Formatting.Indented, 
     new JsonSerializerSettings { ContractResolver = resolver } 
     ); 
+1

好的,但你如何在Web API框架中做到這一點?我認爲這是真正的問題。 –

相關問題