用不同类型的对象替换端点返回的对象

问题描述 投票:0回答:1

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 为 FileResult?

MVP:https://github.com/Lavshyak/ROUMP

asp.net asp.net-core
1个回答
0
投票

已修复。 我添加了一个全局过滤器 (IActionFilter),如果 ResultOrUnprocessable 成功并包含 FileResult,则将方法的返回更改为 FileResult (IActionResult)。

https://github.com/Lavshyak/ROUMV/blob/master/ROUMV/ResultsAndErrors/ResultOrUnprocessableFilter.cs

© www.soinside.com 2019 - 2024. All rights reserved.