在ASP.NET MVC中通过ElasticsearchClientSettings设置index.mapping.ignore_malformed的方法
解决Audit.NET结合Elasticsearch数据审计的400 Bad Request错误
错误原因
报错核心是Elasticsearch自动映射机制将entityFrameworkEvent.entries.changes.originalValue字段识别为date类型,但实际存储的是UUID字符串(如b67265c6-8653-4224-8106-c594c8341eb3),导致日期解析失败,返回400 Bad Request。
解决方法
方法一:手动创建索引并配置字段映射或全局忽略格式错误
Elasticsearch自动生成的映射无法直接修改,需先清理现有索引(若允许),再手动创建索引并指定字段类型或开启全局格式忽略:
var settings = new ElasticsearchClientSettings(new Uri("IP Address")) .DefaultIndex("index_name") .CertificateFingerprint("certificate_fingerprint") .Authentication(new BasicAuthentication("username", "password")); var client = new ElasticsearchClient(settings); // 可选:删除已有索引(注意备份数据) if (client.Indices.Exists("index_name").Exists) { client.Indices.Delete("index_name"); } // 创建索引,精准指定变更字段为keyword类型 var createIndexResponse = client.Indices.Create("index_name", c => c .Mappings(m => m .Properties(p => p .Object<EntityFrameworkAuditEvent>(oe => oe .Name("entityFrameworkEvent") .Properties(e => e .Object<AuditEntry>(ae => ae .Name("entries") .Properties(en => en .Object<AuditChange>(ac => ac .Name("changes") .Properties(ch => ch .Keyword(k => k.Name("originalValue")) .Keyword(k => k.Name("newValue")) ) ) ) ) ) ) ) ) );
若不想精准指定字段,也可开启全局格式忽略(会忽略所有字段的解析错误):
var createIndexResponse = client.Indices.Create("index_name", c => c .Settings(s => s .Setting("index.mapping.ignore_malformed", true) ) );
方法二:修改Audit.NET事件序列化逻辑
在审计事件写入Elasticsearch前,将变更字段的值统一转为字符串,避免Elasticsearch自动映射错误:
var settings = new ElasticsearchClientSettings(new Uri("IP Address")) .DefaultIndex("index_name") .CertificateFingerprint("certificate_fingerprint") .Authentication(new BasicAuthentication("username", "password")); Audit.Core.Configuration.Setup() .UseElasticsearch(config => config .Client(new ElasticsearchClient(settings)) .CustomizeDocument((auditEvent, document) => { var efEvent = auditEvent.GetEntityFrameworkEvent(); if (efEvent?.Entries != null) { foreach (var entry in efEvent.Entries) { if (entry.Changes != null) { foreach (var change in entry.Changes) { change.OriginalValue = change.OriginalValue?.ToString(); change.NewValue = change.NewValue?.ToString(); } } } } return document; }) );
推荐方案
优先选择方法二,无需修改Elasticsearch索引配置,直接在应用层统一处理数据格式,避免后续其他字段出现类似类型映射问题,同时保留审计数据的完整性。
内容的提问来源于stack exchange,提问作者user3634071
相关产品推荐
相关产品推荐

