1、前言
前一篇博客介绍了ASP.NET Core
中的跨域设置,我们已经实现了前端界面对后台API
的访问操作。不过很遗憾:到目前为止,测试代码中的Controller
只包含一个不带任何参数的Get()
方法,而在实际开发过程中,不管是GET
还是POST
请求,往往都包含着一系列参数。下面就来介绍一下如何在Controller
中获取这些前端参数。
2、GET请求模式
2.1、搭建前端界面
GET
请求一般是将参数放在URL
后面以?
分隔,参数与参数之间使用&
分隔,其一般格式如下所示:
http://127.0.0.1:5500/index.html?userName=admin&password=123456
下面就来构建一个简易的前端界面,其代码如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GET请求</title>
<script src="jquery/jquery-3.5.1.min.js"></script>
</head>
<body>
<button id="btn">GET模式</button>
<script>
$('#btn').click(function () {
$.ajax({
type: 'get',
url: 'https://localhost:5001/api/Home/Get',
data: {
name: '张三',
gender: '男',
age: 25
},
cache: false,
success: function (res) {
window.alert(res);
},
error: function (err) {
window.alert(err.status);
}
});
});
</script>
</body>
</html>
2.2、后台接收参数
2.2.1、基础类型接收参数
最简单的方法就是使用C#
中的基础类型参数(string
、double
、int
)进行接收,其代码如下所示:
using Microsoft.AspNetCore.Mvc;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpGet]
public string Get(string name, string gender, int age)
{
return $"姓名:{name}\n性别:{gender}\n年龄:{age}";
}
}
}
程序运行结果如下图所示:
2.2.2、实体类型接收参数
ASP.NET Core
也允许通过实体类的方式接收参数,我们可以先定义一个Person
类,代码如下:
namespace App
{
public class Person
{
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 性别
/// </summary>
public string Gender { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
}
}
然后在Controller
的方法中通过[FromQuery]
标记进行接收,代码如下:
using Microsoft.AspNetCore.Mvc;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpGet]
public string Get([FromQuery] Person person)
{
return $"姓名:{person.Name}\n性别:{person.Gender}\n年龄:{person.Age}";
}
}
}
程序运行结果如下图所示:
2.2.3、解析JSON字符串接收参数
我们也可以通过解析JSON
字符串的方式接收参数。由于JavaScript
提供了一个JSON.stringify
方法进行序列化操作,因此我们可以向后台传递一个JSON
字符串,对前端代码做出如下修改:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GET请求</title>
<script src="jquery/jquery-3.5.1.min.js"></script>
</head>
<body>
<button id="btn">GET模式</button>
<script>
$('#btn').click(function () {
$.ajax({
type: 'get',
url: 'https://localhost:5001/api/Home/Get',
data: {
json: JSON.stringify({
name: '张三',
gender: '男',
age: 25
})
},
cache: false,
success: function (res) {
window.alert(res);
},
error: function (err) {
window.alert(err.status);
}
});
});
</script>
</body>
</html>
在后台获取该字符串,然后反序列化成Person
,注意引入Newtonsoft.Json
,代码如下:
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpGet]
public string Get(string json)
{
if (string.IsNullOrEmpty(json))
{
return "";
}
else
{
Person person = JsonConvert.DeserializeObject<Person>(json);
return $"姓名:{person.Name}\n性别:{person.Gender}\n年龄:{person.Age}";
}
}
}
}
程序运行结果如下图所示:
3、POST请求模式
3.1、基础类型接收参数
下面代码就是一个最常见的POST
模式请求代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST请求</title>
<script src="jquery/jquery-3.5.1.min.js"></script>
</head>
<body>
<button id="btn">POST模式</button>
<script>
$('#btn').click(function () {
$.ajax({
type: 'post',
url: 'https://localhost:5001/api/Home/Post',
data: {
name: '张三',
gender: '男',
age: 25
},
success: function (res) {
window.alert(res);
},
error: function (err) {
window.alert(err.status);
}
});
});
</script>
</body>
</html>
我们可以先试着在Controller
中使用基础类型来接受参数,代码如下:
using Microsoft.AspNetCore.Mvc;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpPost]
public string Post(string name, string gender, int age)
{
return $"姓名:{name}\n性别:{gender}\n年龄:{age}";
}
}
}
运行程序,发现无法接受到前端参数,如下图所示:
这里需要注意:如果在POST
模式下想使用基础类型来接收参数,那么必须给参数加上[FromForm]
标签,代码如下:
using Microsoft.AspNetCore.Mvc;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpPost]
public string Post([FromForm] string name, [FromForm] string gender, [FromForm] int age)
{
return $"姓名:{name}\n性别:{gender}\n年龄:{age}";
}
}
}
程序运行结果如下图所示:
3.2、IFormCollection类型接收参数
在原先的ASP.NET MVC
中,POST
模式下Controller
可以使用FormCollection
接收参数,而在ASP.NET Core
中,也可以使用IFormCollection
接收参数,前端代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST请求</title>
<script src="jquery/jquery-3.5.1.min.js"></script>
</head>
<body>
<button id="btn">POST模式</button>
<script>
$('#btn').click(function () {
$.ajax({
type: 'post',
url: 'https://localhost:5001/api/Home/Post',
data: {
name: '张三',
gender: '男',
age: 25
},
success: function (res) {
window.alert(res);
},
error: function (err) {
window.alert(err.status);
}
});
});
</script>
</body>
</html>
这种方式简洁明了,个人比较推荐这种方法,代码如下:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpPost]
public string Post([FromForm] IFormCollection collection)
{
string name = collection["name"];
string gender = collection["gender"];
string age = collection["age"];
return $"姓名:{name}\n性别:{gender}\n年龄:{age}";
}
}
}
程序运行结果如下图所示:
3.3、实体类型接收参数
如果希望通过实体类型接收参数,则前端代码需要设置contentType
为application/json
,同时传递的参数需要使用JSON.stringify
方法进行序列化,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST请求</title>
<script src="jquery/jquery-3.5.1.min.js"></script>
</head>
<body>
<button id="btn">POST模式</button>
<script>
$('#btn').click(function () {
$.ajax({
type: 'post',
url: 'https://localhost:5001/api/Home/Post',
contentType: 'application/json',
data: JSON.stringify({
name: '张三',
gender: '男',
age: 25
}),
success: function (res) {
window.alert(res);
},
error: function (err) {
window.alert(err.status);
}
});
});
</script>
</body>
</html>
在Controller
的方法中需要通过[FromBody]
标记实体类,代码如下:
using Microsoft.AspNetCore.Mvc;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpPost]
public string Post([FromBody] Person person)
{
return $"姓名:{person.Name}\n性别:{person.Gender}\n年龄:{person.Age}";
}
}
}
程序运行结果如下图所示:
3.4、JObject类型接收参数
前端代码如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST请求</title>
<script src="jquery/jquery-3.5.1.min.js"></script>
</head>
<body>
<button id="btn">POST模式</button>
<script>
$('#btn').click(function () {
$.ajax({
type: 'post',
url: 'https://localhost:5001/api/Home/Post',
contentType: 'application/json',
data: JSON.stringify({
name: '张三',
gender: '男',
age: 25
}),
success: function (res) {
window.alert(res);
},
error: function (err) {
window.alert(err.status);
}
});
});
</script>
</body>
</html>
个人也比较推荐使用JObject
接收参数,因为这种方法较为直观。使用NuGet
引入如下组件,版本选择3.1.23
:
Microsoft.AspNetCore.Mvc.NewtonsoftJson
打开Startup.cs
文件,添加Newtonsoft.Json
的支持,代码如下:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace App
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// 添加Newtonsoft.Json支持
services.AddControllers().AddNewtonsoftJson();
// 添加跨域
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseCors("CorsPolicy");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
之后我们就可以利用JObject
接收参数了,代码如下:
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpPost]
public string Post(JObject obj)
{
string name = obj["name"].ToString();
string gender = obj["gender"].ToString();
int age = int.Parse(obj["age"].ToString());
return $"姓名:{name}\n性别:{gender}\n年龄:{age}";
}
}
}
程序运行结果如下图所示:
3.5、解析JSON字符串接收参数
我们也可以通过解析JSON
字符串的方式接收参数。不过需要对前端代码做出如下修改:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST请求</title>
<script src="jquery/jquery-3.5.1.min.js"></script>
</head>
<body>
<button id="btn">POST模式</button>
<script>
$('#btn').click(function () {
$.ajax({
type: 'post',
url: 'https://localhost:5001/api/Home/Post',
contentType: 'application/json',
data: '\'' + JSON.stringify({
name: '张三',
gender: '男',
age: 25
}) + '\'',
success: function (res) {
window.alert(res);
},
error: function (err) {
window.alert(err.status);
}
});
});
</script>
</body>
</html>
可以发现上面代码在data
属性这里多加了两个单引号。接下来只需要在Controller
中解析JSON
即可,代码如下:
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpPost]
public string Post([FromBody] string json)
{
Person person = JsonConvert.DeserializeObject<Person>(json);
return $"姓名:{person.Name}\n性别:{person.Gender}\n年龄:{person.Age}";
}
}
}
程序运行结果如下图所示:
4、结语
本文主要介绍了ASP.NET Core
中Controller
在GET
和POST
请求模式下接收参数的一系列方法。在实际开发过程中,我们需要根据情景选择合适的方法接收参数。