ASP.NET 8,控制器。
我的类型类似于“任一”:ResultOrUnprocessable<,>。
我有一个方法:
[HttpPost]
public ResultOrUnprocessable<FileResult, SomeErrors> GetFileOrError()
{
return File([2, 3, 5, 6, 2], MediaTypeNames.Application.Octet);
}
还有 IOutputFormatter。根据我的想法,如果方法“返回”FileResult(ResultOrUnprocessable.IsSuccess = true),那么FileResult应该成为返回值并由asp.net处理,就好像该方法返回的不是ResultOrUnprocessable<,>,而是FileResult。
public class ResultOrUnprocessableOutputFormatter : IOutputFormatter
{
private static readonly PropertyInfo ObjectPropertyInfo;
private static readonly PropertyInfo ObjectTypePropertyInfo;
static ResultOrUnprocessableOutputFormatter()
{
var t = typeof(OutputFormatterCanWriteContext);
ObjectPropertyInfo = t.GetProperty("Object") ?? throw new MissingMemberException();
ObjectTypePropertyInfo = t.GetProperty("ObjectType") ?? throw new MissingMemberException();
}
public bool CanWriteResult(OutputFormatterCanWriteContext context)
{
if (context.Object is not IResultOrUnprocessable resultOrUnprocessable)
{
return false;
}
if (resultOrUnprocessable.IsSuccess)
{
//here i replace ResultOrUnprocessable<,> with FileResult
ObjectPropertyInfo.SetValue(context, resultOrUnprocessable.ResultObject);
ObjectTypePropertyInfo.SetValue(context, resultOrUnprocessable.ResultObject?.GetType());
return false;
}
return true;
}
public async Task WriteAsync(OutputFormatterWriteContext context)
{
if (context.Object is not IResultOrUnprocessable resultOrUnprocessable)
{
throw new InvalidCastException();
}
var response = context.HttpContext.Response;
if (!resultOrUnprocessable.IsSuccess)
{
var serialized = JsonSerializer.Serialize(resultOrUnprocessable.UnprocessableInfoObject);
response.StatusCode = StatusCodes.Status422UnprocessableEntity;
response.ContentType = MediaTypeNames.Application.Json;
await response.WriteAsync(serialized);
}
else
{
throw new UnreachableException();
}
}
}
程序.cs:
services.AddControllers(options =>
{
options.OutputFormatters.RemoveType<StringOutputFormatter>(); //so that json is returned and not plain text when I return string or int
options.OutputFormatters.Insert(0, new ResultOrUnprocessableOutputFormatter());
})
但是 FileResult 没有像往常一样返回(application/octet-stream),而是以“application/json; charset=utf-8”的形式返回,正文为:
{
"filecontents": "AgMFBgI=",
"contenttype": "application/octet-stream",
"filedownloadname": "",
"lastmodified": null,
"entitytag": null,
"enablerangeprocessing": false
}
如何正确替换 ResultOrUnprocessable
已修复。
我添加了一个全局过滤器 (IActionFilter),如果 ResultOrUnprocessable
https://github.com/Lavshyak/ROUMV/blob/master/ROUMV/ResultsAndErrors/ResultOrUnprocessableFilter.cs