.NET Core API之格式化输出对象OutputFormatter

当我们在开发.NET Core API时,有时候需要在API返回结果中自定义格式,比如JSON格式化、XML格式化或者自定义格式化等。这时我们可以使用OutputFormatter来自定义输出格式,本文将详细讲解OutputFormatter的使用方法。

什么是OutputFormatter

OutputFormatter是.NET Core框架中提供的一个类,它用于在API返回结果中自定义输出格式。通过继承OutputFormatter类并重写其中的方法,我们可以自定义各种格式化输出。

OutputFormatter的基本使用

OutputFormatter是抽象类,不能直接实例化。我们需要创建一个继承OutputFormatter的类,并在其中实现自定义格式化的逻辑。下面是一个示例:

public class MyOutputFormatter : OutputFormatter
{
    private readonly string mediaType;
    public MyOutputFormatter(string mediaType)
    {
        if (string.IsNullOrEmpty(mediaType))
        {
            throw new ArgumentNullException(nameof(mediaType));
        }
        this.mediaType = mediaType;
        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(mediaType));
    }
    protected override bool CanWriteType(Type type)
    {
        return true;
    }
    public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
    {
        // 格式化输出逻辑
        await context.HttpContext.Response.WriteAsync($"Hello from {mediaType}");
    }
}

其中:

  • 构造函数中通过添加 mediaType 来设置输出格式的媒体类型。
  • 重写 CanWriteType 方法,返回 true 表示这个输出格式支持所有类型。
  • 重写 WriteResponseBodyAsync 方法,完成格式化输出逻辑。在这个方法中,我们可以通过 context 参数获取要输出的对象,通过 selectedEncoding 参数获取编码方式,然后格式化输出。

完成自定义OutputFormatter后,我们需要在Startup.cs文件中注册它。可以通过以下方式进行注册:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers(opts =>
    {
        opts.OutputFormatters.Insert(0, new MyOutputFormatter("application/myformat"));
    });
}

OutputFormatter示例

下面通过两个示例,说明OutputFormatter的具体使用方法。

示例一:自定义JSON格式输出

ASP.NET Core默认的JSON输出格式是驼峰式命名。有时我们需要将输出的属性名称转换为大写格式。这时我们可以通过自定义OutputFormatter来实现。

// 定义输出格式
public class UpperCaseNamingPolicy : JsonNamingPolicy
{
    public override string ConvertName(string name) => name.ToUpper();
}

// 定义OutputFormatter
public class UpperCaseNamingPolicyFormatter : SystemTextJsonOutputFormatter
{
    public UpperCaseNamingPolicyFormatter(JsonSerializerOptions options) : base(options)
    {
    }

    public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding encoding)
    {
        var response = context.HttpContext.Response;
        response.ContentType = "application/json";
        response.StatusCode = 200;

        var json = JsonSerializer.Serialize(context.Object, _jsonOptions);
        json = json.ToJson(ConfigurationManager.AppSettings["ConvertDataType"].ToString().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); // 可以在这里对输出对象进行二次处理

        using (var writer = new StreamWriter(response.Body, encoding))
        {
            await writer.WriteAsync(json.TrimEnd('\r','\n'));
            await writer.FlushAsync();
        }
    }
}

在该类的构造函数中,对JSON序列化组件进行了设置,以保证格式处理的正确性。在WriteResponseBodyAsync方法中,我们将输出对象格式化为JSON格式,并将属性名称转换为大写格式。在进行对象的序列化处理后,我们也可以对输出对象进行二次处理。

最后,在Startup.cs文件中进行注册:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    // 添加自定义输出格式
    services.AddSingleton<JsonSerializerOptions>(new JsonSerializerOptions
    {
        PropertyNamingPolicy = new UpperCaseNamingPolicy(),
        WriteIndented = true
    });
    services.AddMvc(options =>
    {
        options.OutputFormatters.RemoveType<SystemTextJsonOutputFormatter>();
        options.OutputFormatters.Insert(0, new UpperCaseNamingPolicyFormatter(options));
    });
}

示例二:自定义CSV格式输出

有时我们需要将API返回的数据以CSV格式进行输出。这时可以通过自定义OutputFormatter来实现。

// 定义输出格式
public class CsvMediaType : MediaTypeHeaderValue
{
    public CsvMediaType() : base("text/csv")
    {
    }
}

// 定义OutputFormatter
public class CsvOutputFormatter : OutputFormatter
{
    CsvMediaType csvMediaType;

    public CsvOutputFormatter(CsvMediaType csvMediaType)
    {
        this.csvMediaType = csvMediaType;
        SupportedMediaTypes.Add(csvMediaType);
    }

    protected override bool CanWriteType(Type type)
    {
        return typeof(IEnumerable<ExpandoObject>).IsAssignableFrom(type);
    }

    public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
    {
        var response = context.HttpContext.Response;
        response.Headers.Add("Content-Disposition", new ContentDispositionHeaderValue("attachment")
        {
            FileName = "export.csv"
        }.ToString());

        response.ContentType = csvMediaType.ToString();

        var streamWriter = new StreamWriter(response.Body, selectedEncoding);
        var csvWriter = new CsvWriter(streamWriter, CultureInfo.CurrentCulture);

        var records = (IEnumerable<ExpandoObject>)context.Object;

        // 写入列名
        var columnNames = ((IDictionary<string, object>)records.First()).Keys.ToList();
        foreach (var columnName in columnNames)
        {
            csvWriter.WriteField(columnName);
        }
        csvWriter.NextRecord();

        // 写入数据
        foreach (var record in records)
        {
            foreach (var columnName in columnNames)
            {
                csvWriter.WriteField(((IDictionary<string, object>)record)[columnName]?.ToString());
            }
            csvWriter.NextRecord();
        }

        return Task.CompletedTask;
    }
}

其中,CsvMediaType类用于定义媒体类型为CSV,CsvOutputFormatter类用于自定义CSV格式输出。在CanWriteType方法中,我们通过判断输出对象是否为IEnumerable类型来指定这个输出格式支持的类型。在WriteResponseBodyAsync方法中,则是完成CSV格式化输出逻辑。

最后,在Startup.cs文件中进行注册:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers(opts =>
    {
        opts.OutputFormatters.Insert(0, new CsvOutputFormatter(new CsvMediaType()));
    });
}

这样,每次API返回IEnumerable类型的数据时就会以CSV格式进行输出了。

通过以上两个示例,我们可以发现OutputFormatter的强大之处。我们可以根据具体业务需要,自定义各种格式化输出,提高API返回结果的灵活性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:.NET Core API之格式化输出对象OutputFormatter - Python技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • ASP.NET Core – 缓存之内存缓存(下)

    话接上篇 [ASP.NET Core – 缓存之内存缓存(上)],所以这里的目录从 2.4 开始。 2.4 MemoryCacheEntryOptions MemoryCacheEntryOptions 是内存缓存配置类,可以通过它配置缓存相关的策略。除了上面讲到的过期时间,我们还能够设置下面这些: 设置缓存优先级。 设置在从缓存中逐出条目后调用的 Post…

    C# 2023年4月17日
    00
  • C#.NET采用HTML模板发送电子邮件完整实例

    下面是 C#.NET 采用 HTML 模板发送电子邮件的完整攻略: 第一步:添加命名空间和引用 在 C# 代码中,我们需要引用 System.Net.Mail 命名空间来发送电子邮件。因此,在代码文件的头部需要添加以下引用语句: using System.Net.Mail; 第二步:构建邮件内容 首先,我们需要准备好邮件的内容。在这里,我们将采用 HTML …

    C# 2023年5月31日
    00
  • C#中使用async和await实现异步Udp通讯的示例代码

    当我们需要进行大量的网络IO操作时,使用异步编程可以大大提高程序的效率和性能。在C#中,我们可以使用async和await关键字来进行异步编程。 具体地,当我们进行UDP通讯时,可以将接收和发送操作都用异步的方法来进行,并且使用await关键字来等待异步操作完成。下面我们来看一个实现异步UDP通讯的示例代码。 步骤一:创建UdpClient对象 在C#中,我…

    C# 2023年6月6日
    00
  • C#对桌面应用程序自定义鼠标光标

    当我们需要在C#桌面应用程序中改变鼠标光标的默认外观时,可以使用C#编程语言中提供的Cursor类。下面是关于如何使用Cursor类来实现自定义鼠标光标的攻略: 导入命名空间 在使用Cursor类之前,需要先导入System.Windows.Forms命名空间。代码如下: using System.Windows.Forms; 加载自定义光标文件 在使用自定…

    C# 2023年6月7日
    00
  • .net 读取项目AssemblyInfo.cs属性值

    要读取.NET项目AssemblyInfo.cs文件中的属性值,可以使用System.Reflection.Assembly类的GetExecutingAssembly方法来加载当前项目的Assembly对象,再使用Assembly对象的GetCustomAttribute方法获取特定的属性信息。下面是完整的攻略步骤: Step 1: 准备工作 首先,需要在…

    C# 2023年5月31日
    00
  • C#从数据库读取数据到DataSet并保存到xml文件的方法

    下面是详细讲解“C#从数据库读取数据到DataSet并保存到xml文件的方法”的完整攻略: 步骤1:连接数据库并读取数据 首先,需要在代码中连接数据库,从中读取数据,并将其存储在内存中的 DataSet 中。可以使用 SqlConnection 和 SqlDataAdapter 类来实现这个步骤。下面是一个示例代码: string connectionStr…

    C# 2023年5月31日
    00
  • C# SQLite序列操作实现方法详解

    C# SQLite序列操作实现方法详解 1. 简介 本文主要介绍如何使用C#操作SQLite数据库中的序列(sequence),包括创建、查看、增加和删除序列。 2. 创建和查看序列 2.1 创建序列 在SQLite中创建序列需要用到以下SQL语句: CREATE SEQUENCE sequence_name INCREMENT BY step START …

    C# 2023年5月31日
    00
  • C#难点逐个击破(7):checked与unchecked

    C#难点逐个击破(7):checked与unchecked checked与unchecked的作用 C#中对于数值类型的运算,当结果超出该类型所能存储的范围时,会发生溢出。而C#提供了checked和unchecked关键字来控制这种情况的处理。 checked关键字用于指示将溢出检测应用于所在作用域内的整个表达式。 unchecked关键字用于禁用溢出检…

    C# 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部