2016-04-01 20 views
1

Bir ASP.NET Web API projesinde, tüm yanıtlarda tüm varlık kimliklerini şifrelemek ve şifrelenmiş değerleri tüm isteklerde çözmek istiyorum.ASP.NET Web API'sinde Basit Özellik Üzerinde Özel Tür Dönüştürücü

(NOT:. I/şifrelemek verilerin şifresini çözmek için nasıl, sorum değildir)

Ben sadece ben olarak şifrelenir/gereken özelliklere dekore eğer iyi olacağını düşünüyorum özel bir özelliğe sahip yanıtlar/istekler.

Bu

Ben çalışmak istiyorum nasıl:

Web API yönteminde Sonra
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;} 
} 

:

// 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; 
} 

yukarıdaki Web API için arzu yanıttır:

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

Ve bu başka bir örnektir, bu sefer PUT fiil için bir Web API'sı:

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

ilgili Web API yöntemi:

// 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); 
} 

nasıl [EncryptDecrypt] niteliğini geliştirebilirler?

[EncryptDecrypt] aslında JsonConverter attribute olmalıdır? Veya özel bir Media Formatter veya Model Binder veya Değer Sağlayıcı veya Parametre Binder mi geliştirmeliyim? Kafam karıştı.

+0

Böyle bir şey ister misiniz? http://www.codemag.com/article/0307041 – Namrehs

+2

Bkz. [Nesnemi dizileştirirken seçili özellikleri nasıl şifreleyebilirim?] (http://stackoverflow.com/q/29196809/10263) nasıl ele alınacağı hakkında bir fikir edinmek için serileştirme sonu. Bunu dizeleri değil, sayısal özellikler üzerinde çalışmasını istediğinizden biraz uyarlamanız gerekir. Web API parametresi kullanımı için özel bir Web API'si olan 'IValueProvider' ve 'ValueProviderFactory' oluşturmak istediğinizi düşünüyorum. Bir göz atın: http: //www.asp.Net/web API/genel/biçimleri-ve-modeli bağlayıcı/parametre bağlayıcı-in-aspnet-internet-api –

cevap

1

[EncryptDecrypt] özniteliğini nasıl geliştirebilirim?

[EncryptDecrypt] aslında bir JsonConverter özniteliği olmalı mı? Yoksa özel bir Medya Formatlayıcı veya Model Binder mi, Değer Sağlayıcı mı, yoksa Parametre Binder mi geliştirmeliyim? Kafam karıştı.

İkisini de biraz geliştirmelisiniz; JSON verilerini ve (şifrelenmiş int/long) değerini son nokta parametresine bağlamak için özel bir ModelBinder (de) serileştirmek için bir özel JsonConverter. Böyle

deneyin şey:

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; 
    } 
} 

Sonra böyle modeller süslemeleri: Web API yöntemlerinin gelince

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; } 
} 

, böyle dekore etmek gerekir:

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); 
}