.NET后台接收JSON数据的多种方法与实践**
在现代Web开发中,JSON(JavaScript Object Notation)因其轻量级、易读易写的特性,已成为前后端数据交换的主流格式。.NET后台作为强大的服务端框架,提供了多种灵活的方式来接收和处理JSON数据,本文将详细介绍在.NET Core(及后续版本)和传统.NET Framework中,如何高效地接收JSON数据。
准备工作:引入必要的NuGet包
无论是.NET Core还是.NET Framework,处理JSON数据通常离不开Newtonsoft.Json(Json.NET)或.NET内置的System.Text.Json。
- System.Text.Json:.NET Core 3.0及以上版本已内置,无需额外安装,性能较好,推荐在新项目中使用。
- Newtonsoft.Json:老牌JSON库,功能极其丰富,社区支持广泛,许多旧项目或依赖特定功能的项目仍在使用。
如果你习惯使用Newtonsoft.Json,可以通过NuGet包管理器安装:
Install-Package Newtonsoft.Json
对于System.Text.Json,通常无需安装,直接using即可。
常见场景一:接收HTTP请求中的JSON数据(Web API / MVC)
这是最常见的情况,前端通过POST或PUT请求将JSON数据发送到后端API。
方法1:直接读取请求流并手动反序列化(适用于原始请求或特殊格式)
当你需要直接处理请求体中的原始JSON字符串时,可以这样做。
示例(使用System.Text.Json):
using Microsoft.AspNetCore.Mvc;
using System.IO;
using System.Text;
using System.Text.Json;
[ApiController]
[Route("api/[controller]")]
public class RawJsonController : ControllerBase
{
[HttpPost("receive")]
public IActionResult ReceiveRawJson()
{
using var streamReader = new StreamReader(Request.Body, Encoding.UTF8);
var jsonBody = streamReader.ReadToEnd();
// 反序列化到特定类型
var myObject = JsonSerializer.Deserialize<MyModel>(jsonBody);
// 或者反序列化为JsonDocument
// using var jsonDoc = JsonDocument.Parse(jsonBody);
// var root = jsonDoc.RootElement;
return Ok($"Received: {myObject?.SomeProperty}");
}
}
public class MyModel
{
public string SomeProperty { get; set; }
public int AnotherProperty { get; set; }
}
示例(使用Newtonsoft.Json):
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.IO;
using System.Text;
[ApiController]
[Route("api/[controller]")]
public class RawJsonNewtonsoftController : ControllerBase
{
[HttpPost("receive")]
public IActionResult ReceiveRawJson()
{
using var streamReader = new StreamReader(Request.Body, Encoding.UTF8);
var jsonBody = streamReader.ReadToEnd();
var myObject = JsonConvert.DeserializeObject<MyModel>(jsonBody);
return Ok($"Received: {myObject?.SomeProperty}");
}
}
// MyModel同上
方法2:通过模型绑定(推荐,简洁高效)
ASP.NET Core的模型绑定机制非常强大,可以自动将请求体中的JSON数据反序列化到action参数的复杂类型中,这是最推荐的方式。
步骤:
- 定义一个与JSON结构对应的C#模型(POCO类)。
- 在Controller的Action方法中,将该模型作为参数。
- 确保请求的
Content-Type头设置为application/json。
示例:
using Microsoft.AspNetCore.Mvc;
using System.Text.Json.Serialization; // 用于System.Text.Json的属性
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
// 使用System.Text.Json (默认)
[HttpPost]
public IActionResult CreateProduct([FromBody] Product product)
{
if (product == null)
{
return BadRequest("Product data is null.");
}
// 验证模型(可选,但推荐)
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// 处理product数据...
// _productService.Add(product);
return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
}
[HttpGet("{id}")]
public IActionResult GetProduct(int id) // 假设GetProduct方法存在
{
// ...
return Ok();
}
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
}
使用Newtonsoft.Json时的小贴士:
如果你在项目中大量使用Newtonsoft.Json,并希望保持一致性,可以在Startup.cs(或Program.cs在.NET 6+中)中配置默认使用Newtonsoft.Json:
// Program.cs (.NET 6+)
builder.Services.AddControllers()
.AddNewtonsoftJson(); // 添加这一行
这样,[FromBody]模型绑定就会默认使用Newtonsoft.Json进行反序列化,并且你可以在模型上使用[JsonProperty]等特性:
using Newtonsoft.Json;
public class ProductNewtonsoft
{
[JsonProperty("product_id")]
public int Id { get; set; }
[JsonProperty("product_name")]
public string Name { get; set; }
// ...
}
方法3:接收JObject / JToken(Newtonsoft.Json,适用于动态或未知结构)
当JSON结构不固定,或者你需要动态操作JSON时,可以使用Newtonsoft.Json中的JObject或JToken。
示例:
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
[ApiController]
[Route("api/[controller]")]
public class DynamicJsonController : ControllerBase
{
[HttpPost("receive-dynamic")]
public IActionResult ReceiveDynamic([FromBody] JObject jsonData)
{
if (jsonData == null)
{
return BadRequest("Invalid JSON data.");
}
// 动态访问属性
string name = jsonData["name"]?.ToString();
int age = jsonData["age"]?.Value<int>() ?? 0;
// 遍历所有属性
foreach (var prop in jsonData.Properties())
{
Console.WriteLine($"{prop.Name}: {prop.Value}");
}
return Ok($"Dynamic data received: Name={name}, Age={age}");
}
}
常见场景二:接收客户端(如HttpClient)发送的JSON数据
当.NET后台作为客户端,使用HttpClient向其他服务发送POST请求并携带JSON数据时,通常也需要接收响应的JSON数据。
示例(发送JSON并接收JSON响应,使用System.Text.Json):
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
public class ExternalApiService
{
private readonly HttpClient _httpClient;
public ExternalApiService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<MyApiResponse> CallExternalApiAsync(MyRequestData requestData)
{
var jsonRequest = JsonSerializer.Serialize(requestData);
var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync("https://api.example.com/data", content);
response.EnsureSuccessStatusCode();
using var responseStream = await response.Content.ReadAsStreamAsync();
var responseJson = await JsonSerializer.DeserializeAsync<MyApiResponse>(responseStream);
return responseJson ?? throw new InvalidOperationException("Failed to deserialize response.");
}
}
public class MyRequestData { /* ... */ }
public class MyApiResponse { /* ... */ }
示例(使用Newtonsoft.Json):
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class ExternalApiServiceNewtonsoft
{
private readonly HttpClient _httpClient;
public ExternalApiServiceNewtonsoft(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<MyApiResponseNewtonsoft> CallExternalApiAsync(MyRequestDataNewtonsoft requestData)
{
var jsonRequest = JsonConvert.SerializeObject(requestData);
var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync("https://api.example.com/data", content);
response.EnsureSuccessStatusCode();
var jsonResponse = await response.Content.ReadAsStringAsync();
var responseObj = JsonConvert.DeserializeObject<MyApiResponseNewtonsoft>(jsonResponse);
return responseObj ?? throw new InvalidOperationException("Failed to deserialize response.");
}
}
public class MyRequestDataNewtonsoft { /* ... */ }
public class MyApiResponseNewtonsoft { /* ... */ }
注意事项与最佳实践
- 模型验证:使用
[FromBody]绑定时,务必进行模型验证(ModelState.IsValid),确保数据的完整性和合法性。 - 异常处理:JSON反序列化可能抛出异常(如格式错误、类型不匹配),应使用
try-catch块妥善处理,避免服务崩溃。 - 大小写敏感:默认情况下,JSON属性名是区分大小写的,确保C#模型属性名与JSON键名匹配,或使用特性(如`[JsonPropertyName("json



还没有评论,来说两句吧...