Iva*_*vov 5 c# json asp.net-web-api
我的 WebAPI 应用程序中有一个模型,用 .NET 4.0 编写,具有 type 属性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 */
}
Run Code Online (Sandbox Code Playgroud)
该模型驻留在与我的 Web 项目不同的程序集中。
因此,客户端向我发送一条 JSON 消息,我需要将其转换为此类:
{
"size": 12345,
"contentType": "image/png",
"name": "avatar.png"
}
Run Code Online (Sandbox Code Playgroud)
为了告诉 Json.NET 如何转换,ContentType我注册了一个JsonConverter为此目的编写的自定义:
JsonFormatter.SerializerSettings.Converters.Add(new ContentTypeJsonConverter());
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我指的是JsonFormatterWebApi 应用程序的全局对象。
因此,当客户端向我发送 JSON 时,我希望控制器能够正确解析该消息。
不幸的是,它失败并出现错误:
“无法从 System.String 转换或转换为 System.Net.Mime.ContentType。”
我知道我可以通过将以下代码添加到我的FileData类中来解决这个问题:
public class FileData
{
...
[JsonConverter(typeof(ContentTypeJsonConverter))]
public ContentType ContentType { /* Getter and Setter */ }
}
Run Code Online (Sandbox Code Playgroud)
但问题是我不能在类型FileData所在的程序集中引入对 JSON.NET 的依赖关系。
有没有办法contentType在不改变FileData类的情况下触发成员的正确反序列化?
除了上述之外,我还尝试了布莱恩·罗杰斯的建议:
JsonFormatter.SerializerSettings.ContractResolver = new CustomResolver();
Run Code Online (Sandbox Code Playgroud)
具有以下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;
}
}
Run Code Online (Sandbox Code Playgroud)
结果还是一样。
以下内容对我有用(Web API 2)。
模型:
[Serializable]
public class FileData
{
private ContentType contentType;
public ContentType ContentType
{
get { return contentType; }
set { contentType = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
自定义 JSON 转换器:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
转换器注册 ( WebApiConfig.cs):
public static void Register(HttpConfiguration config)
{
...
config
.Formatters
.JsonFormatter
.SerializerSettings
.Converters
.Add(new ContentTypeJsonConverter());
}
Run Code Online (Sandbox Code Playgroud)
控制器:
public class TestController : ApiController
{
public IHttpActionResult Post(FileData data)
{
return this.Ok(data);
}
}
Run Code Online (Sandbox Code Playgroud)
要求:
POST /api/test HTTP/1.1
Content-Type: application/json
Host: localhost:48278
Content-Length: 36
{
"contentType": "image/png"
}
Run Code Online (Sandbox Code Playgroud)
回复:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?ZDpcd29ya1xUb0REXGFwaVx0ZXN0?=
X-Powered-By: ASP.NET
Date: Mon, 25 Jul 2016 07:06:02 GMT
Content-Length: 27
{"contentType":"image/png"}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1928 次 |
| 最近记录: |