You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSON.NET中是否有属性标记字符串用JRaw序列化?及测试问题

在JSON.NET中让指定字符串属性以JRaw方式序列化的解决方案

问题背景

你需要让对象的特定字符串属性在JSON.NET序列化时以JRaw的方式输出(即不添加引号,直接保留原始内容),已经定义了RawStringConverter转换器和标记了特性的TestObject类,但测试中使用匿名类型时,目标属性仍被单引号包裹,未达到预期效果。

问题根源

测试代码中使用的是匿名对象,该对象的OnClick属性没有标记[JsonConverter(typeof(RawStringConverter))]特性,因此序列化过程不会触发自定义转换器,导致属性值被当作普通字符串处理。


修复方案

方案一:使用标记特性的实体类

直接使用你定义好的TestObject类创建实例,替换测试中的匿名对象:

public class SomeTest {
  [Fact]
  public void ShouldSerializeRaw()
  {
    var result = JavaScriptConverter.SerializeObject(
        new TestObject
        {
          Name = "Jane",
          OnClick = "function() { return 'Hello'; }"
        }
      )
      .ToString();
    result.ShouldBe("{name: 'Jane',onClick: function() { return 'Hello'; }}");
  }
}

方案二:动态指定转换器(适配匿名类型)

如果必须使用匿名类型,可以通过自定义契约解析器,指定特定属性使用RawStringConverter:

  1. 自定义契约解析器:
public class RawStringContractResolver : CamelCasePropertyNamesContractResolver
{
    private readonly HashSet<string> _rawPropertyNames;

    public RawStringContractResolver(params string[] rawPropertyNames)
    {
        _rawPropertyNames = new HashSet<string>(rawPropertyNames, StringComparer.OrdinalIgnoreCase);
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
        if (_rawPropertyNames.Contains(property.PropertyName))
        {
            property.Converter = new RawStringConverter();
        }
        return property;
    }
}
  1. 修改序列化方法,支持传入需要处理的属性名:
public static class JavaScriptConverter
{
  public static IHtmlContent SerializeObject(
    object value,
    params string[] rawPropertyNames
  )
  {
    using var stringWriter = new StringWriter();
    using var jsonWriter = new JsonTextWriter(stringWriter);

    var serializer = new JsonSerializer
    {
      ContractResolver = rawPropertyNames.Length > 0 
          ? new RawStringContractResolver(rawPropertyNames) 
          : new CamelCasePropertyNamesContractResolver()
    };

    jsonWriter.QuoteName = false;
    jsonWriter.QuoteChar = '\'';
    serializer.Serialize(jsonWriter, value);

    return new HtmlString(stringWriter.ToString());
  }
}
  1. 测试时指定目标属性:
var result = JavaScriptConverter.SerializeObject(
    new
    {
      Name = "Jane",
      OnClick = "function() { return 'Hello'; }"
    },
    "onClick" // 指定该属性使用RawStringConverter
  )
  .ToString();

验证说明

你的RawStringConverter实现是正确的,WriteJson方法中调用writer.WriteRawValue会直接输出原始字符串,不会添加引号。只要确保转换器被正确应用到目标属性上,就能得到预期的序列化结果。

内容的提问来源于stack exchange,提问作者Alexander Zeitler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 13:40:57