注意
我不相信这是this question的副本。目标是使用非默认构造函数对模型进行反序列化,而我需要使用自定义反序列化器而不是模型来使用其非默认构造函数进行实例化,在API statup中注入一些依赖项设置。无论如何我试过了JsonConstructor
,但它仍然产生了同样的错误。
Newtonsoft.Json.JsonException:没有为'Domain.UserProjector'定义无参数构造函数。
我正在开发一个API,允许消费者根据一些查询字符串参数来指定资源预测。我觉得在JSON序列化过程中最容易处理它。
模型
我用自定义序列化器装饰我的模型。
[JsonConverter(typeof(CustomProjector))]
public class SomeDTO { /* members */ }
转换器
我实现了自定义序列化程序,注入了所需的HttpContext。
public class CustomProjector : JsonConverter
{
public CustomProjector(IHttpContextAccessor httpContext)
{
/* IHttpContextAccessor is already set up in the dependency container. Then get the requirements from the query string. */
}
/* JsonConverter implementation */
}
API方法
我所要做的就是返回结果。
public IActionResult GetSomething(int id)
{
SomeDTO something = domain.GetSomething(id);
return this.Ok(somthing);
}
不幸的是,这不起作用,因为JsonConverter
实现需要默认构造函数,并且由于CustomProjector
中的参数化构造函数而引发错误,从而产生错误:
Newtonsoft.Json.JsonException:没有为'Domain.UserProjector'定义无参数构造函数。
一种可能的解决方案是简单地向CustomProjector
提供查询字符串并手动执行转换。
模型
无需装饰。
public class SomeDTO { /* members */ }
转换器
HttpContext被查询字符串替换,因为我将手动实例化它。
public class CustomProjector : JsonConverter
{
public CustomProjector(string queryString)
{
/* Get requirements from query string. */
}
/* JsonConverter implementation */
}
API方法
在返回结果之前,实例化转换器并使用它转换。
public IActionResult GetSomething(int id)
{
SomeDTO something = domain.GetSomething(id);
CustomProjector projector = new CustomProjector(this.Request.QueryString.Value);
string somethingSerialised = JsonConvert.SerializeObject(something, projector);
return this.Ok(somethingSerialised);
}
或
将单个查询字符串参数传递给构造函数,但这与上面的选项基本相同。
模型
public class CustomProjector : JsonConverter
{
public CustomProjector(string reqParam1, string reqParam2)
{
/* Use requirements provided. */
}
/* JsonConverter implementation */
}
API方法
public IActionResult GetSomething(int id, string reqParam1, string reqParam2)
{
SomeDTO something = domain.GetSomething(id);
CustomProjector projector = new CustomProjector(reqParam1, reqParam2);
string somethingSerialised = JsonConvert.SerializeObject(something, projector);
return this.Ok(somethingSerialised);
}
我想避免使用这些解决方案,因为它需要API方法来包含参数,并要求每个方法手动转换结果,否则返回的数据将不正确。
有什么我可以改变让它按照我想要的方式工作吗?也许与DI有关?也许是一个不同的序列化器?
非常感谢!