.NET Core 2 MVC控制器接收API JSON含双反斜杠问题求助
嘿,我看了你的代码,这个额外反斜杠的问题其实是双重序列化导致的,咱们一步步来捋清楚:
问题根源
你的API里用Ok(result)返回数据时,如果countryHelper.GetCountries(mediaType)返回的已经是序列化好的JSON字符串,Ok()方法会把这个字符串当作普通字符串再序列化一次——这就导致最终响应的JSON是被转义过的(比如原JSON是[{"ShortName":"CN"}],经过Ok()处理后会变成"[{\"ShortName\":\"CN\"}]"),客户端拿到的自然就是带额外反斜杠的内容。
就算GetCountries返回的是List<Country>对象,你客户端用ReadAsStringAsync()读取后再手动JsonConvert.DeserializeObject的方式也容易出问题,而且完全没必要绕这一步。
解决方案
根据你的情况分两种处理方式:
情况1:API返回的是实体对象(推荐)
如果countryHelper.GetCountries返回的是List<Country>类型的对象,那API的代码没问题,只需要修改客户端的代码,让HttpClient自动帮你反序列化,不用手动处理字符串:
public async Task<JsonResult> GetCountriesList(string searchText) { HttpResponseMessage responseMessage; List<Country> listCountries = null; using (var client = getHttpClient(WebClientContentType.JSON)) { var requestUri = new Uri($"{_webApiUrl}/api/Country/GetCountryList"); responseMessage = await client.GetAsync(requestUri); if (responseMessage.IsSuccessStatusCode) { // 直接用ReadAsAsync让HttpClient自动反序列化 listCountries = await responseMessage.Content.ReadAsAsync<List<Country>>(); if (!string.IsNullOrEmpty(searchText)) { listCountries = listCountries.Where(m => m.ShortName.ToLower().StartsWith(searchText.ToLower())).ToList(); } } else { return Json(responseMessage.StatusCode); } } return Json(listCountries); }
另外注意把ReadAsStringAsync().Result改成await ReadAsAsync(...),用.Result会阻塞异步流程,容易引发死锁问题。
情况2:API返回的是已序列化的JSON字符串
如果countryHelper.GetCountries返回的是已经序列化好的JSON字符串,那你需要修改API的返回方式,避免双重序列化:
[HttpGet] [Route("api/Country/GetCountryList")] public IActionResult GetCountryList() { ProcedureReturnType mediaType = GetMediaType(); try { CountryHelper countryHelper = new CountryHelper(); var result = countryHelper.GetCountries(mediaType); // 用Content直接返回字符串,指定Content-Type为JSON,而不是用Ok() return Content(result, "application/json"); } catch (Exception ex) { return BadRequest(ex.Message); } }
这样API就不会把JSON字符串再序列化一次,客户端拿到的就是干净的JSON内容,再用JsonConvert.DeserializeObject反序列化就没问题了。
验证你的测试案例
你提到当API返回Ok("\r")时,客户端拿到的是"\"\\r\""——这就是典型的双重序列化:"\r"是字符串,Ok()把它序列化为JSON字符串,所以响应内容是"\"\r\"",客户端读取后就会看到带反斜杠的转义内容。如果改成Content("\r", "text/plain")或者Content("\\r", "application/json"),就能得到你预期的结果。
内容的提问来源于stack exchange,提问作者Rajet

