本文内容来自书籍: Marinko Spasojevic - Ultimate ASP.NET Core Web API - From Zero To Six-Figure Backend Developer (2nd edition)
内容协商是可以让我们API服务对用户更加的友好和灵活,但是因为这样那样的原因,它的使用没有那么的充分
ASP.NET Core 默认返回JSON格式的结果
builder.Services .AddControllers(config => { config.RespectBrowserAcceptHeader = true; }) .AddXmlDataContractSerializerFormatters() .AddApplicationPart( typeof(CompanyEmployees.Presentation.AssemblyReference).Assembly);
我们的DTO是个record
,所以在返回的时候,会报错,我们需要对这个类型进行处理
[Serializable]
init
的属性设置修改了DTO之后,AutoMapper也要相应修改
CreateMap<Company, CompanyDto>() .ForMember(c => c.FullAddress, opt => opt.MapFrom(x => string.Join(' ', x.Address, x.Country)));
当客户端给服务端发送一些服务端不知道的返回类型的时候,可以通过设置,返回406 Not Acceptable
builder.Services .AddControllers(config => { config.RespectBrowserAcceptHeader = true; config.ReturnHttpNotAcceptable = true; }) .AddXmlDataContractSerializerFormatters() .AddApplicationPart( typeof(CompanyEmployees.Presentation.AssemblyReference).Assembly);
这样就可以让客户端一定要遵守服务端所支持的类型
如果希望API能够支持非常规的格式化,ASP.NET Core支持自定义格式化器
有如下几种方法
public class CsvOutputFormatter : TextOutputFormatter { public CsvOutputFormatter() { SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/csv")); SupportedEncodings.Add(Encoding.UTF8); SupportedEncodings.Add(Encoding.Unicode); } protected override bool CanWriteType(Type? type) { if (typeof(CompanyDto).IsAssignableFrom(type) || typeof(IEnumerable<CompanyDto>).IsAssignableFrom(type)) { return base.CanWriteType(type); } return false; } public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) { var response = context.HttpContext.Response; var buffer = new StringBuilder(); if (context.Object is IEnumerable<CompanyDto>) { foreach (var company in (IEnumerable<CompanyDto>)context.Object) { FormatCsv(buffer, company); } } else { FormatCsv(buffer, (CompanyDto)context.Object); } await response.WriteAsync(buffer.ToString()); } private static void FormatCsv(StringBuilder buffer, CompanyDto company) { buffer.AppendLine($"{company.Id},\"{company.Name},\"{company.FullAddress}\""); } }
CanWriteType
方法重写,表明CompanyDto
这种类型可以被这个格式化器序列化WriteResponseBodyAsync
方法重写,构造响应FormatCsv
私有方法,响应的格式化然后在主项目中注册服务,然后服务器就支持返回text/csv
格式
public static IMvcBuilder AddCustomCsvFormatter(this IMvcBuilder builder) => builder.AddMvcOptions(config => config.OutputFormatters.Add(new CsvOutputFormatter())); // Program.cs builder.Services.AddControllers(config => { config.RespectBrowserAcceptHeader = true; config.ReturnHttpNotAcceptable = true; }) .AddXmlDataContractSerializerFormatters() .AddCustomCsvFormatter() .AddApplicationPart(typeof(AssemblyReference).Assembly);