我对asp.net core jsonserializer有一个问题。即使我明确将参考文献和引用属性设置为coreenceLophandling.ignore。
我有这个github问题中的详细信息:https://github.com/aspnet/entityframeworkcore/issues/14997
编辑:
整个启动配置代码:
public void ConfigureServices(IServiceCollection services)
{
// Deserialize specific settings into living objects
services.Configure<JwtSettings>(this.Configuration.GetSection("Jwt"));
services.Configure<CookieSettings>(this.Configuration.GetSection("Cookies"));
// Read settings to apply locally
DatabasesSettings dbSettings = DatabasesSettings.GetDatabasesSettings(this.Configuration);
JwtSettings jwtSettings = this.Configuration.GetSection("Jwt").Get<JwtSettings>();
CookieSettings cookieSettings = this.Configuration.GetSection("Cookies").Get<CookieSettings>();
switch (dbSettings[DatabaseConstants.DatabaseSettingsData].Provider)
{
case "mysql":
services.AddEntityFrameworkMySql()
.AddDbContext<DataContext>(options => options.UseMySql(ConnectionStringBuilder.BuildConnectionString(dbSettings[DatabaseConstants.DatabaseSettingsData])));
break;
case "mssql":
services.AddEntityFrameworkSqlServer()
.AddDbContext<DataContext>(options => options.UseSqlServer(ConnectionStringBuilder.BuildConnectionString(dbSettings[DatabaseConstants.DatabaseSettingsData])));
break;
}
// Identity MUST precede AUTHENTICATION in order to produce correct 401 Unauthorized instead of 404 Not found
services.AddIdentity<User, IdentityRole>(options =>
{
options.User.RequireUniqueEmail = true;
options.Password.RequiredLength = 6;
options.Password.RequireDigit = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequireLowercase = false;
}).AddEntityFrameworkStores<DataContext>().AddDefaultTokenProviders();
// JWT Bearer Token Authentication configuration secretKey contains a secret passphrase only your server knows
Action<JwtBearerOptions> jwtOptions = options =>
{
options.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
// Get the EF Context responsbile for authentication
DataContext dbContext = context.HttpContext.RequestServices.GetRequiredService<DataContext>();
List<Claim> claims = new List<Claim>
{
new Claim("AuthorizedAccess", "true"),
};
// Add claim(s) based on user -- todo
ClaimsIdentity appIdentity = new ClaimsIdentity(claims);
context.Principal.AddIdentity(appIdentity);
return Task.CompletedTask;
}
};
options.TokenValidationParameters = new TokenValidationParameters
{
// Do not validate lifetime. Need logout to invalidate. todo: verify if we can leave it this way
ValidateLifetime = jwtSettings.Expiration.Enabled,
// If you want to allow a certain amount of clock drift, set that here:
ClockSkew = TimeSpan.FromMinutes(jwtSettings.Expiration.ClockDrift),
// Validate the JWT Issuer (iss) claim
ValidateIssuer = true,
ValidIssuer = jwtSettings.Issuer,
// Validate the JWT Audience (aud) claim
ValidateAudience = true,
ValidAudience = jwtSettings.Audience,
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Key)),
SaveSigninToken = true
};
};
// Authentication Service
services.AddAuthentication(
options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(jwtOptions).AddCookie();
// Authorization Service
services.AddAuthorization(
options =>
{
options.AddPolicy(PolicyNames.AdministrationPolicy, policy => policy.Requirements.Add(new AuthorizationNameRequirement(PolicyNames.AdministrationPolicy)));
options.AddPolicy(PolicyNames.PurchasePolicy, policy => policy.Requirements.Add(new AuthorizationNameRequirement(PolicyNames.PurchasePolicy)));
options.AddPolicy(PolicyNames.TradePolicy, policy => policy.Requirements.Add(new AuthorizationNameRequirement(PolicyNames.TradePolicy)));
options.AddPolicy(PolicyNames.ExchangePolicy, policy => policy.Requirements.Add(new AuthorizationNameRequirement(PolicyNames.ExchangePolicy)));
});
// Application Cookie
services.ConfigureApplicationCookie(
options =>
{
// Avoid redirecting REST clients on 401
options.Events = new CookieAuthenticationEvents
{
OnRedirectToLogin = ctx =>
{
ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
return Task.FromResult(0);
}
};
options.Cookie.Name = cookieSettings.ApplicationCookieName;
});
// Antiforgery
services.AddAntiforgery(
options =>
{
options.Cookie.Name = cookieSettings.AntiforgeryCookieName;
options.Cookie.Domain = cookieSettings.AntiforgeryCookieDomain;
options.Cookie.Path = "/";
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
// Additional Services
services.AddSingleton<IAuthorizationHandler, AuthorizationNameHandler>();
// Cross Origin Policies
services.AddCors(
options =>
{
options.AddPolicy("AllowAnyOrigin", builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials().Build(); });
});
// Enable Response Compression
services.AddResponseCompression();
// MVC
services.AddMvc(
options =>
{
options.Filters.Add(new CorsAuthorizationFilterFactory("AllowAnyOrigin"));
options.CacheProfiles.Add(
"Default",
new CacheProfile()
{
Duration = 60
});
options.CacheProfiles.Add(
"Never",
new CacheProfile()
{
Location = ResponseCacheLocation.None,
NoStore = true
});
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2).AddJsonOptions(
options =>
{
options.SerializerSettings.Formatting = Formatting.Indented;
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (Program.IsDebug)
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseCors("AllowAnyOrigin");
// app.UseCorsMiddleware(); // Custom middleware
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthentication();
app.UseResponseCompression();
app.UseMvc();
}
您可以配置Json.NET
以忽略对象图中找到的周期。这是在Startup.cs
中的ConfigureServices(...
)方法中完成的,如下所示:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
...
}
在您的代码中,用以下内容替换options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Error;
:
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore