2016-04-01 8 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; 
} 

上記のWeb 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を見てください。net/web-api/overview/formats-and-model-binding /パラメータバインディング-aspnet-web-api –

答えて

1

[EncryptDecrypt]属性はどのように開発できますか?

[EncryptDecrypt]は実際にはJsonConverter属性である必要がありますか?または、カスタムのMedia FormatterやModel Binder、Value Provider、またはParameter Binderを開発する必要がありますか?私は混乱しています。

両方のビットを開発する必要があります。エンドポイントパラメータに(暗号化された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; 
    } 
} 

あなたは、このようなモデルを飾ることができます。Web APIメソッドについては

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

を、あなたはこのようにそれを飾るために必要があるでしょう:

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); 
} 
関連する問題