Reputation: 742
I have a model object that I send to the browser and gets sent back to me. I want that ID value in that object to be encrypted. I created a custom JsonConverter to encrypt the string and then decrypt it.
public class SecretItem
{
[JsonConverter(typeof(EncryptedIdConverter))]
public string Id { get; set; }
public string Name { get; set; }
}
This is my EncryptedIdConverter class
class EncryptedIdConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
string encryptedValue = (string)value;
if (!string.IsNullOrWhiteSpace(encryptedValue))
encryptedValue = Encryption.EncryptString(encryptedValue);
serializer.Serialize(writer, encryptedValue);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
string decryptedString = (string)reader.Value;
if (!string.IsNullOrWhiteSpace(decryptedString))
decryptedString = Encryption.DecryptString(decryptedString);
return decryptedString;
}
public override bool CanConvert(Type objectType)
{
return typeof(string).IsAssignableFrom(objectType);
}
}
If I try calling the JsonConvert.Serialization functions, everything works correctly.
JsonConvert.SerializeObject(secretItem)
JsonConvert.DeserializeObject<SecretItem>([JSON secretItem]);
When I return the HttpActionResult Ok(secretItem)
... the browser also gets the encrypted Id string.
However, when I POST the data back to my controller, my webapi method is not getting a decrypted property. It skips the JsonConverter.
public async Task<IHttpActionResult> Post(SecretItem secretItem)
{
// Not decrypted
var decryptedId = secretItem.Id;
}
Why would the deserialize logic not be working the same as the serialize logic in my WebAPI? I don't even know where to start debugging that.
We are using Newtonsoft.Json 10.0.0.0, MVC5, .NET Framework 4.6.1.
Upvotes: 5
Views: 5682
Reputation: 8599
How is your Global.asax
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
it should work
When Web API calls a method on a controller, it must set values for the parameters, a process called binding
This is called Model binding
Post(SecretItem secretItem)
Model binding use a TypeConverter
This is called JSON Serialization
HttpActionResult Ok(secretItem)
JSON Serialization use a JsonConverter
asp.net mvc - C# WebAPI: Set default JSON serializer to NewtonSoft JSON - Stack Overflow
c# - Setting the default JSON serializer in ASP.NET MVC - Stack Overflow
c# - How to use Json.NET for JSON modelbinding in an MVC5 project? - Stack Overflow
Upvotes: 2
Reputation: 742
It turns out the code is working correctly. The problem was that on the POST that was being tested, the content-type wasn't set to "application/json". So, it didn't use the JsonNetFormatter and therefore skipped the converter.
Once I set the contentType, everything works!
Upvotes: 4