我正在迁移仅具有API控制器且没有视图的.Net Core 2.2 Web API应用程序。我在我的项目中使用SuperJsonOutputFormatter设置了自定义API响应。现在,我正在使用NewtonsoftJsonOutputFormatter为API创建自定义响应。但是根据Microsoft文档的服务,.Net Core 3.1中已弃用AddMvc()。因此,如何在startup.cs中调用customformatter。我正在使用以下代码
services.AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
options.SerializerSettings.Formatting = Formatting.Indented;
});
services.AddScoped<SuperJsonOutputFormatterFilter>();
services.AddMvc(opts =>
{
opts.EnableEndpointRouting = false;
var oldFormatter = opts.OutputFormatters.OfType<CustomOutputFormatter>().Single();
opts.OutputFormatters.Remove(oldFormatter);
var replacementJsonOutputFormatter =
new CustomOutputFormatter(oldFormatter.serializerSettings, ArrayPool<char>.Shared);
opts.OutputFormatters.Add(replacementJsonOutputFormatter);
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
配置服务如下
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseRouting();
app.UseExceptionHandler("/Error");
app.UseAuthentication();
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseMvc();
}
上面的代码给出了一个运行时错误,指出某些服务无法构建,在验证服务描述符时出错。如何在不使用Services.AppMvc()的情况下调用customformatter
我的错误帮助器如下
ErrorDescription类
public class ErrorDescription { public ErrorDescription(HttpStatusCode statusCode) { this.Code = (int)statusCode; this.Description = GetDescription((int)statusCode); } string GetDescription(int statusCode) { return statusCode switch { 404 => "Employee ID not found", 500 => "Internal server error", 400 => "Device token already registered", 406 => "No data found in table", _ => "", }; } [JsonProperty("errorCode")] public int Code { get; set; } [JsonProperty("errorDescription")] public string Description { get; set; } }
FormatterFilter类
public class CustomJsonOutputFormatterFilter : IAsyncActionFilter { private readonly CustomOutputFormatter _formatter; // inject SuperJsonOutputFormatter service public CustomJsonOutputFormatterFilter(CustomOutputFormatter formatter) { this._formatter = formatter; } // a helper method that provides an ObjectResult wrapper over the raw object private ObjectResult WrapObjectResult(ActionExecutedContext context, object obj) { var wrapper = new ObjectResult(obj); wrapper.Formatters.Add(this._formatter); context.Result = wrapper; return wrapper; } public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { ActionExecutedContext resultContext = await next(); // in case we get a 500 if (resultContext.Exception != null && !resultContext.ExceptionHandled) { var ewrapper = this.WrapObjectResult(resultContext, new { }); ewrapper.StatusCode = (int)HttpStatusCode.InternalServerError; resultContext.ExceptionHandled = true; return; } else { switch (resultContext.Result) { case BadRequestObjectResult b: // 400 with an object var bwrapper = this.WrapObjectResult(resultContext, b.Value); bwrapper.StatusCode = b.StatusCode; break; case NotFoundObjectResult n: // 404 with an object var nwrapper = this.WrapObjectResult(resultContext, n.Value); nwrapper.StatusCode = n.StatusCode; break; case ObjectResult o: // plain object this.WrapObjectResult(resultContext, o.Value); break; case JsonResult j: // plain json this.WrapObjectResult(resultContext, j.Value); break; case StatusCodeResult s: // other statusCodeResult(including NotFound,NoContent,...), you might want to custom this case var swrapper = this.WrapObjectResult(resultContext, new { result="" }); swrapper.StatusCode = s.StatusCode; break; } } } }
Custom Outputformatter类,此类称为customformatterfilter
public class CustomOutputFormatter : NewtonsoftJsonOutputFormatter
{
public CustomOutputFormatter(JsonSerializerSettings serializerSettings,
ArrayPool<char> charPool) : base (serializerSettings, charPool)
{
}
public JsonSerializerSettings serializerSettings { get; private set; }
public override async Task WriteResponseBodyAsync(
OutputFormatterWriteContext context,
Encoding selectedEncoding)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
if (selectedEncoding == null)
if (selectedEncoding == null)
throw new ArgumentNullException(nameof(selectedEncoding));
using TextWriter writer = context.WriterFactory(context.HttpContext.Response.Body, selectedEncoding);
var statusCode = context.HttpContext.Response.StatusCode;
var rewrittenValue = new
{
status = IsSucceeded(statusCode),
error = IsSucceeded(statusCode) ? null : new ErrorDescription((HttpStatusCode)statusCode),
data = context.Object,
};
writer.Write(rewrittenValue);
this.CreateJsonWriter(writer);
await writer.FlushAsync();
}
private bool IsSucceeded(int statusCode)
{
// 204 is not an error but handled
if (statusCode >= 400 || statusCode == 204) { return false; }
return true;
}
}
我正在迁移仅具有API控制器且没有视图的.Net Core 2.2 Web API应用程序。我在我的项目中使用SuperJsonOutputFormatter设置了自定义API响应。现在,我正在使用...
您可以使用Microsoft提供的迁移指南: