我有一个测试来检查项目是否正确序列化
public interface IMyJsIdentity
{
string Forename { get; }
string Surname { get; }
string Guid { get; }
}
public class MyIdentity : IMyJsIdentity
{
public string Forename { get; set; }
public string Surname { get; set; }
public string Guid { get; set; }
public int Id { get; set; }
}
[Fact]
public void SerialiseCorrectly()
{
// Arrange
MyIdentity identity = new MyIdentity()
{
Forename = "forename",
Surname = "surname",
Guid = "abcdefghijk"
};
// Act
string result = JsonConvert.SerializeObject(
identity,
new JsonSerializerSettings()
{
ContractResolver = new InterfaceContractResolver(typeof(IMyJsIdentity))
});
// Assert
result.Should().Be(
"{{"Forename":"forename","Surname":"surname","Guid":"abcdefghijk"}}"
);
}
然而,我在测试失败上得到了以下错误
Xunit.Sdk.AssertException: Expected string to be
"{{"Forename":"forename","Surname":"surname","Guid":"abcdefghijk"}}" with a length of 66, but
"{{"Forename":"forename","Surname":"surname","Guid":"abcdefghijk"}}" has a length of 64.
Json.net显然对字符串做了一些特殊的处理,但我不知道是什么。
奇怪的是,它通过了
result.Should().Be(
String.Format("{{"Forename":"forename","Surname":"surname","Guid":"abcdefghijk"}}")
);
我想这没什么大不了的,但我想知道为什么。
我刚刚测试过,result
的值是:
{"Forename":"Forename","Surname":《姓氏》,"Guid":"abcdefghijk","Id":0}
对于您预期的字符串:,它自然会失败
"{{\"Forename\":\"Forename\",\"Surname\":\"姓氏\",\"Guid\":\"abcdefghijk\"}}">
使用双大括号是仅用于String.Format
方法中使用的格式字符串的转义序列,因此可以包含单个大括号。来自复合格式MSDN页面:
左大括号和右大括号被解释为格式化项目。因此,必须使用转义序列来显示字面上的左大括号或右大括号。指定两个大括号("{{")在固定文本中显示一个左大括号("}")或两个右大括号("}")显示一个右大括号。
如果您不使用String.Format
,那么根据C#规范2.4.4.5,双大括号将被字面解释为两个大括号,因为它不是字符串文字的转义符。
由此产生的错误消息令人困惑。我不确定这是因为调试器如何向GUI报告它,还是因为他们如何格式化错误消息的错误(也许他们过于激进地为输出转义大括号),或者是什么。
如果您将测试更改为:
result.Should().Be(
"{"Forename":"forename","Surname":"surname","Guid":"abcdefghijk"}"
);
我怀疑它会过去的。这是通过使用String.Format
调用的附加测试来备份的,该调用将双大括号更改为单大括号。现在,如果您打算在JSON周围使用双包装大括号,那完全是另一个问题,但我怀疑这不是您的意图。