ASP.NET Core 响应location

本文涉及的产品
实时计算 Flink 版,1000CU*H 3个月
实时数仓Hologres,5000CU*H 100GB 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
简介: 响应中 location 的设置示例:发送POST 请求,进行创建资源的操作。注意的请求头中content-type 的设置,需要设置成 application/json 类型,并不一定需要json 类型的数据,但默认情况下使用的都是json传输数据,否则asp.net core 会返回 415 状态码。同时请求体中 也要符合api 接口需要的格式,如果不符合,则会得到 400 的响应码。...

响应中 location 的设置

示例:
发送POST 请求,进行创建资源的操作。
image.png

注意的请求头中content-type 的设置,需要设置成 application/json 类型,并不一定需要json 类型的数据,但默认情况下使用的都是json传输数据,否则asp.net core 会返回 415 状态码。
同时请求体中 也要符合api 接口需要的格式,如果不符合,则会得到 400 的响应码。

image.png

在响应头中 包含 location 信息, 标识的新创建的资源的所在。

使用 代码示例:

        // 这里使用 Name 属性为Action赋值,用于标识,一般跟Action方法名同称
        [HttpGet(template:"{CompanyId}", Name = nameof(GetCompany))]
        public async Task<IActionResult> GetCompany(Guid companyId)
        {
   
   
            var company = await _companyRepository.GetCompanyAsync(companyId);
            if (company == null)
            {
   
   
                return NotFound();
            }
            return Ok(_mapper.Map<CompanyDTO>(company));
        }
        // 创建资源的Action
        [HttpPost]
        public async Task<ActionResult<CompanyDTO>> CreateCompany([FromBody] CompanyAddDto company)
        {
   
   
            var entity = _mapper.Map<Company>(company);
            _companyRepository.AddCompany(entity);
            await _companyRepository.SaveAsync();

            var returnDto = _mapper.Map<CompanyDTO>(entity);
            // CreateRoute 方法 通过传递Action名称,以及一个匿名类 用于拼接完成的url,最后一个响应体的信息
            // 该 方法就会在响应头中添加上 location 信息,数值 则是 传递的Action 的访问路径 加上 匿名类设置的属性值,凭借成完整的url返回
            return CreatedAtRoute(nameof(GetCompany), new {
   
    companyId = returnDto.Id}, returnDto);
        }

ASP.NET Core 自定义模型绑定 modelbinder

在复杂的业务逻辑场景下,asp.net core 默认的模型绑定满足不了需要,需要自定义modelbinder

    // 需要实现 IModelBinder 接口
    public class ArrayModelBinder : IModelBinder
    {
   
       
        // 实现 BindModelAsync 方法
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
   
   
            // 验证传递进来的模型元数据是否是 Enumerable 的类型
            // 不是则返回失败
            if (!bindingContext.ModelMetadata.IsEnumerableType)
            {
   
   
                bindingContext.Result = ModelBindingResult.Failed();
                return Task.CompletedTask;
            }
            // 验证传递进来的模型元数据是否是空数据
            // 将模型中的数据转换成 String 类型
            var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).ToString();
            // 验证数据是否是null,或空白字符串
            if (String.IsNullOrWhiteSpace(value))
            {
   
   
                bindingContext.Result = ModelBindingResult.Success(null);
                return Task.CompletedTask;
            }
            // 获取到模型的数据的具体类型
            var elementType = bindingContext.ModelType.GenericTypeArguments[0];
            // 获取一个转换器,将类型转换成指定类型的转换器
            var converter = TypeDescriptor.GetConverter(elementType);
            // 将模型的数据转换成的String 数据按,分割,通时使用转换器将String数据转换成 转换器指定的类型 的类型数据
            var values = value.Split(new[] {
   
    "," }, StringSplitOptions.RemoveEmptyEntries).Select(x => converter.ConvertFromString(x.Trim())).ToArray();
            // 创建一个指定类型和长度的数组,数组的元素的数值是指定类型的默认值
            var typeValues = Array.CreateInstance(elementType, values.Length);
            // 将转换后的数据复制给新建的数组
            values.CopyTo(typeValues, 0);
            // 将放置转换后的数据的数组赋值给model
            bindingContext.Model = typeValues;
            // 操作成功
            bindingContext.Result = ModelBindingResult.Success(typeValues);
            return Task.CompletedTask;
        }
    }

上面的代码是将 用户传递的 类似 1,2,3,4 这样的字符串,通过模型绑定,转换成 IEnumable 类型的数据。

HTTP Options 方法

1、获取服务器支持的HTTP请求方法;
2、用来检查服务器的性能。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。
在 跨域时 CORS 中,使用很多。

Data Annotations 数据验证

asp.net core 内置提供的数据验证方式。
在 System.ComponmentModel.DataAnnotations 命名空间下通过的各种 Attribute,供于使用。
在这里插入图片描述

IValidatableObject 接口实现 数据验证

通过实现 IValidatableObject 接口 可以实现更为复杂的数据验证,可以对 数据模型类进行验证,跨属性的验证等。
使用:

    // 与上面的Data Annotations位于同一命名空间下。
    public class EmployeeAdd : IValidatableObject
    {
   
   
        [Display(Name = "员工号"), Required(ErrorMessage = "{0}是必填项"), StringLength(10, MinimumLength = 10, ErrorMessage = "{0}的长度是{1}")]
        public String EmployeeNo {
   
    get; set; }
        [Display(Name = "名"), Required(ErrorMessage = "{0}是必填项"), MaxLength(50, ErrorMessage = "{0}的最大长度不超过{1}")]
        public String FirstName {
   
    get; set; }
        [Display(Name = "姓"), Required(ErrorMessage = "{0}是必填项"), MaxLength(50, ErrorMessage = "{0}的最大长度不超过{1}")]
        public String LastName {
   
    get; set; }
        [Display(Name = "性别")]
        public Gender Gender {
   
    get; set; }
        [Display(Name = "出生日期")]
        public DateTime DateOfBirth {
   
    get; set; }
        // 实现接口,实现方法,在方法中对类进行更复杂的验证
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
   
   
            if (FirstName == LastName)
            {
   
   
                yield return new ValidationResult(errorMessage: "姓和名不能一致!", memberNames: new[] {
   
    nameof(FirstName), nameof(LastName)});
            }
        }
    }

自定义Attribute 数据验证

使用自定义 Attribute 也可以完成复杂的数据验证。
通过继承 ValidationAttribute 类,并重写 IsValid 方法来自定义 Attribute。
使用

    // 继承 System.ComponmentModel.DataAnnotations 命名空间下的 ValidationAttribute类
    public class EmployeeNoMustFromFirstNameAttribute : ValidationAttribute
    {
   
   
        // 重写 IsValid 方法
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
   
   
            // 这里可以完成复杂的验证,
            // object value 是 当该attribute 使用在属性上时 可以通过该参数获取到具体的该属性数据
            // ValidationContext validationContext 当使用在 类上时,可以通过该参数获取到模型类数据
            var addDto = (EmployeeAddDto)validationContext.ObjectInstance;
            if (addDto.EmployeeNo == addDto.FirstName)
            {
   
   
                return new ValidationResult(errorMessage: "名称与编号不能一致", memberNames: new[] {
   
    nameof(EmployeeAddDto) });
            }
            return base.IsValid(value, validationContext);
        }

    }

注意:
一般情况下,asp.net core 内置的data annotations 验证的优先级比较好(可以简单的这样认为),当data annotation 验证报错时则后面的IValidatableObject 接口和自定义 Attribute 则不会在进行验证,这就是一个优先级的问题,而IValidatableObject 接口验证 和 自定义Attribute 的优先级基本一致。

目录
相关文章
|
10月前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
229 5
|
11月前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
211 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
10月前
|
开发框架 算法 中间件
ASP.NET Core 中的速率限制中间件
在ASP.NET Core中,速率限制中间件用于控制客户端请求速率,防止服务器过载并提高安全性。通过`AddRateLimiter`注册服务,并配置不同策略如固定窗口、滑动窗口、令牌桶和并发限制。这些策略可在全局、控制器或动作级别应用,支持自定义响应处理。使用中间件`UseRateLimiter`启用限流功能,并可通过属性禁用特定控制器或动作的限流。这有助于有效保护API免受滥用和过载。 欢迎关注我的公众号:Net分享 (239字符)
189 1
|
10月前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
227 3
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
386 0
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
200 7
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
221 0
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
167 0
|
开发框架 前端开发 安全
ASP.NET MVC 如何使用 Form Authentication?
ASP.NET MVC 如何使用 Form Authentication?
299 0
|
开发框架 .NET
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
410 0