我的WebAPI应用程序中有一个模型,用.NET 4.0编写,具有System.Net.Mime.ContentType
类型的属性,如下所示:
[Serializable]
public class FileData
{
private ContentType contentType;
private long size;
private string name;
public ContentType ContentType
{
get { return contentType; }
set { contentType = value; }
}
...
/* same getter/setter logic for the other fields */
}
模型位于与我的Web项目不同的程序集中。
因此,客户端向我发送了一条JSON消息,我需要将其转换为此类:
{
"size": 12345,
"contentType": "image/png",
"name": "avatar.png"
}
为了告诉Json.NET如何转换ContentType
我已经注册了我为此目的编写的自定义JsonConverter
:
JsonFormatter.SerializerSettings.Converters.Add(new ContentTypeJsonConverter());
在上面的代码中,我指的是WebApi应用程序的全局JsonFormatter
对象。
因此,当客户端向我发送JSON时,我希望控制器正确解析消息。
不幸的是,它失败并出现错误:
"无法从System.String转换或转换为System.Net.Mime.ContentType。"
我知道我可以通过将以下代码添加到我的FileData
类来解决这个问题:
public class FileData
{
...
[JsonConverter(typeof(ContentTypeJsonConverter))]
public ContentType ContentType { /* Getter and Setter */ }
}
但问题是我不能在FileData
类型所在的程序集中为JSON.NET引入依赖项。
有没有办法在不改变contentType
类的情况下触发FileData
成员的正确反序列化?
除了上述内容,我还尝试了Brian Rogers建议的内容:
JsonFormatter.SerializerSettings.ContractResolver = new CustomResolver();
实施以下CustomResolver
:
class CustomResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
var contract = base.CreateContract(objectType);
if (objectType == typeof(ContentType))
{
contract.Converter = new ContentTypeJsonConverter();
}
return contract;
}
}
结果仍然相同。
答案 0 :(得分:1)
以下适用于我(Web API 2)。
型号:
<script>
(function () {
var QUEUE = MathJax.Hub.queue;
var math = null, box = null;
var HIDEBOX = function () {box.style.visibility = "hidden"}
var SHOWBOX = function () {box.style.visibility = "visible"}
QUEUE.Push(function () {
math = MathJax.Hub.getAllJax("MathOutput")[0];
box = document.getElementById("box");
SHOWBOX(); // box is initially hidden so the braces don't show
});
window.UpdateMath = function (TeX) {
QUEUE.Push(
HIDEBOX,
["resetEquationNumbers",MathJax.InputJax.TeX],
["Text",math,"\\displaystyle{"+TeX+"}"],
SHOWBOX
);
}
})();
</script>
<input id="MathInput" size="80" onchange="UpdateMath(this.value)" />
<div class="box" id="box" style="visibility:hidden">
<textarea id="MathOutput" class="output" name="txtSender">$${}$$</textarea>
</div>
<script>
if (MathJax.Hub.Browser.isMSIE) {
MathInput.onkeypress = function () {
if (window.event && window.event.keyCode === 13) {this.blur(); this.focus()}
}
}
</script>
自定义JSON转换器:
[Serializable]
public class FileData
{
private ContentType contentType;
public ContentType ContentType
{
get { return contentType; }
set { contentType = value; }
}
}
转换器注册(public class ContentTypeJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ContentType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return new ContentType((string)reader.Value);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(((ContentType)value).ToString());
}
}
):
WebApiConfig.cs
控制器:
public static void Register(HttpConfiguration config)
{
...
config
.Formatters
.JsonFormatter
.SerializerSettings
.Converters
.Add(new ContentTypeJsonConverter());
}
请求:
public class TestController : ApiController
{
public IHttpActionResult Post(FileData data)
{
return this.Ok(data);
}
}
响应:
POST /api/test HTTP/1.1
Content-Type: application/json
Host: localhost:48278
Content-Length: 36
{
"contentType": "image/png"
}