.net webapi http参数自定义绑定模型

news2025/6/8 15:42:43

.NET Web API 中 HTTP 参数自定义绑定模型的深度解析

在 .NET Web API 开发里,常规的参数绑定往往能满足大部分需求。不过,当遇到一些特殊情况时,就需要自定义将 HTTP 参数绑定到 action 特定模型参数了。接下来,我们就深入探讨如何通过实现 IModelBinder 接口来自定义模型绑定逻辑。

自定义绑定的必要性

在某些场景下,请求中的数据可能不会按照常规方式传递,或者需要对数据进行特殊处理后再绑定到模型。比如,从请求头中提取特定信息,或者对请求体中的数据进行复杂的解析。这时,自定义模型绑定就派上用场了。

实现步骤

1. 定义模型

首先,我们要定义一个模型类,用来存储从请求中获取的数据。假设我们有一个 User 模型,它有一个 ApiKey 属性,我们希望从请求头 X-API-Key 中获取这个值。

public class User
{
    public string ApiKey { get; set; }
    // 其他属性...
}

2. 创建自定义模型绑定器

接着,创建一个自定义模型绑定器,实现 IModelBinder 接口。该接口包含一个 BindModelAsync 方法,用于从请求中提取数据并绑定到模型对象。

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Threading.Tasks;

public class ApiKeyModelBinderToUser : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new System.ArgumentNullException(nameof(bindingContext));
        }

        // 获取请求头中的值
        var apiKeyValue = bindingContext.HttpContext.Request.Headers["X-API-Key"].ToString();

        // 尝试将值绑定到模型
        if (!string.IsNullOrEmpty(apiKeyValue))
        {
            var user = new User { ApiKey = apiKeyValue };
            bindingContext.Result = ModelBindingResult.Success(user);
        }
        else
        {
            bindingContext.Result = ModelBindingResult.Failed();
        }

        return Task.CompletedTask;
    }
}

在这个绑定器中,我们首先检查 bindingContext 是否为 null,然后从请求头中获取 X-API-Key 的值。如果该值不为空,就创建一个 User 实例,并将 ApiKey 属性设置为该值,最后返回绑定成功的结果。否则,返回绑定失败的结果。

3. 使用自定义模型绑定器

有几种不同的方式可以使用自定义模型绑定器。

在控制器操作方法的参数上使用
[ApiController]
[Route("[controller]")]
public class UserController : ControllerBase
{
    // 直接绑定到 User 对象
    [HttpPost]
    public IActionResult Post([ModelBinder(BinderType = typeof(ApiKeyModelBinderToUser))] User user)
    {
        return Ok(user);
    }
}

这种方式直接在控制器的方法参数上指定使用自定义绑定器,适用于只在特定方法中使用该绑定器的情况。

使用特性(推荐用法)
[ModelBinder(BinderType = typeof(ApiKeyModelBinderToUser))]
public class User
{
    // ...
}

通过在模型类上使用特性,可以让该模型在所有使用的地方都自动使用自定义绑定器,提高了代码的复用性。

添加全局模型绑定器

如果你希望自定义绑定器自动应用于所有匹配的模型类型,可以创建一个自定义的 IModelBinderProvider 并将其注册到 ASP.NET Core 的 MVC 选项中。

首先,创建自定义模型绑定器提供者:

using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.DependencyInjection;

public class CustomModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (context.Metadata.ModelType == typeof(User))
        {
            var services = context.Services;
            return new BinderTypeModelBinder(typeof(ApiKeyModelBinderToUser));
            // 或者,如果你希望直接从服务容器中解析绑定器(如果它已注册为服务):
            // return services.GetRequiredService<ApiKeyModelBinderToUser>();
        }

        return null; // 表示此提供者不提供绑定器
    }
}

然后,在 Program.cs 文件中注册自定义模型绑定器提供者:

builder.Services.AddControllers(options =>
{
    options.ModelBinderProviders.Insert(0, new CustomModelBinderProvider());
});

// 或者,如果你使用的是 MVC 控制器:
builder.Services.AddControllersWithViews(options =>
{
    options.ModelBinderProviders.Insert(0, new CustomModelBinderProvider());
});

使用 Insert(0, ...) 方法将自定义模型绑定器提供者添加到提供者列表的开头,确保它会在其他默认的提供者之前被考虑。如果你的自定义绑定器应该仅在默认提供者失败时才被考虑,可以使用 Add 方法。

注意事项

全局模型绑定器可能会影响应用程序中的所有匹配模型类型,使用时要格外小心。通常,最好通过特性来指定自定义模型绑定器,以便更精确地控制它们的应用范围。

总结

通过自定义模型绑定器,我们可以灵活地处理各种复杂的 HTTP 参数绑定需求。无论是在特定方法中使用,还是全局应用,都能让我们的 .NET Web API 开发更加高效和灵活。希望本文能帮助你更好地掌握这一技术。 ======================================================================
前些天发现了一个比较好玩的人工智能学习网站,通俗易懂,风趣幽默,可以了解了解AI基础知识,人工智能教程,不是一堆数学公式和算法的那种,用各种举例子来学习,读起来比较轻松,有兴趣可以看一下。
人工智能教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2404274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RocketMQ入门5.3.2版本(基于java、SpringBoot操作)

一、RocketMQ概述 RocketMQ是一款由阿里巴巴于2012年开源的分布式消息中间件&#xff0c;旨在提供高吞吐量、高可靠性的消息传递服务。主要特点有&#xff1a; 灵活的可扩展性 海量消息堆积能力 支持顺序消息 支持多种消息过滤方式 支持事务消息 支持回溯消费 支持延时消…

使用osqp求解简单二次规划问题

文章目录 一、问题描述二、数学推导1. 目标函数处理2. 约束条件处理 三、代码编写 一、问题描述 已知&#xff1a; m i n ( x 1 − 1 ) 2 ( x 2 − 2 ) 2 s . t . 0 ⩽ x 1 ⩽ 1.5 , 1 ⩽ x 2 ⩽ 2.5 min(x_1-1)^2(x_2-2)^2 \qquad s.t. \ \ 0 \leqslant x_1 \leqslant 1.5,…

【C语言】通用统计数据结构及其更新函数(最值、变化量、总和、平均数、方差等)

【C语言】通用统计数据结构及其更新函数&#xff08;最值、变化量、总和、平均数、方差等&#xff09; 更新以gitee为准&#xff1a; gitee 文章目录 通用统计数据结构更新函数附录&#xff1a;压缩字符串、大小端格式转换压缩字符串浮点数压缩Packed-ASCII字符串 大小端转换什…

Spring AI(10)——STUDIO传输的MCP服务端

Spring AI MCP&#xff08;模型上下文协议&#xff09;服务器Starters提供了在 Spring Boot 应用程序中设置 MCP 服务器的自动配置。它支持将 MCP 服务器功能与 Spring Boot 的自动配置系统无缝集成。 本文主要演示支持STDIO传输的MCP服务器 仅支持STDIO传输的MCP服务器 导入j…

Sklearn 机器学习 缺失值处理 填充数据列的缺失值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 💡使用 Scikit-learn 处理数据缺失值的完整指南 在机器学习项目中,数据缺失是不可避…

猜字符位置游戏-position gasses

import java.util.*;public class Main {/*字符猜位置游戏;每次提交只能被告知答对几个位置;根据提示答对的位置数推测出每个字符对应的正确位置;*/public static void main(String[] args) {char startChar A;int gameLength 8;List<String> ballList new ArrayList&…

宝塔安装配置FRP

FRP&#xff08;Fast Reverse Proxy&#xff09;作为一款高性能的反向代理应用&#xff0c;能够帮助我们轻松实现内网穿透&#xff0c;将内网服务暴露到公网&#xff0c;满足远程访问、开发调试等多种需求。宝塔面板以其简洁易用的界面和强大的功能&#xff0c;成为众多站长和开…

元器件基础学习笔记——结型场效应晶体管 (JFET)

场效应晶体管&#xff08;Field Effect Transistor&#xff0c;FET&#xff09;简称场效应管&#xff0c;是一种三端子半导体器件&#xff0c;它根据施加到其其中一个端子的电场来控制电流的流动。与双极结型晶体管 &#xff08;BJT&#xff09; 不同&#xff0c;场效应晶体管 …

tableau 实战工作场景常用函数与LOD表达式的应用详解

这是tableau实战工作场景图表制作第七期--常用函数与LOD表达式的应用 数据资源已经与这篇博客捆绑&#xff0c;有需要者可以下载通过网盘分享的文件&#xff1a;3.2-8月成交数据.xlsx等3个文件 链接: https://pan.baidu.com/s/17WtUoZTqzoNo5kTFjua4hw?pwd0623 提取码: 06…

《PyTorch:开启深度学习新世界的魔法之门》

一、遇见 PyTorch:深度学习框架新星登场 在当今的技术领域中,深度学习已然成为推动人工智能发展的核心动力,而深度学习框架则是这场技术革命中的关键工具。在众多深度学习框架里,PyTorch 以其独特的魅力和强大的功能,迅速崛起并占据了重要的地位,吸引着无数开发者和研究者…

分布式光纤传感(DAS)技术应用解析:从原理到落地场景

近年来&#xff0c;分布式光纤传感&#xff08;Distributed Acoustic Sensing&#xff0c;DAS&#xff09;技术正悄然改变着众多传统行业的感知方式。它将普通的通信光缆转化为一个长距离、连续分布的“听觉传感器”&#xff0c;对振动、声音等信号实现高精度、高灵敏度的监测。…

Spring事务回滚在系统中的应用

以文章发布为例&#xff0c;介绍Spring事务回滚在系统中的应用 事务回滚的核心概念 事务回滚是数据库管理系统中的关键机制&#xff0c;它确保数据库操作要么全部成功&#xff0c;要么全部失败。在Spring框架中&#xff0c;我们可以通过Transactional注解轻松实现事务管理。 …

ASP.NET Core使用Quartz部署到IIS资源自动被回收解决方案

iis自动回收的原因 回收机制默认配置&#xff0c;间隔时间是1740分钟&#xff0c;意思是&#xff1a;默认情况下每1740分钟(29小时)回收一次&#xff0c;定期检查应用程序池中的工作进程&#xff0c;并终止那些已经存在很长时间或已经使用了太多资源的工作进程 进程模型默认配…

调用.net DLL让CANoe自动识别串口号

1.前言 CANoe9.0用CAPL控制数控电源_canoe读取程控电源电流值-CSDN博客 之前做CAPL通过串口控制数控电源&#xff0c;存在一个缺点&#xff1a;更换电脑需要改串口号 CSDN上有类似的博客&#xff0c;不过要收费&#xff0c;本文根据VID和PID来自动获取串口号&#xff0c;代码…

算法(蓝桥杯学习C/C++版)

up: 溶金落梧桐 溶金落梧桐的个人空间-溶金落梧桐个人主页-哔哩哔哩视频 蓝桥杯三十天冲刺系列 BV18eQkY3EtP 网站&#xff1a; OI Wiki OI Wiki - OI Wiki 注意 比赛时&#xff0c;devc勾选c11&#xff08;必看&#xff09; 必须勾选c11一共有两个方法&#xff0c;任用…

Docker镜像无法拉取问题解决办法

最近再学习RabbitMQ&#xff0c;需要从Docker镜像中拉取rabbitMQ&#xff0c;但是下拉失败 总的来说就是无法和docker镜像远程仓库建立连接 我又去尝试ping docker.io发现根本没有反应&#xff0c;还是无法连接找了许多办法还是没有办法解决&#xff0c;最后才发现是镜像问题&a…

ZephyrOS 嵌入式开发Black Pill V1.2之Debug调试器

版本和环境信息如下&#xff1a; PC平台&#xff1a; Windows 11 专业版 Zephyr开发环境&#xff1a;v4.1.0 Windows 下搭建 Zephyr 开发环境 WeAct BlackPill V1.2开发板&#xff1a; WeAct STM32F411CEU6 BlackPill 核心板 Debug调试器&#xff1a; ST-LINK V2: ST-LINK V2 S…

服务器磁盘空间被Docker容器日志占满处理方法

事发场景&#xff1a; 原本正常的服务停止运行了&#xff0c;查看时MQTT服务链接失败&#xff0c;查看对应的容器服务发现是EMQX镜像停止运行了&#xff0c;重启也是也报错无法正常运行&#xff0c;报错如下图&#xff1a; 报错日志中连续出现两个"no space left on devi…

c++学习-this指针

1.基本概念 非静态成员函数都会默认传递this指针&#xff08;静态成员函数属于类本身&#xff0c;不属于某个实例对象&#xff09;&#xff0c;方便访问对象对类成员变量和 成员函数。 2.基本使用 编译器实际处理类成员函数&#xff0c;this是第一个隐藏的参数&#xff0c;类…

交易所系统攻坚:高并发撮合引擎与合规化金融架构设计

交易所系统攻坚&#xff1a;高并发撮合引擎与合规化金融架构设计 ——2025年数字资产交易平台的性能与合规双轮驱动 一、高并发撮合引擎&#xff1a;从微秒级延迟到百万TPS 核心架构设计 订单簿优化&#xff1a;数据结构创新&#xff1a;基于红黑树与链表混合存储&#xff0c…