Search code examples
c#encryption

Data type to handle decrypting data - as method param data type


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?


Solution

  • 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());