如何使用Json.NET将IHtmlString序列化为JSON?

时间:2012-07-05 18:31:19

标签: c# json json.net

我有一个字段,其中包含通过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序列化中获得预期的字符串?

2 个答案:

答案 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添加接口检查。