2016-07-10 14 views
4

Auf mehreren unserer AJAX-Endpunkte akzeptieren wir eine Zeichenfolge und versuchen sofort, die Zeichenfolge in der int zu entschlüsseln. Scheint wie viel repetitive Code.Datentyp zum Behandeln von Entschlüsselungsdaten - als Methode param Datentyp

public void DoSomething(string myId) 
{ 
    int? id = DecryptId(myId); 
} 

Wo DecryptId eine gemeinsame Methode (in der Basis-Controller-Klasse) ist

Ich möchte eine Klasse erstellen, die für mich all dies tut, und diese neue Klasse als Datentyp in dem Verfahren Argument (statt string) und dann eine getter, die die entschlüsselte int?

zurückgibt. Was ist der beste Weg, dies zu tun?

Edit:

Hier ist meine Implementierung, die funktioniert.

public class EncryptedInt 
{ 
    public int? Id { get; set; } 
} 

public class EncryptedIntModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext == null) 
     { 
      throw new ArgumentNullException("bindingContext"); 
     } 

     var rawVal = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     var ei = new EncryptedInt 
     { 
      Id = Crypto.DecryptToInt(rawVal.AttemptedValue) 
     }; 
     return ei; 
    } 
} 

public class EncryptedIntAttribute : CustomModelBinderAttribute 
{ 
    private readonly IModelBinder _binder; 

    public EncryptedIntAttribute() 
    { 
     _binder = new EncryptedIntModelBinder(); 
    } 

    public override IModelBinder GetBinder() { return _binder; } 
} 
+1

Wenn Wenn Sie Asp.Net MVC verwenden, glaube ich, dass der beste Weg wäre, einen "EncryptedString" -Typ zu erstellen und einen Modellbinder dafür zu registrieren. – haim770

+0

Ich wollte gerade eine Erweiterungsmethode für 'string' vorschlagen, aber ich denke, dass die Entschlüsselung nur einmal stattfinden soll (nicht einmal pro Methode/Eigenschaft). – Heinzi

+0

@Heinzi, ja, ich möchte nur die Entschlüsselung einmal passieren lassen. –

Antwort

1

Hier ist meine Implementierung, die funktioniert.

public class EncryptedInt 
{ 
    public int? Id { get; set; } 

    // User-defined conversion from EncryptedInt to int 
    public static implicit operator int(EncryptedInt d) 
    { 
     return d.Id; 
    } 
} 

public class EncryptedIntModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext == null) 
     { 
      throw new ArgumentNullException("bindingContext"); 
     } 

     var rawVal = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     var ei = new EncryptedInt 
     { 
      Id = Crypto.DecryptToInt(rawVal.AttemptedValue) 
     }; 
     return ei; 
    } 
} 

public class EncryptedIntAttribute : CustomModelBinderAttribute 
{ 
    private readonly IModelBinder _binder; 

    public EncryptedIntAttribute() 
    { 
     _binder = new EncryptedIntModelBinder(); 
    } 

    public override IModelBinder GetBinder() { return _binder; } 
} 

... und in Global.asax.cs in Application_Start Methode (falls Sie es für alle EncryptedInt Typen global wollen statt mit Attribut auf jede Referenz) ...

// register Model Binder for EncryptedInt type 
ModelBinders.Binders.Add(typeof(EncryptedInt), new EncryptedIntModelBinder());