以 C# WebApi Get 请求方式传递实体参数

举报
Rolle 发表于 2024/10/31 22:39:01 2024/10/31
【摘要】 在 C# 开发中,Web API 是构建基于 HTTP 协议的服务的重要工具。通常,我们会使用 GET 请求来从服务器获取数据。在大多数情况下,GET 请求传递简单参数(例如字符串或整数)就足够了。但是,有时我们需要传递更复杂的数据,例如一个包含多个字段的实体参数。这种情况下,如何优雅地通过 GET 请求传递实体参数呢?本文将详细探讨这一问题,并提供相应的解决方案。GET 请求与实体参数HT...

在 C# 开发中,Web API 是构建基于 HTTP 协议的服务的重要工具。通常,我们会使用 GET 请求来从服务器获取数据。在大多数情况下,GET 请求传递简单参数(例如字符串或整数)就足够了。但是,有时我们需要传递更复杂的数据,例如一个包含多个字段的实体参数。这种情况下,如何优雅地通过 GET 请求传递实体参数呢?本文将详细探讨这一问题,并提供相应的解决方案。

GET 请求与实体参数
HTTP GET 请求的主要目的是从服务器获取资源。根据 RESTful 风格的 API 设计,GET 请求通常不应包含主体数据(body),而应通过 URL 参数传递数据。然而,URL 参数通常用于传递简单的数据类型,如整数、字符串等,对于复杂的实体参数,处理起来会比较麻烦。我们可以通过将实体参数的各个字段作为 URL 参数来实现这种需求。

具体实现
创建 Web API 项目
首先,我们需要创建一个新的 Web API 项目。假设你已经安装了 Visual Studio,可以按照以下步骤创建一个新的 Web API 项目:

打开 Visual Studio,选择“创建新项目”。
选择“ASP.NET Core Web 应用程序”模板,点击“下一步”。
命名你的项目并选择存储位置,点击“创建”。
在“创建新 ASP.NET Core Web 应用程序”窗口中,选择“API”模板,点击“创建”。
项目创建完成后,我们将在该项目中添加一个控制器和一个包含实体参数的 GET 请求方法。

定义实体类
首先,我们定义一个简单的实体类 Person,包含姓名、年龄和地址字段。
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
创建控制器
接下来,我们创建一个新的控制器 PersonController,其中包含一个 GET 请求方法,该方法接受 Person 类的各个字段作为 URL 参数。
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route(“api/[controller]”)]
public class PersonController : ControllerBase
{
[HttpGet]
public IActionResult GetPerson([FromQuery] string name, [FromQuery] int age, [FromQuery] string address)
{
Person person = new Person
{
Name = name,
Age = age,
Address = address
};

    return Ok(person);
}

}
在上面的代码中,[FromQuery] 特性指示 ASP.NET Core 从 URL 查询字符串中绑定参数值。这种方式适用于参数较少的情况。如果实体类有很多属性,手动将所有属性作为 URL 参数传递会显得繁琐而且容易出错。

改进实现
使用自定义模型绑定
为了解决上述问题,我们可以创建一个自定义模型绑定器,将 URL 查询字符串绑定到一个复杂的对象上。首先,我们创建一个自定义模型绑定器 PersonModelBinder。
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System;
using System.Threading.Tasks;

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

    var name = bindingContext.ValueProvider.GetValue("name").FirstValue;
    var age = bindingContext.ValueProvider.GetValue("age").FirstValue;
    var address = bindingContext.ValueProvider.GetValue("address").FirstValue;

    if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(age) || string.IsNullOrEmpty(address))
    {
        bindingContext.Result = ModelBindingResult.Failed();
        return Task.CompletedTask;
    }

    var person = new Person
    {
        Name = name,
        Age = int.Parse(age),
        Address = address
    };

    bindingContext.Result = ModelBindingResult.Success(person);
    return Task.CompletedTask;
}

}
然后,我们需要创建一个自定义模型绑定器提供程序 PersonModelBinderProvider。
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using System;

public class PersonModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

    if (context.Metadata.ModelType == typeof(Person))
    {
        return new BinderTypeModelBinder(typeof(PersonModelBinder));
    }

    return null;
}

}
最后,我们需要在 Startup.cs 中注册自定义模型绑定器提供程序。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.ModelBinderProviders.Insert(0, new PersonModelBinderProvider());
});
}
现在,我们可以修改 PersonController,让其接受 Person 实体参数。
[HttpGet]
public IActionResult GetPerson([ModelBinder(BinderType = typeof(PersonModelBinder))] Person person)
{
return Ok(person);
}
测试
我们可以通过以下 URL 测试上述实现:
https://localhost:5001/api/person?name=John&age=30&address=123+Main+St
如果一切正常,响应将会是:
{
“name”: “John”,
“age”: 30,
“address”: “123 Main St”
}

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。