2016-04-01 20 views
1

在ASP.NET Web API項目中,我想要加密所有響應中的所有實體ID並解密所有請求中的加密值。ASP.NET Web API中的簡單屬性上的自定義類型轉換器

(注:我知道如何加密/解密數據,這不是我的問題)

我認爲這將是很好,如果我只是裝點,我需要進行加密/解密的屬性回覆/請求,具有自定義屬性。

這是我喜歡它的工作:

public class Person 
{ 
    [EncryptDecrypt] 
    public int PersonID {get; set;} 

    public string Name {get; set;} 

    public IEnumerable<Order> Orders {get; set;} 
} 

public class Order 
{ 
    [EncryptDecrypt] 
    public long OrderID {get; set;} 

    public string Title {get; set;} 

    public float Price {get; set;} 
} 
在Web API方法

然後:

// GET: api/persons/xhj$j78dPs (xhj$j78dPs is an encrypted PersonID)  

public Person Get([EncryptDecrypt]int personId) 
{ 
    // Now, I expect personId to be a normal ID, like: 187356 

    Person person = _repository.GetPerson(personId); 

    return person; 
} 

針對上述網絡API的願望的迴應是:

{ 
    "personId": "xhj$j78dPs", 
    "name": "Joe Williams", 
    "orders": [ 
     { 
     "orderId": "a#jd75mlzed0ihd", 
     "title": "Buying a new item", 
     "price": 19.99 
     } 
    ] 
} 

這又是一個例子,這次是用於PUT動詞的Web API:

/* PUT Request body: */ 
{ 
    "orderId": "a#jd75mlzed0ihd", 
    "title": "Buying a new item - edited", 
    "price": 13.00 
} 

相關的Web API方法:

// PUT: api/persons/xhj$j78dPs/orders/ (xhj$j78dPs is an encrypted PersonID) 

public void Put([EncryptDecrypt]int personId, Order editedOrder) 
{ 
    // I expect personId to be a normal ID, like: 187356 

    // I expect editedOrder.OrderID to be a normal ID, like: 10000089765 

    _repository.UpdateOrder(personId, editedOrder); 
} 

我怎樣才能開發[EncryptDecrypt]屬性?

[EncryptDecrypt]實際上應該是JsonConverter attribute?或者我應該開發一個自定義的Media Formatter或模型聯編程序或值提供程序或參數聯編程序?我很困惑。

+0

會是這樣的工作? http://www.codemag.com/article/0307041 – Namrehs

+2

請參閱[如何在序列化我的對象時加密選定的屬性?](http://stackoverflow.com/q/29196809/10263)瞭解如何處理它的序列化結束。你必須定製它,因爲你希望它能處理數字屬性而不是字符串。對於Web API參數處理,我想你會想創建一個自定義Web API「IValueProvider」和「ValueProviderFactory」。看看這裏:http://www.asp。淨/ Web的API /概要/格式和 - 模型綁定/參數結合功能於ASPNET的Web-API –

回答

1

如何開發[EncryptDecrypt]屬性?

[EncryptDecrypt]實際上應該是JsonConverter屬性嗎?或者我應該開發一個自定義媒體格式化程序或模型聯編程序或值提供程序或參數聯編程序?我很困惑。

你需要開發一些; (de)序列化JSON數據的定製JsonConverter以及用於將(加密的int/long)值綁定到端點參數的定製ModelBinder

嘗試這樣:

public class EncryptDecrypt : JsonConverter, IModelBinder 
{  
    public override bool CanConvert(Type objectType) 
    { 
    return typeof(int).IsAssignableFrom(objectType) || 
      typeof(long).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
    // Deserialize the provided value as string 
    // and decrypt it to its exprected int/long type 
    var value = serializer.Deserialize<string>(reader); 
    return Decrypt(value, objectType); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
    // obviously Encrypt() should convert the int/ long value 
    // to its encrypted string representation. 
    var encrypted = Encrypt(value); 
    writer.WriteValue(encrypted); 
    } 

    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
    { 
    if (!CanConvert(bindingContext.ModelType)) return false; 

    var val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
    if (val == null) return false; 

    // bindingContext.ModelType should tell us whether the decrypted value 
    // is expected as an int/ long. 
    var decrypted = Decrypt(val.RawValue as string, bindingContext.ModelType); 
    if (decrypted != null) 
    { 
     bindingContext.Model = decrypted; 
     return true; 
    } 

    bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Cannot convert value"); 
    return false; 
    } 
} 

然後,您可以裝點模型是這樣的:

public class Person 
{ 
    [JsonConverter(typeof(EncryptDecrypt))] 
    public int PersonID { get; set; } 

    public string Name { get; set; } 

    public IEnumerable<Order> Orders { get; set; } 
} 

public class Order 
{ 
    [JsonConverter(typeof(EncryptDecrypt))]  
    public long OrderID { get; set; } 

    public string Title { get; set; } 

    public float Price { get; set; } 
} 

至於在Web API方法,你需要來裝飾它像這樣:

public IHttpActionResult Get([ModelBinder(typeof(EncryptDecrypt))] int personId) 
{ 
    // Now, I expect personId to be a normal ID, like: 187356 
    Person person = _repository.GetPerson(personId); 

    return Json(person); 
} 

public void Put([ModelBinder(typeof(EncryptDecrypt))] int personId, Order editedOrder) 
{ 
    // I expect personId to be a normal ID, like: 187356 
    // I expect editedOrder.OrderID to be a normal ID, like: 10000089765 

    _repository.UpdateOrder(personId, editedOrder); 
} 
相關問題