我有一个检查项目是否正确序列化的测试
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\"}}")
);
我想这不是什么大问题,但我想知道原因。
答案 0 :(得分:4)
我刚刚测试过,result
的值是:
{ “用名字”: “用名字”, “姓”: “姓”, “GUID”: “ABCDEFGHIJK”, “ID”:0}
对于您期望的字符串:
,这自然会失败“{{\” 用名字\ “:\” 用名字\ “\ ”姓\“:\ ”姓\“,\ ”GUID \“:\ ”ABCDEFGHIJK \“}}”
使用双花括号是仅适用于String.Format
方法中使用的格式字符串的转义序列,因此您可以包含单个括号。来自Composite Formatting MSDN page:
打开和关闭括号被解释为开始和结束a 格式项。因此,您必须使用转义序列来显示 一个字面的开口支撑或关闭支撑。指定两个开口括号 (“{{”)在固定文本中显示一个左括号(“{”)或两个 关闭大括号(“}}”)以显示一个右大括号(“}”)。
如果你没有使用String.Format
,那么根据C# Specification 2.4.4.5,双括号将按字面解释为两个括号,因为它不是字符串文字的转义字符。
生成的错误消息令人困惑。我不确定这是因为调试器如何向GUI报告它,或者它们如何格式化它们的错误消息(可能它们过于激进地转换大括号以输出),或者是什么。
如果您将测试更改为:
result.Should().Be(
"{\"Forename\":\"forename\",\"Surname\":\"surname\",\"Guid\":\"abcdefghijk\"}"
);
然后它会通过我怀疑。您可以使用String.Format
调用进行额外测试,从而将双括号更改为单个括号。现在,如果你打算围绕你的JSON进行双重包裹,这完全是另一个问题,但我怀疑这不是你的意图。