我有一些非常基本的HttpClient代码,可以归结为:
var criteria = new Criteria() { Name = "TestName" };
criteria.listProperty.Add(new ComplexObject<int>("value", true));
httpClient.PostAsJsonAsync("api/ctl/myAction", criteria)
控制器如下所示:
[HttpPost]
public HttpResponseMessage myAction([FromBody]Criteria criteria)
{
return DoSomethingWithIt(criteria);
}
问题是,我在我的PostAsJsonAsync
上设置了一个断点,我的条件对象的名称为&#34; TestName&#34;,而它的listProperty有一个带有&#34;值&#34的项目;和真正的属性。一切都应该如此。
但控制器上的断点显示标准为0,而它仍然显示标准对象的名称为&#34; TestName。&#34;然后我尝试了这个:
[HttpPost]
public HttpResponseMessage myAction(Object criteria)
{
var jsonString = model.ToString();
}
jsonString包含所有内容,包括复杂属性&#34; value&#34;和真正的属性。
我的Criteria和ComplexObject对象是这样的:
public class SearchCriteria
{
public List<ComplexObject> listProperty { get; set; }
public string Name { get; set; }
}
public class ComplexObject<T> : ComplexObject
{
public T Value { get; set; }
public List<T> Choices { get; private set; }
public ComplexObject<T>(string complexName, bool isRequired, List<T> choices = null)
{
this.ComplexName = complexName;
this.IsRequired = isRequired;
this.Choices = choices;
}
}
public abstract class ComplexObject
{
public string ComplexName { get; protected set; }
public bool IsRequired { get; protected set; }
}
P.S。:无论有没有[FromBody],我都试过了两个控制器。
答案 0 :(得分:1)
正如您所料,答案是,当通过HTTP或反序列化为JSON时,通用类型会丢失。为了完成这项工作,我必须在我的抽象ComplexObject上编写一个自定义解析器(Deserializer),在SearchCriteria中编写一个迭代器来为每个listProperty调用解析器。
最后,这是我在共享模型命名空间的c#项目之间使用Web API的优雅答案。但是使用剃刀和/或angularjs在我的MVC项目中使用它要复杂得多。
如果您在Web API中使用泛型并遇到问题,我的建议是重新评估您的应用程序的哪个部分非常漂亮。您可以拥有一个可以轻松传递泛型的漂亮后端,或者需要更多基本后端代码来跨越序列化的干净前端。