Asp.Net Core Web Api 路由传参探幽

不同的方式传参

本文需要用到的自定义复杂类型:

public class Student
{
    public int Age { get; set; }
    public string Name { get; set; }
    public string Color { get; set; }
} 

query传参

1.简单类型-简单类型

[HttpGet]
public ActionResult Get(string a, int b);
http://localhost:5000/api/values?a=aaa&b=111

2.简单类型-复杂类型

[HttpGet]
public ActionResult Get(Student student);
http://localhost:5000/api/values?age=11&name=jack&color=red

3.Json-简单类型,复杂类型

query没必要用json来传递简单类型

query无法将Json格式的字符串直接映射到复杂类型,可能是复杂类型会忽略其名称(student)。但是可以传递Json格式的字符串至一个字符串接收器,随后可以二次解析。

总结:query只能传递简单类型,而接受方则可以是简单类型和复杂类型

Route传参

  1. 路由也只能传递简单数据类型(路由本身不可能是复杂类型)
  2. 不是路由中的任何值都能做参数
[HttpGet("id")]
public ActionResult Get(int id);
http://localhost:5000/api/values/id?id=5

此时,路由中的第一个id并没有做参数,而是单纯的路由,且不可以被省略,否则会找不到路由

  1. 将路由当做参数
[HttpGet("{id}")]
public ActionResult Get(int id)
http://localhost:5000/api/values/6

将路由中id加上{}后就能将id当做参数了。即使后面再跟别的query id,后面的id也不会起作用了。

如果将路由中6改成字符串,则id的值为默认的0

  1. 可以指定多级路由来传递至复杂类型
[HttpGet("{Age?}/{Name?}/{Color?}")]
public ActionResult Get(int Age, Student student)
http://localhost:5000/api/values/8/shang/red

总结:route只能传递简单类型,而接受方则可以是简单类型和复杂类型

Header传参

header出传参必须加[FromHeader],否则无法识别

1.简单类型-简单类型

[HttpGet()]
public ActionResult Get([FromHeader]int age, [FromHeader]string name, [FromHeader]string color)
http://localhost:5000/api/values/

在这里插入图片描述
2.简单类型-复杂类型

[HttpGet()]
public ActionResult Get([FromHeader]Student student)

注意:无法通过简单类型传递到复杂类型

3.Header传递的Json字符串无法被识别

总结:header只能传递简单类型,而接受方则也只能是简单类型

From传参

1.简单类型-简单类型

[HttpGet()]
public ActionResult Get([FromHeader]int age, [FromHeader]string name, [FromHeader]string color)
http://localhost:5000/api/values/

在这里插入图片描述

2.简单类型-复杂类型

[HttpGet()]
public ActionResult Get(Student student)
http://localhost:5000/api/values/

在这里插入图片描述

3.无法用json传递

在这里插入图片描述
4.传文件

看我写的模型绑定那篇文章

总结:form只能传递简单类型,而接受方则可以是简单类型和复杂类型

Body传参

  1. Body传参也必须加上[FromBody]属性,否则无法识别
  2. asp.net core默认接收json格式的数据,除非设置了其他格式的解析,本文只采用json来传参。想要添加xml格式的解析,或者添加自定义解析可以看官方文档。
  3. Body不存在简单类型和复杂类型,就是Json格式
  4. 一个参数列表只能存在一个[FromBody]
  5. json-简单类型
[HttpGet()]
public ActionResult Get([FromBody]string name)

body无法传递简单数据

6.json-复杂类型

[HttpGet()]
public ActionResult Get([FromBody]Student student);
http://localhost:5000/api/values/

总结:body只能传递json字符串,而接受方只能是复杂类型

同时指定参数

如果这几种传参方式同时指定了值,那么会选择谁呢?

由于headerbody都需要指定[FromXXX]属性,所以不需要考虑了。

测试结果:

1.当form,query,route同时指定时,选择form

http://localhost:5000/api/values/route?name=query

在这里插入图片描述
2.当query,route同时指定时,选择route

http://localhost:5000/api/values/route?name=query

默认值

值类型

1.不传值

[HttpGet()]
public ActionResult Get(int a, bool b, DateTime c);
http://localhost:5000/api/values/

结果:
在这里插入图片描述

2.传匹配类型的值

[HttpGet()]
public ActionResult Get(int a, bool b, DateTime c);
http://localhost:5000/api/values?a=11&b=true&c=1992-01-02

结果:
在这里插入图片描述
3.传不匹配类型的值

[HttpGet()]
public ActionResult Get(int a, bool b, DateTime c);
http://localhost:5000/api/values?a=11&b=name&c=19920102

结果:

总结:值类型如果不传值或者传不匹配的值,则值为该类型的默认值。传匹配的值则正确接收值

引用类型

1.不传值

[HttpGet()]
public ActionResult Get(Student student,string other);
http://localhost:5000/api/values

结果:
在这里插入图片描述
2.传配类型的数据

[HttpGet()]
public ActionResult Get(Student student,string other);
http://localhost:5000/api/values?age=11&name=zhang&color=red&other=sui

结果:
在这里插入图片描述
3.引用类型不存在不匹配的数据

总结:string类型的数据不传值则为null,传值则为该值。复杂类型本身不为null(实际上asp.net core会在内部调用它的默认构造函数),但是它包含的属性(值类型,引用类型)都遵循前述规则

由服务端接收到的值推断客户端的传参形式

值类型

1.服务端接收到的值为除默认值外的值

客户端传值了

2.服务端接收到了默认值

客户端没传值,客户端传了个不符合类型的值,客户端传了默认值

解决办法:

客户端没传值:用可空类型约束

客户端传了不符合类型的值:校验ModelState

客户端传了默认值:正确,不用做

总结:要根据服务端接收到的值推断客户端的具体行为采用的方法是可空类型+ModelState。可以判断客户端想要将值设为另外一个值还是不改动(为null则不改动,为数值类型包括默认值则就为该值)

引用类型

1.服务端接到的值不为null

客户端传了正确的值

2.服务端接收到的值为null

客户端没传值,客户端传了空白

http://localhost:5000/api/values
http://localhost:5000/api/values?name=
http://localhost:5000/api/values?name=空格

解决办法

设置默认值

HttpContext.Form.ContainsKey("key")

总结:当一个引用类型无法判断是想修改值还是不修改值时,可以用设置默认值的方式,接收到默认值,说明是不修改值,接收null则表示将值改为null。还可以直接获取HttpContext信息,判断该参数有还是没有,没有说明不需要改。有,如果为null,则置为null。有,如果不为null,则置为该值。

https://blog.csdn.net/qq_34759481/article/details/102755686


详解ASP.NET Core WebApi 返回统一格式参数

业务场景:

业务需求要求,需要对 WebApi 接口服务统一返回参数,也就是把实际的结果用一定的格式包裹起来,比如下面格式:

{
  "response":{
    "code":200,
    "msg":"Remote service error",
    "result":""
  }
}

具体实现:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
 
public class WebApiResultMiddleware : ActionFilterAttribute
{
  public override void OnResultExecuting(ResultExecutingContext context)
  {
    //根据实际需求进行具体实现
    if (context.Result is ObjectResult)
    {
      var objectResult = context.Result as ObjectResult;
      if (objectResult.Value == null)
      {
        context.Result = new ObjectResult(new { code = 404, sub_msg = "未找到资源", msg = "" });
      }
      else
      {
        context.Result = new ObjectResult(new { code = 200, msg = "", result = objectResult.Value });
      }
    }
    else if (context.Result is EmptyResult)
    {
      context.Result = new ObjectResult(new { code = 404, sub_msg = "未找到资源", msg = "" });
    }
    else if (context.Result is ContentResult)
    {
      context.Result = new ObjectResult(new { code = 200, msg = "", result= (context.Result as ContentResult).Content });
    }
    else if (context.Result is StatusCodeResult)
    {
      context.Result = new ObjectResult(new { code = (context.Result as StatusCodeResult).StatusCode, sub_msg = "", msg = "" });
    }
  }
}

Startup添加对应配置:

public void ConfigureServices(IServiceCollection services)
{
  services.AddMvc(options =>
  {
    options.Filters.Add(typeof(WebApiResultMiddleware));
    options.RespectBrowserAcceptHeader = true;
  });
}

.net core webapi常用传递方式

一、传数组

js:

return request({
    url: '',
    method: 'post',
    data:[1,2,3]
  })

服务端写法:

 [HttpPost]
 public Response 方法名([FromBody] string[] ids) {}//ids的名称自定义

二、传一个对象集合(传单个对象的方法与之相同)

如实体类叫 student:

class student{ 
   name{get;set;}
   age{get;set;}
}

js:

  return request({
    url: '',
    dataType: "json",
    contentType: "application/json;charset=utf-8",
    method: 'post',
    data:rows  //rows是一个数组,里面是json对象,如:[{name:"a",age:1},{name:"b",age:2}]
  })

服务端方法:

[HttpPost]
public Response 方法名([FromBody] List<student> rows){}//其中rows是形参名,自定义

三、同时传集合和其他参数

//js:  
return request({
    url: '',
    dataType: "json",
    contentType: "application/json;charset=utf-8",
    method: 'post',
    params: { a:"123" },
    data:rows//rows是一个数组,里面是json对象,如:[{name:"a",age:1},{name:"b",age:2}]
  })
//服务端
[HttpPost]
public Response 方法名([FromBody] List<student> rows, [FromQuery] string a)

.NET Core WebAPI post参数传递时后端的接收方式

  1. 实体类
  2. dynamic动态类型
  3. JObject参数
  4. 单值参数(字符串参数)

A.前端Post请求代码

$.ajax({
           url: "/api/student/poststudent",
           type: 'POST',
           data:JSON.stringify({ name: "张三", age: 21 }),
           success:function () {
           },
           dataType: "json",
           contentType: "application/json"
       });

B.后端接收参数方式

1. 实体类

实体类是比较简单的一种传参方式,使用频率非常高。

  1. 添加实体类
public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
}
  1. 后台处理Post请求代码
[HttpPost("{id}")]
public void PostStudent(Student student)
{
}
  1. 接收参数结果
    在这里插入图片描述

2.dynamic动态类型

  1. 后台处理Post请求代码
[HttpPost("{id}")]
public void PostStudent(dynamic student)
{
    var name = student.name;//name大小写与前端参数一致
    var age = student.age;
}
  1. 接收参数结果
    在这里插入图片描述

3.JObject参数

  1. 引入Microsoft.AspNetCore.Mvc.NewtonsoftJson
  2. 添加引用 using Newtonsoft.Json.Linq;
  3. 后台处理Post请求代码
[HttpPost("{id}")]
public void PostStudent(JObject student)
{
}
  1. 接收参数结果
    在这里插入图片描述

4.单值参数(字符串参数)

只能传一个字符串参数,并且用单引号包一个双引号,双引号里为字符串内容!
2. 前端代码与以上方式不同

$.ajax({
           url: "/api/student/poststudent",
           type: 'POST',
           data:'"name=张三,age=21"',//这里是重点!用单引号包一个双引号,双引号里为字符串内容!
           success:function () {
           },
           dataType: "json",
           contentType: "application/json"
       });
  1. 后台处理Post请求代码
[HttpPost("{id}")]
public void PostStudent([FromBody] string values)
{
}

WebApi 方法参数前加[FromBody]标识,表示该参数值应该从请求的Body中获取,而不是从URL中获取。不加[FromBody]标识后台取不到参数值。

4. 接收参数结果

在这里插入图片描述

设置允许跨域
如果有跨域需求支持,请设置允许跨域。在Startup.cs中添加如下代码。

  1. 修改ConfigureServices方法,添加代码如下:
//允许一个或多个来源可以跨域
services.AddCors(options =>
{
      options.AddPolicy("CustomCorsPolicy", policy =>
      {
             // 设定允许跨域的来源,有多个可以用','隔开
             policy.WithOrigins("https://localhost:5000")//只允许https://localhost:5000来源允许跨域
             .AllowAnyHeader()
             .AllowAnyMethod()
             .AllowCredentials();
      });
});
  1. 修改Configure方法,添加代码如下:
app.UseCors("CustomCorsPolicy");
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值