简体   繁体   中英

Model binding stopped working in case of ASP.NET Core 3.1 Web API

I have an ASP.NET Core 3.1 Web API with the following code in Startup.cs in which case model-binding worked perfectly without any issues:

Startup.cs :

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers().AddNewtonsoftJson(newtonsoft =>
    {
        newtonsoft.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    });
}

I did a minor change to encapsulate all the methods and updated the code to the following: post the below change Model binding stopped working.

Startup.cs :

public virtual void ConfigureServices(IServiceCollection services) => services.AddControllers().Services.AddCustomConfigureOptions();

public static IServiceCollection AddCustomConfigureOptions(this IServiceCollection services) => services.ConfigureOptions<ConfigureJsonOptions>();

ConfigureJsonOptions.cs :

public class ConfigureJsonOptions : IConfigureOptions<MvcNewtonsoftJsonOptions>
{
    private readonly IWebHostEnvironment webHostEnvironment;
    public ConfigureJsonOptions(IWebHostEnvironment webHostEnvironment) => this.webHostEnvironment = webHostEnvironment;

    public void Configure(MvcNewtonsoftJsonOptions options)
    {
        if (webHostEnvironment.IsEnvironment(C.Constants.Local))
        {
            // Pretty print the JSON in development for easier debugging.
            options.SerializerSettings.Formatting = Formatting.Indented;
        }

        // Parse dates as DateTimeOffset values by default. You should prefer using DateTimeOffset over
        // DateTime everywhere. Not doing so can cause problems with time-zones.
        options.SerializerSettings.DateParseHandling = DateParseHandling.DateTimeOffset;
        options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        // Output enumeration values as strings in JSON.
        options.SerializerSettings.Converters.Add(new StringEnumConverter());
    }
}

Can anyone help me to resolve this issue?

Well the first thing I'm noticing is that you are never setting your webHostEnvironment property of the configure class. The thing is, you are still building your service definitions (note that you have IServiceCollection instead of IServiceProvider , and IServiceCollection.ConfigureOptions<TConfigureOptions>() is really meant to extend the options pattern , which is IMO better used for dynamic settings that service configuration.

Instead of encapsulating this in a separate class, I'd say keep it simple and just stick with the lambda based config. If you have to base it off of environment, use something like this . If not, I've always found preprocessor directives to address this issue very cleanly:

// Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddControllers();
      services.AddNewtonsoftJson(jsonSettings =>
      {
        #if DEBUG
        jsonSettings.SerializerSettings.Formatting = Formatting.Indented;
        #endif

        // Parse dates as DateTimeOffset values by default. You should prefer using DateTimeOffset over
        // DateTime everywhere. Not doing so can cause problems with time-zones.
        options.SerializerSettings.DateParseHandling =
          DateParseHandling.DateTimeOffset;

        jsonSettings.SerializerSettings.ReferenceLoopHandling =
          ReferenceLoopHandling.Ignore;

        // Output enumeration values as strings in JSON.
        jsonSettings.SerializerSettings.Converters.Add(new StringEnumConverter());
      });

      // other service definitions here
      // ...
    }

This checks to see if the build was done in debug or release mode, and only includes that line in debug builds.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM