On several of our AJAX endpoints, we accept a string and immediately in the method, we try to decrypt the string into an int. Seems like a lot of repetitive code.
public void DoSomething(string myId)
{
int? id = DecryptId(myId);
}
Where DecryptId is a common method (in the base controller class)
I would like to create a class that does all this for me and use this new class as the data type in the method argument (instead of string
) and then a getter
that returns the decrypted int?
What's the best way to do this?
Here's my implementation that is working.
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; }
}
... and in Global.asax.cs in the Application_Start method (in case you want it global for all EncryptedInt types instead of using Attribute on each reference) ...
// register Model Binder for EncryptedInt type
ModelBinders.Binders.Add(typeof(EncryptedInt), new EncryptedIntModelBinder());