我有一个字段,其中包含通过JSON发布的原始HTML,最近从字符串转换为IHtmlString。当发生这种变化时,该字段从一个JSON字符串变为一个空对象,并且消耗了JSON开始爆炸的一堆东西。
// When it was a string...
{
someField: "some <span>html</span> string"
}
// When it became an IHtmlString...
{
someField: { }
}
忽略JSON中原始HTML的任何参数,因为这个项目没有实际意义,我如何在我的JSON序列化中获得预期的字符串?
答案 0 :(得分:6)
Json.NET和默认的.NET JavaScriptSerializer都会将IHtmlString
的实例视为没有属性的对象,并将其序列化为空对象。为什么?因为它是只有一个方法的接口,所以方法不会序列化为JSON。
public interface IHtmlString {
string ToHtmlString();
}
对于Json.NET,您需要创建一个将使用JsonConverter
并输出原始字符串的自定义IHtmlString
。
public class IHtmlStringConverter : Newtonsoft.Json.JsonConverter {
public override bool CanConvert(Type objectType) {
return typeof(IHtmlString).IsAssignableFrom(objectType);
}
public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) {
IHtmlString source = value as IHtmlString;
if (source == null) {
return;
}
writer.WriteValue(source.ToString());
}
public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) {
// warning, not thoroughly tested
var html = reader.Value as string;
return html == null ? null : System.Web.Mvc.MvcHtmlString.Create(html);
}
}
有了这个,将新IHtmlStringConverter
的实例发送到Json.NET的SerializeObject
电话。
string json = JsonConvert.SerializeObject(objectWithAnIHtmlString, new[] { new IHtmlStringConverter() });
对于控制器演示此示例的MVC项目,请转到this question's GitHub repository。
答案 1 :(得分:0)
上面的答案是没有考虑将类型考虑在内,将ReadJson更改为下面的代码应该解决这个问题。参考:https://sebnilsson.com/blog/serialize-htmlstring-mvchtmlstring-in-json-net/
var value = reader.Value as string;
// Specifically MvcHtmlString
if (objectType == typeof(MvcHtmlString))
{
return new MvcHtmlString(value);
}
// Generally HtmlString
if (objectType == typeof(HtmlString))
{
return new HtmlString(value);
}
if (objectType.IsInterface && objectType == typeof(IHtmlString))
{
return new HtmlString(value);
}
// Fallback for other (future?) implementations of IHtmlString
return Activator.CreateInstance(objectType, value);
更新:向IHtmlString添加接口检查。