ASP.NET Core中数据绑定的Attribute

概要

ASP.NET Core的Web API在调用过程中,经常涉及到Client端参数传递和Server端参数的接收的问题。其中参数主要包括URL参数,表单参数和路由参数等,如何处理好各种类型的参数传递,尤其是复杂类型参数的处理,是正确调用Web API的关键也是难点。

本文通过介绍FromQueryAttribute,FromRouteAttribute和FromBodyAttribute三个Attribute,来介绍如果在URL,表单和路由中传递对复杂的对象参数。

定义

FromQueryAttribute: 通过调用WebAPI的URL参数绑定Action参数数据。
FromRouteAttribute: 通过调用WebAPI的URL的路由参数绑定Action参数数据。
FromBodyAttribute:通过Web请求中的body段数据绑定Action参数数据,一个Action方法,只能使用一次FromBodyAttribute属性。

代码验证

我们通过一个获取足球明星信息的Web API来验证上述定义,包含单一的参数使用模式和混合参数的使用模式。

具体Player类代码如下,Web API完整代码请参考附录。

public class Player
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Number { get; set; }
}

FromQueryAttribute

Server直接通过URL参数实例化对象。

[HttpGet]
[Route(nameof(playerGetByURL))]
public Player playerGetByURL([FromQuery]Player player)
{
   return player;
}
  1. Action方法playerGetByURL中包含一个Player类型的参数,包含Id,Name和出场号码。
  2. URL https://localhost:5001/players/playerGetByURL?id=1&name=Zidane&number=5在PostMan中调用。
    ASP.NET Core中数据绑定的Attribute_第1张图片
  3. URL中的参数被Server直接实例化成了Player对象。

FromRouteAttribute

Server直接通过路由参数实例化对象。

[HttpGet]
[Route(nameof(playerGetByRoute) + "/{id}/{name}/{number}")]
public Player playerGetByRoute([FromRoute] Player player)
{
   return player;
}
  1. Action方法playerGetByRoute中包含一个Player类型的参数,包含Id,Name和出场号码。
  2. URL https://localhost:5001/players/playerGetByRoute/1/Inzaghi/9在PostMan中调用。
    ASP.NET Core中数据绑定的Attribute_第2张图片
  3. 路由中的参数被Server直接实例化成了Player对象。

FromBodyAttribute

Server直接通过请求的body段数据创建Player对象。

[HttpPost(nameof(playerGetByBody))]
public Player playerGetByBody([FromBody]Player player)
{
   return player;
}
  1. Action方法playerGetByBody中包含一个Player类型的参数,包含Id,Name和出场号码。
  2. URL https://localhost:5001/players/playerGetByBody在PostMan中调用。Body段的JSON数据为:
    {
    “id”: 12,
    “name”: “Sheva”,
    “number”: 7
    }

ASP.NET Core中数据绑定的Attribute_第3张图片
3. Body内容被Server直接实例化成了Player对象。

FromQueryAttribute + FromBodyAttribute

Server直接通过请求的body段数据和URL参数创建两个Player对象

 [HttpPost(nameof(playerGetByBodyURL))]
 public IEnumerable<Player> playerGetByBodyURL([FromBody]Player player1, [FromQuery]Player player2)
 {
     return new List<Player>(){
         player1,player2
     };
  }
  1. Action方法playerGetByBodyURL中包含两个Player类型的参数,一个来自请求的Body段,另一个来自URL参数。
  2. URL https://localhost:5001/players/playerGetByBodyURL?id=1&name=Zidane&number=5 在PostMan中调用。Body段的JSON数据为:
    {
    “id”: 12,
    “name”: “Sheva”,
    “number”: 7
    }
    ASP.NET Core中数据绑定的Attribute_第4张图片
  3. Body内容和URL中的参数被Server直接实例化成了Player对象。

FromQueryAttribute + FromRouteAttribute

Server直接通过路由和URL参数创建两个Player对象

  [HttpGet(nameof(playerGetByURLRoute) +  "/{id}/{name}/{number}")]
public IEnumerable<Player> playerGetByURLRoute([FromQuery]Player player1,  [FromRoute]Player player2)
        {
           return new List<Player>(){
               player1,player2
           };
        }
  1. Action方法playerGetByURLRoute中包含两个Player类型的参数,一个来自URL参数,另一个来自路由参数。
  2. URL https://localhost:5001/players/playerGetByURLRoute/1/Inzaghi/9?id=1&name=Zidane&number=5在PostMan中调用。

FromRouteAttribute+ FromBodyAttribute

Server直接通过Request的body段数据和路由参数创建两个Player对象

[HttpPost(nameof(playerGetByBodyRoute) + "/{id}/{name}/{number}")]
public IEnumerable<Player> playerGetByBodyRoute([FromBody]Player player1, [FromRoute]Player player2)
{
   return new List<Player>(){
       player1,player2
   };
}
  1. Action方法playerGetByBodyRoute中包含两个Player类型的参数,一个来自请求的Body段,另一个来自URL参数。
  2. URL https://localhost:5001/players/playerGetByBodyRoute/1/Inzaghi/9 在PostMan中调用。Body段的JSON数据为:
    {
    “id”: 12,
    “name”: “Sheva”,
    “number”: 7
    }
    ASP.NET Core中数据绑定的Attribute_第5张图片
  3. Body内容和路由中的参数被Server直接实例化成了Player对象。

FromRouteAttribute+ FromBodyAttribute + FromQueryAttribute

Server直接通过Web请求的body段数据,路由参数和URL参数创建三个Player对象

 [HttpPost(nameof(playerGetByBodyRouteURL) + "/{id}/{name}/{number}")]
public IEnumerable<Player> playerGetByBodyRouteURL([FromBody]Player player1, [FromRoute]Player player2, [FromQuery]Player player3)
{
    return new List<Player>(){
        player1, player2, player3
    };
 }
  1. Action方法playerGetByBodyRouteURL中包含三个Player类型的参数,一个来自请求的Body段,一个来自路由参数,一个来自URL参数。
  2. URL https://localhost:5001/players/playerGetByBodyRouteURL/1/Inzaghi/9?id=1&name=Zidane&number=5,在PostMan中调用。 Body段的JSON数据为:
    {
    “id”: 12,
    “name”: “Sheva”,
    “number”: 7
    }

ASP.NET Core中数据绑定的Attribute_第6张图片
ASP.NET Core中数据绑定的Attribute_第7张图片

结论

FromQueryAttribute,FromRouteAttribute和FromBodyAttribute让Action中参数绑定的方式变得非常清晰。建议大家在开发中,采用这种显示指定的方式来处理代码,这样会让代码更便于管理。

附录

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using football.Models;
namespace football.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class PlayersController : ControllerBase
    {
       
        private readonly ILogger<PlayersController> _logger;

        public PlayersController(ILogger<PlayersController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        [Route(nameof(playerGetByURL))]
        public Player playerGetByURL([FromQuery]Player player)
        {
           return player;
        }

        [HttpGet]
        [Route(nameof(playerGetByRoute) + "/{id}/{name}/{number}")]
        public Player playerGetByRoute([FromRoute] Player player)
        {
           return player;
        }
        [HttpPost(nameof(playerGetByBody))]
        public Player playerGetByBody([FromBody]Player player)
        {
           return player;
        }

        [HttpPost(nameof(playerGetByBodyURL))]
        public IEnumerable<Player> playerGetByBodyURL([FromBody]Player player1, [FromQuery]Player player2)
        {
           return new List<Player>(){
               player1,player2
           };
        }

        [HttpPost(nameof(playerGetByBodyRoute) + "/{id}/{name}/{number}")]
        public IEnumerable<Player> playerGetByBodyRoute([FromBody]Player player1, [FromRoute]Player player2)
        {
           return new List<Player>(){
               player1,player2
           };
        }

        [HttpGet(nameof(playerGetByURLRoute) +  "/{id}/{name}/{number}")]
        public IEnumerable<Player> playerGetByURLRoute([FromQuery]Player player1,  [FromRoute]Player player2)
        {
           return new List<Player>(){
               player1,player2
           };
        }

        [HttpPost(nameof(playerGetByBodyRouteURL) + "/{id}/{name}/{number}")]
        public IEnumerable<Player> playerGetByBodyRouteURL([FromBody]Player player1, [FromRoute]Player player2, [FromQuery]Player player3)
        {
           return new List<Player>(){
               player1, player2, player3
           };
        }

    }
}

你可能感兴趣的:(ASP.NET,Core,.Net,Core,.Net,.netcore,microsoft)