如何防止ReadAsStringAsync返回双重转义的字符串?

我有一个Web API方法,看起来有点像这样:

[HttpPost] public ResponseMessageResult Post(Thing thing) { var content = "\r"; var httpResponseMessage = Request.CreateResponse(HttpStatusCode.Accepted, content); return ResponseMessage(httpResponseMessage); } 

在其他一些客户端代码中,当我打电话时:

  var content = httpResponseMessage.Content.ReadAsStringAsync().Result; 

content是:

  "\\r" 

但我希望它保持原状:

  "\r" 

为什么客户端收到双重转义的字符串,我该如何防止它发生?

它正在做它正在做的事情,因为你用一把大锤打蛋。

当您调用Request.CreateResponse(HttpStatusCode statusCode, T value)您告诉Web API您希望使用其中一种媒体类型格式化程序序列化您的值。 因此,Web API将您的value填充到ObjectContent的实例中,执行大量的连接代码,并确定它可以使用Formatter X来序列化您的“对象”。

有可能是JSONSerializer正在尽力尝试返回它认为你想要的字符串而不是CR字符。

无论如何,你可以通过使用专为通过线路发送简单字符串而设计的HttpContent对象来切入追逐并避免执行70 bajillion代码行。

 [HttpPost] public ResponseMessageResult Post(Thing thing) { var content = "\r"; var httpResponseMessage = new HttpResponseMessage(HttpStatusCode.Accepted) { RequestMessage = Request, Content = new StringContent(content) }; return ResponseMessage(httpResponseMessage); } 

我知道通过这样做我可能会导致70亿条代码执行(对不起Darrel Miller)但是我发现它对我选择的开发模式使用它同样有效,并且破坏性更小:

 response.Content.ReadAsAsync().Result; 

要么

 await response.Content.ReadAsAsync(); 

而不是这个(逃脱报价):

 response.Content.ReadAsStringAsync().Result; 

注意: ReadAsAsyncSystem.Net.Http.Formatting程序集中System.Net.Http.HttpContentExtensions的扩展方法。 如果它在项目中不可用,则可以添加NuGet包Microsoft.AspNet.WebApi.Client

你没有收到@"\\r"的值,你收到"\\r" – 你的回复中不会得到一个逐字字符,因为逐字字符只是一个以特定方式逃避字符串的指令 – 逐字修饰语本身不作为字符串的一部分存储。 结果是您将verbatim修饰符应用到的适当转义版本。

@"\r"为您提供字符串"\\r" ,当应用于文本框时,它显示为\r转义后的反斜杠和“r”。

您只需要从初始分配中删除逐字修饰符。

这与ReadAsStringAsync – 你只是首先分配错误的字符串文字。

如果你得到一个文字的双字符\r序列输出(在C#表单中为"\\r" ),那么这几乎可以肯定你所投入的内容。你说你的Web API方法“看起来有点像这样”。 我强烈怀疑问题在于您在问题中发布的内容与实际实施中的内容之间的差异。

您需要validation您的响应消息是否包含实际的回车符,而不是文本文本"\r" 。 文本读取API不会查找文字C#转义序列并专门处理它们,因为C#字符串转义序列在纯文本中没有意义。 如果您的文本文件包含文本c:\name.txt ,那么您不希望文本读取API将其读取为c:ame.txt

如果你想找到并转换C#风格的转义序列,你必须自己动手。 您可以使用这样的方法(根据需要添加其他转义序列):

 private static string Unescape(string value) { if (value == null) return null; var length = value.Length; var result = new StringBuilder(length); for (var i = 0; i < length; i++) { var c = value[i]; if (c == '\\' && i++ < length) { c = value[i]; switch (c) { case 'n': result.Append('\n'); break; case 'r': result.Append('\r'); break; case 't': result.Append('\t'); break; case '\\': result.Append('\\'); break; default: result.Append(c); break; } } else { result.Append(c); } } return result.ToString(); } 
  [HttpPost] public async Task Post(Thing thing) { var content = "\r"; var httpResponseMessage = Request.CreateResponse(HttpStatusCode.Accepted, content); var escapedString = await httpResponseMessage.Content.ReadAsStringAsync(); return Content(escapedString, "application/json"); }