这是我的控制器方法:
[System.Web.Http.HttpPost]
[System.Web.Http.Route("api/exercise")]
public HttpResponseMessage CreateExercise(ExerciseDto exercise) {
以下是我的课程:
public class Exercise {
[Key]
[Required]
public int ExerciseId { get; set; }
[StringLength(300, ErrorMessage = "The value cannot exceed 300 characters. ")]
public string Title { get; set; }
}
[NotMapped]
[Serializable]
public class ExerciseDto : Exercise {
public ExerciseDto(Exercise exercise) {
ExerciseId = exercise.ExerciseId;
Title = exercise.Title;
UserHasExercise = true;
}
public bool UserHasExercise { get; set; }
public List<int> SomeIds { get; set; }
}
如果我在API控制器中使用类型Exercise
,则该对象会通过。我创建了DTO以使用更多属性扩展POCO,但是如果我使用这个ExerciseDto
类,每当我发送之前发送的相同数据时,我都会获得null
。发生了什么事?
WebAPI配置:
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;
config.Formatters.Remove(config.Formatters.XmlFormatter);
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var enumConverter = new Newtonsoft.Json.Converters.StringEnumConverter();
json.SerializerSettings.Converters.Add(enumConverter);
更新:
我暂时的解决方案是完全废弃DTO的想法,只使用[NotMapped]
属性扩展POCO:
public class Exercise {
[Key]
[Required]
public int ExerciseId { get; set; }
[StringLength(300, ErrorMessage = "The value cannot exceed 300 characters. ")]
public string Title { get; set; }
[NotMapped]
public bool UserHasExercise { get; set; }
[NotMapped]
public List<int> SomeIds { get; set; }
}
这使一切变得非常简单,但我觉得它不是更复杂模型的最佳实践。我非常有兴趣看到正确的方法来处理这个问题。
答案 0 :(得分:2)
ExerciseDto
需要一个无参数构造函数,以便Post body正确反序列化。
更新:您的更新是我的方式。
答案 1 :(得分:0)
我认为问题是您已将ExerciseDto
声明为[Serializable]
,但您未在请求中传递所有ExerciseDto
模型参数(您提到了传递与Exercise
)相同的数据。您可以删除[Serializable]
属性,也可以将[JsonIgnore]
添加到模型的UserHasExercise
和SomeIds
参数中。如果您将数据作为xml而不是json传递,则使用[IgnoreDataMember]
代替[JsonIgnore]
。