Search code examples
c#asp.net-coreasp.net-core-webapiaction-filter

Getting an unknown Type at runtime in a Web API action filter


I want to be able to change an object result value within an action filter without using reflection.

I am able to get this to work fine (as provided in the code below) if I provide the type (Person) however during runtime I am not sure what the type will be and as a result I am looking for more of a "dynamic" type if it is possible.

public class MyFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        var result = context.Result as OkObjectResult;

        string json = JsonConvert.SerializeObject(result.Value);
        json = json.Replace("John", "John Smith");

        var modifiedResultValue = JsonConvert.DeserializeObject<Person>(json);

        result.Value = modifiedResultValue;
    }
}
{
  "name": "John Smith"
}

I have tried using dynamic, as below

var modifiedResultValue = JsonConvert.DeserializeObject<dynamic>(json);

however it deletes all the values

{
  "Name": []
}

Is there a way to achieve this?


Solution

  • ASP.NET Core by default uses System.Text.Json to handle serialization, not Newtonsoft Json.NET (where JsonConvert comes from). dynamic in this case will be treated as JObject from the Json.NET and it is not treated correctly by the first default one.

    Quick and dirty approach would be to just switch to the latter by installing Microsoft.AspNetCore.Mvc.NewtonsoftJson package and adding AddNewtonsoftJson call to your app startup. For example:

    builder.Services.AddControllers().AddNewtonsoftJson();
    

    Another options could be:

    1. Provide type information for Json.NET so it uses correct one:
      var modifiedResultValue = JsonConvert.DeserializeObject(json, result.Value.GetType());
      
    2. Switch filter logic to using System.Text.Json (see How to use a JSON document object model in System.Text.Json)
    3. For purely JSON APIs you can try looking into custom serializers.