在Web API控制器中,我返回一个JSON编码对象,实际上是一个Organization
对象列表,每个对象都有自己的Branch
个对象集合,每个对象都有{{1}列表对象。
我从控制器返回它,如Person
:
IHttpActionResult
其中:
return Ok(SerializeObject(orgs));
和
protected virtual string SerializeObject(object source)
{
return JsonConvert.SerializeObject(source, SharedSettings.JsonSerializerSettings);
}
我要求它:
public static JsonSerializerSettings JsonSerializerSettings { get; } = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
TypeNameHandling = TypeNameHandling.None,
NullValueHandling = NullValueHandling.Include
};
我不使用HttpResponseMessage response = await Client.PostAsync(resource, null);
if (!response.IsSuccessStatusCode)
{
RaiseException(response, exMsg);
}
var content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<TReturn>(content, SharedSettings.JsonSerializerSettings);
,因为我非常确定我在两边使用相同的Json序列化程序及其设置。返回的JSON看起来很好,如果您为了简洁而原谅几行:
response.Content.ReadAsAsync<TReturn>()
反序列化的例外是
&#39;错误转换价值&#34;&#34; &#34;输入 &#39; System.Collections.Generic.List`1 [ApptEase.DataModels.Entities.Organization]&#39 ;. 路径&#39;&#39;,第1行,第439200位。
我之前从未遇到过任何关于NewtonSoft JSON的问题,但也许我只对其提出的要求较少。有谁知道可能出现什么问题?
BREAKING:如果我将JSON字符串写入文件,然后使用小型测试程序读取它,它会反序列化,没有明确的选项。有希望,我从主程序中的反序列化中删除了options子句,但我仍然得到相同的错误。我想我应该开始研究文本编码问题。
还可能会注意到[
{
"Branches": [
{
"People": [
{
"FullName": "Katie Darwin",
"BranchId": 2,
"OrgId": 2,
"Id": 18
}
],
"Name": "Jolimont",
"Phone": null,
"OrgId": 2,
"Id": 2
}
],
"Name": "Contoso, Ltd.",
"Id": 2
},
{
"Branches": [],
"Name": "Trey Research",
"Id": 11
}
]
标题和错误位置相等:439200。
答案 0 :(得分:0)
我是愚蠢的,愚蠢的让自己被这么多不同的错误例子所误导。我忘记了ApiController
的一个原则是,它更像是一个存储库而不是一个控制器,在任何地方都没有HTTP垃圾。有问题的控制器现在看起来像这样:
[System.Web.Mvc.RoutePrefix("api/Org")]
public class OrgController : BaseController
{
[HttpPost]
public IEnumerable<Organization> Get()
{
Db.Configuration.LazyLoadingEnabled = false;
return Db.Organizations.ToList();
}
}
返回的对象是这样获得的,Content.ReadAsAsync<TReturn>()
。
public virtual async Task<TReturn> PostAsync<TReturn>(string resource)
{
var exMsg = $"Post request failed to get resource: '{resource}' from '{Client.BaseAddress}'.";
try
{
HttpResponseMessage response = await Client.PostAsync(resource, null);
if (!response.IsSuccessStatusCode)
{
RaiseException(response, exMsg);
}
return await response.Content.ReadAsAsync<TReturn>();
}
catch (Exception ex) when (ex.GetType() != typeof(RestClientException))
{
throw;
}
}
我可能应该使用自定义Response
对象,这可以为来电者提供更多信息,例如抓住了一个例外,但像这样的原始设计是如何工作和工作的那样。