ASP.NET Core Web API 参数传递方式

news2025/4/6 16:31:56

文章目录

  • 前言
  • 一、参数传递方式
    • 路由参数(Route Parameters)
    • 查询字符串参数(Query String Parameters)
    • 请求体参数(Request Body)
    • 表单数据(Form Data)
    • 请求头参数(Header Parameters)
    • 服务注入(Service Injection)
  • 二、高级用法与技巧
    • 混合参数来源
    • 模型绑定(自动绑定)
    • 自定义模型绑定
  • 三、验证与安全性
    • 数据注解验证
    • 敏感参数处理
    • 文件上传安全
  • 四、最佳实践
    • 遵循RESTful设计:
    • 明确参数来源:
    • 性能优化:
    • 版本控制:
    • 文档化:
  • 五、常见问题
    • 参数绑定失败如何处理?
    • 如何接收动态参数(如未知的查询键值对)?
    • 如何处理数组参数?
    • 如果参数和上面不一样需要用到FromRoute: [FromRoute(Name= "XXX")]
  • 总结


前言

在ASP.NET Core Web API中,参数传递方式多样且灵活,合理选择传递方式对API设计和性能优化至关重要。

一、参数传递方式

路由参数(Route Parameters)

  1. 用途:标识资源路径中的核心参数(如ID、分类名)。
  2. 绑定特性[FromRoute]
  3. 示例
    [HttpGet("products/{id}")]
    public IActionResult GetProduct([FromRoute] int id) 
    {
        // 通过路径如 /api/products/5 获取id=5
    }
    

查询字符串参数(Query String Parameters)

  1. 用途:用于过滤、分页、排序等可选操作。
  2. 绑定特性[FromQuery]
  3. 示例
    [HttpGet("products")]
    public IActionResult Search([FromQuery] string keyword, [FromQuery] int page = 1) 
    {
        // 请求示例:/api/products?keyword=apple&page=2
    }
    

请求体参数(Request Body)

  1. 用途:传递复杂数据结构(如JSON对象),常用于POST/PUT请求。
  2. 绑定特性[FromBody]
  3. 示例
    [HttpPost("products")]
    public IActionResult CreateProduct([FromBody] ProductDto product) 
    {
        // 请求体为JSON:{ "Name": "Phone", "Price": 999 }
    }
    

表单数据(Form Data)

  1. 用途:处理multipart/form-dataapplication/x-www-form-urlencoded格式(如文件上传)。
  2. 绑定特性[FromForm]
  3. 示例
    [HttpPost("upload")]
    public IActionResult UploadFile([FromForm] IFormFile file, [FromForm] string description) 
    {
        // 通过表单提交文件和描述字段
    }
    

请求头参数(Header Parameters)

  1. 用途:传递元数据(如认证令牌客户端信息)。
  2. 绑定特性[FromHeader]
  3. 示例
    [HttpGet("user")]
    public IActionResult GetUser([FromHeader(Name = "Authorization")] string authToken) 
    {
        // 从请求头获取Authorization值
    }
    

服务注入(Service Injection)

  1. 用途:直接注入依赖的服务(如数据库上下文、日志服务)。
  2. 绑定特性[FromServices]
  3. 示例
    [HttpGet("logs")]
    public IActionResult GetLogs([FromServices] ILogger<MyController> logger) 
    {
        logger.LogInformation("Fetching logs...");
        // ...
    }
    

二、高级用法与技巧

混合参数来源

  1. 场景:同时使用路由查询字符串请求体
  2. 示例:
    [HttpPut("products/{id}")]
    public IActionResult UpdateProduct(
        [FromRoute] int id,
        [FromQuery] bool forceUpdate,
        [FromBody] ProductDto product
    ) 
    {
        // 请求示例:PUT /api/products/5?forceUpdate=true
        // Body: { "Name": "New Name" }
    }
    

模型绑定(自动绑定)

  1. 说明:ASP.NET Core自动根据参数名和类型绑定数据,无需显式标注**[From*]**。
  2. 示例
    [HttpGet("products")]
    public IActionResult Get(int page, int pageSize) 
    {
        // 自动从查询字符串绑定:/api/products?page=2&pageSize=20
    }
    

自定义模型绑定

  1. 场景:处理特殊格式的输入(如自定义日期格式)。
  2. 实现:继承IModelBinder接口。
  3. 示例
    public class CustomDateBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext context)
        {
            var value = context.ValueProvider.GetValue("customDate").FirstValue;
            // 解析自定义日期格式...
        }
    }
    
    [HttpGet("events")]
    public IActionResult GetEvents([ModelBinder(typeof(CustomDateBinder))] DateTime date) 
    {
        // 使用自定义日期绑定逻辑
    }
    

三、验证与安全性

数据注解验证

  1. 用途:通过DataAnnotations验证参数合法性。
  2. 示例
    public class ProductDto
    {
        [Required]
        [StringLength(100)]
        public string Name { get; set; }
    
        [Range(0, 10000)]
        public decimal Price { get; set; }
    }
    
    [HttpPost("products")]
    public IActionResult CreateProduct([FromBody] ProductDto product) 
    {
        if (!ModelState.IsValid) 
        {
            return BadRequest(ModelState);
        }
        // ...
    }
    

敏感参数处理

  1. 建议:避免通过URL传递敏感信息(如密码),改用请求体或Headers
  2. 错误示例
    // 不推荐:密码暴露在URL中
    [HttpGet("login")]
    public IActionResult Login([FromQuery] string username, [FromQuery] string password) 
    {
        // ...
    }
    

文件上传安全

  1. 建议:限制文件类型和大小
  2. 示例
    [HttpPost("upload")]
    public async Task<IActionResult> Upload([FromForm] IFormFile file)
    {
        if (file.Length > 5 * 1024 * 1024) 
        {
            return BadRequest("文件大小不能超过5MB");
        }
        // ...
    }
    

四、最佳实践

遵循RESTful设计:

  1. GET:使用路由和查询参数。
  2. POST/PUT:使用请求体传递复杂数据。

明确参数来源:

  1. 显式使用[FromRoute]、[FromQuery]等特性,避免歧义。

性能优化:

  1. 避免在GET请求中使用请求体(不符合HTTP规范)。
  2. 大文件上传使用IFormFile,而非Base64编码。

版本控制:

  1. 通过路由或查询参数实现API版本管理:
    [Route("api/v1/[controller]")]
    public class ProductsV1Controller : ControllerBase { /*...*/ }
    

文档化:

  1. 使用Swagger/OpenAPI生成文档,明确参数类型和用途
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
    });
    
    app.UseSwagger();
    app.UseSwaggerUI();
    
    

五、常见问题

参数绑定失败如何处理?

  1. 方案:检查模型绑定错误,返回详细错误信息:
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    

如何接收动态参数(如未知的查询键值对)?

  1. 方案:使用Dictionary<string, string>动态类型
    [HttpGet("search")]
    public IActionResult Search([FromQuery] Dictionary<string, string> filters) 
    {
        // 处理动态过滤条件
    }
    

如何处理数组参数?

  1. 示例:通过查询字符串传递数组:
    // 请求:/api/products?categories=books&categories=electronics
    [HttpGet("products")]
    public IActionResult GetProducts([FromQuery] List<string> categories) 
    {
        // categories = ["books", "electronics"]
    }
    

如果参数和上面不一样需要用到FromRoute: [FromRoute(Name= “XXX”)]

  1. 示例
    [HttpGet("{age}/{address}")]
    public ActionResult<Person> GetPersonByAgeAndAddress(int age, string address)
    //如果参数和上面不一样需要用到FromRoute: [FromRoute(Name= "address")]string addre
    //public ActionResult<Person> GetPersonByAgeAndAddress(int age,[FromRoute(Name= "address")]string addre)
    {
        List<Person> plist = new List<Person> {
            new Person ("张三", 32, "湖北"),
            new Person ("李四", 29, "湖南")
        };
    
        var person = plist.SingleOrDefault(a => a.Age == age&&a.Address== address);
        if (person == null)
        {
            return NotFound("无此人员的数据信息");
        }
        else
        {
            return person;
        }
    }
    

总结

通过合理选择参数传递方式,结合验证和安全性措施,可以构建高效、安全且易维护的Web API。

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

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

相关文章

04.游戏开发-unity编辑器详细-工具栏、菜单栏、工作识图详解

04.游戏开发&#xff0c;unity编辑器详细-工具栏、菜单栏、工作识图详解 提示&#xff1a;帮帮志会陆续更新非常多的IT技术知识&#xff0c;希望分享的内容对您有用。本章分享的是Python基础语法。前后每一小节的内容是存在的有&#xff1a;学习and理解的关联性&#xff0c;希…

QGIS中第三方POI坐标偏移的快速校正-百度POI

1.百度POI&#xff1a; name,lng,lat,address 龙记黄焖鸡米饭(共享区店),121.908315,30.886636,南汇新城镇沪城环路699弄117号(A1区110室) 好福记黄焖鸡(御桥路店),121.571409,31.162292,沪南路2419弄26号1层B间 御品黄焖鸡米饭(安亭店),121.160322,31.305977,安亭镇新源路792号…

Pycharm 启动时候一直扫描索引/更新索引 Update index/Scanning files to index

多个项目共用一个虚拟环境&#xff0c;有助于加快PyCharm 启动吗 chatgpt 4o认为很有帮助&#xff0c;gemini 2.5pro认为没鸟用&#xff0c;我更认可gemini的观点。不知道他们谁在一本正经胡说八道。 -------- 打开pycharm的时候&#xff0c;下方的进度条一直显示在扫描文件…

Vanna:用检索增强生成(RAG)技术革新自然语言转SQL

引言&#xff1a;为什么我们需要更智能的SQL生成&#xff1f; 在数据驱动的业务环境中&#xff0c;SQL 仍然是数据分析的核心工具。然而&#xff0c;编写正确的 SQL 查询需要专业知识&#xff0c;而大型语言模型&#xff08;LLM&#xff09;直接生成的 SQL 往往存在**幻觉&…

CKPT文件是什么?

检查点&#xff08;Checkpoint&#xff0c;简称ckpt&#xff09;是一种用于记录系统状态或数据变化的技术&#xff0c;广泛应用于数据库管理、机器学习模型训练、并行计算以及网络安全等领域。以下将详细介绍不同领域中ckpt检查点的定义、功能和应用场景。 数据库中的ckpt检查点…

Android使用OpenGL和MediaCodec录制

目录 一,什么是opengl 二,什么是Android OpenGL ES 三, OpenGL 绘制流程 四, OpenGL坐标系 五, OpenGL 着色器 六, GLSL编程语言 七,使用MediaCodec录制在Opengl中渲染架构 八,代码实现 8.1 自定义渲染view继承GLSurfaceView 8.2 自定义渲染器TigerRender 8.3 创建编…

《如何避免虚无》速读笔记

文章目录 书籍信息概览躺派&#xff08;出世&#xff09;卷派&#xff08;入世&#xff09;虚无篇&#xff1a;直面虚无自我篇&#xff1a;认识自我孤独篇&#xff1a;应对孤独幸福篇&#xff1a;追寻幸福超越篇&#xff1a;超越自我 书籍信息 书名&#xff1a;《如何避免虚无…

哈尔滨工业大学:大模型时代的具身智能

大家好&#xff0c;我是樱木。 机器人在工业领域&#xff0c;已经逐渐成熟。具身容易&#xff0c;智能难。 机器人-》智能机器人&#xff0c;需要自主能力&#xff0c;加上通用能力。 智能机器人-》人类&#xff0c;这个阶段就太有想象空间了。而最受关注的-类人机器人。 如何…

理解OSPF 特殊区域NSSA和各类LSA特点

本文基于上文 理解OSPF Stub区域和各类LSA特点 在理解了Stub区域之后&#xff0c;我们再来理解一下NSSA区域&#xff0c;NSSA区域用于需要引入少量外部路由&#xff0c;同时又需要保持Stub区域特性的情况 一、 网络总拓扑图 我们在R1上配置黑洞路由&#xff0c;来模拟NSSA区域…

如何通过优化HMI设计大幅提升产品竞争力?

一、HMI设计的重要性与竞争力提升 HMI&#xff08;人机交互界面&#xff09;设计在现代产品开发中扮演着至关重要的角色。良好的HMI设计不仅能够提升用户体验&#xff0c;还能显著增强产品的竞争力。在功能趋同的市场环境中&#xff0c;用户体验成为产品竞争的关键。HMI设计通…

Linux信号——信号的处理(3)

信号是什么时候被处理&#xff1f; 进程从内核态&#xff0c;切换到用户态的时候&#xff0c;信号会被检测处理。 内核态&#xff1a;操作系统的状态&#xff0c;权限级别高 用户态&#xff1a;你自己的状态 内核态和用户态 进程地址空间第三次 所谓的系统调用本质其实是一堆…

Pod的调度

在默认情况下&#xff0c;一个Pod在哪个Node节点上运行&#xff0c;是由Scheduler组件采用相应的算法计算出来的&#xff0c;这个过程是不受人工控制的。但是在实际使用中&#xff0c;这并不满足的需求&#xff0c;因为很多情况下&#xff0c;我们想控制某些Pod到达某些节点上&…

LabVIEW面向对象编程设计方法

一、概述 面向对象编程&#xff08;OOP&#xff09;在软件开发中占据重要地位&#xff0c;尤其是在大规模软件项目中。它与小型程序开发思路不同&#xff0c;更注重未来功能的升级与扩展。在设计阶段&#xff0c;需思考如何构建既灵活又稳定的系统&#xff0c;这涉及众多设计方…

Dify票据识别遇到的分支判断不准确问题

已测试这篇文章中 https://zhuanlan.zhihu.com/p/5465385787 使用多分支条件判断使用不同的大模型识别图片内容 发现了细节问题。在使用时若不注意&#xff0c;分支会出现走向不准的问题。 需要关注部分 下方红框处。1&#xff0c;2后不能跟点。否则会出问。除此之外&#xff0…

《全栈+双客户端Turnkey方案》架构设计图

今天分享一些全栈双客户端Turnkey方案的架构与结构图。 1&#xff1a;三种分布式部署方案:网关方案&#xff0c;超级服务器单服方案&#xff0c;直连逻辑服方案 2: 单服多线程核心架构: 系统服务逻辑服服务 3: 系统服务的多线程池调度设计 4:LogicServer Update与ECS架构&…

某碰瓷国赛美赛,号称第三赛事的数模竞赛

首先我非常不能理解的就是怎么好意思自称第三赛事的呢&#xff1f;下面我们进行一个简单讨论&#xff0c;当然这里不对国赛和美赛进行讨论。首先我们来明确一点&#xff0c;比赛的含金量由什么来定&#xff1f;这个可能大家的评价指标可能不唯一&#xff0c;我通过DeepSeek选取…

【大模型深度学习】如何估算大模型需要的显存

一、模型参数量 参数量的单位 参数量指的是模型中所有权重和偏置的数量总和。在大模型中&#xff0c;参数量的单位通常以“百万”&#xff08;M&#xff09;或“亿”&#xff08;B&#xff0c;也常说十亿&#xff09;来表示。 百万&#xff08;M&#xff09;&#xff1a;表示…

Mysql 数据库编程技术01

一、数据库基础 1.1 认识数据库 为什么学习数据库 瞬时数据&#xff1a;比如内存中的数据&#xff0c;是不能永久保存的。持久化数据&#xff1a;比如持久化至数据库中或者文档中&#xff0c;能够长久保存。 数据库是“按照数据结构来组织、存储和管理数据的仓库”。是一个长…

Mysql慢查询设置 和 建立索引

1 .mysql慢查询的设置 slow_query_log ON //或 slow_query_log_file /usr/local/mysql/data/slow.log long_query_time 2 修改后重启动mysql 1.1 查看设置后的参数 mysql> show variables like slow_query%; --------------------------------------------------…

【Android】界面布局-相对布局RelativeLayout-例子

题目 完成下面相对布局&#xff0c;要求&#xff1a; 中间的button在整个屏幕的中央&#xff0c;其他的以它为基准排列。Hints&#xff1a;利用layout_toEndof,_toRightof,_toLeftof,_toStartof完成。 结果演示 代码实现 <?xml version"1.0" encoding"u…