c# - (C# .NET 5 REST API)使用转换器添加多态时输入无效
问题描述
我正在尝试使用转换器在我的 REST API 中使用多态性。我浏览了本教程:https ://newbedev.com/deserialising-json-to-derived-types-in-asp-net-web-api并将其调整为我自己的基类和派生类型。
我发送的请求是这样的:
{
"createdBy": "string",
"createdAt": "2021-08-23T14:42:21.500Z",
"modifiedBy": "string",
"modifiedAt": "2021-08-23T14:42:21.500Z",
"id": 0,
"points": 0,
"text": "test",
"quizId": 4,
"quizOptions": [
]
}
当我删除“文本”属性时它可以工作,但我当然会收到内部服务器错误,因为它不能被解析为“ImageOptionDto”或“TextOptionDto”。
我的转换器:
public class QuizOptionJsonConverter : JsonCreationConverter<QuizOptionDto>
{
protected override QuizOptionDto Create(Type objectType, JObject jObject)
{
if (jObject == null) throw new ArgumentNullException("jObject");
if (jObject["text"] != null)
{
return jObject.ToObject<TextOptionDto>();
}
else if (jObject["imageUrl"] != null)
{
return jObject.ToObject<ImageOptionDto>();
}
else
{
return null;
}
}
}
我的基类:
[JsonConverter(typeof(QuizOptionJsonConverter))]
public class QuizOptionDto : IdentifierBaseModelDto
{
public bool IsCorrect { get; set; }
public int QuizQuestionId { get; set; }
public QuizQuestionDto QuizQuestion { get; set; }
}
我的派生类:
public class TextOptionDto : QuizOptionDto
{
public string Text { get; set; }
}
和
public class ImageOptionDto : QuizOptionDto
{
public string ImageUrl { get; set; }
}
经过一些研究,我还将它添加到我的 Startup.cs
options.SerializerSettings.TypeNameHandling = TypeNameHandling.All;
options.SerializerSettings.Converters.Add(new QuizQuestionJsonConverter());
options.SerializerSettings.Converters.Add(new QuizOptionJsonConverter());
我的问题正是当我使用派生属性进行 api 调用时,例如:'text' 它返回“输入无效”,例如 400)。我试图抑制模型状态验证,但是我的 post 方法中的参数只是“null”。显然,这里出了点问题。
我调试了代码并得出结论,我的代码没有通过该CanConvert
方法。我检查了“objectType(方法中的参数)”的类型,它说:
我希望“TextOptionDto”是这里的类型,而不是“AnnotatedProblemDetails”。我知道这里发生了什么,但我不知道如何解决它。
错误:
{
"$type": "Microsoft.AspNetCore.Mvc.NewtonsoftJson.ValidationProblemDetailsConverter+AnnotatedValidationProblemDetails, Microsoft.AspNetCore.Mvc.NewtonsoftJson",
"errors": {
"$type": "System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib],[System.String[], System.Private.CoreLib]], System.Private.CoreLib",
"": {
"$type": "System.String[], System.Private.CoreLib",
"$values": [
"The input was not valid."
]
}
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-742ca70c9de2454bac8f94422bc49a2b-bd270ab858be3d43-00"
}
你们能帮帮我吗?
谢谢!
编辑
经过一番研究,我发现了问题。它似乎与我来自 OData 的 EDM 有关。当我删除这部分时:
public static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EnableLowerCamelCase();
// The name in the string must be the same as the controller classname e.g. Users
builder.EntitySet<ProductDto>("Products");
builder.EntitySet<CategoryDto>("Categories");
builder.EntitySet<TextBlockDto>("TextBlocks");
builder.EntitySet<MediaDto>("Media");
builder.EntitySet<QuizDto>("Quizzes");
builder.EntitySet<QuizResultDto>("QuizResults");
builder.EntitySet<QuizQuestionDto>("QuizQuestions"); <---
builder.EntitySet<UserDto>("Users");
return builder.GetEdmModel();
}
它工作得很好,但是如果我这样做,这个控制器当然不会使用 OData。
关于如何构建我的模型以使其允许继承的任何建议?
解决方案
推荐阅读
- typescript - 在打字稿中,如何访问窗口函数中的变量?
- sql - 语法错误,意外的 tCONSTANT,期待 ')'
- jquery - 如何通过单击按钮更改数据库中的状态
- variables - 在内存方面,Kotlin 中的 null 变量会发生什么?
- javascript - 应用程序在开发中有效,但在部署到 heroku 时无效
- python - 当扩展这个类时,它的一个方法现在需要一个额外的参数。为什么?
- latex - 从 LaTeX+BibLaTeX 到 Markdown 的 Pandoc 转换
- mysql - 选择将其所有关联项目匹配到列表的行组
- cadence-workflow - 调用子工作流时,如何防止循环依赖/无限循环
- javascript - 比较两个巨大的对象数组的最有效方法