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:
- 自定义契约解析器:
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; } }
- 修改序列化方法,支持传入需要处理的属性名:
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()); } }
- 测试时指定目标属性:
var result = JavaScriptConverter.SerializeObject( new { Name = "Jane", OnClick = "function() { return 'Hello'; }" }, "onClick" // 指定该属性使用RawStringConverter ) .ToString();
验证说明
你的RawStringConverter实现是正确的,WriteJson方法中调用writer.WriteRawValue会直接输出原始字符串,不会添加引号。只要确保转换器被正确应用到目标属性上,就能得到预期的序列化结果。
内容的提问来源于stack exchange,提问作者Alexander Zeitler
相关产品推荐
相关产品推荐

