如何防止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
您告诉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;
注意: ReadAsAsync
是System.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:
。
如果你想找到并转换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"); }
- 如果API速率限制超过使用WebApiThrottle – C#Web API,则阻止API请求5分钟
- 每种类型自定义Json.NET序列化程序设置
- global.asax中的Application_Error未捕获WebAPI中的错误
- 从单个WebApi方法提供多个二进制文件的最佳方法是什么?
- 使用HttpServer或HttpSelfHostServer对Web API进行unit testing
- 使用WebApi进行OData分页($ inlinecount)
- 如何从WebAPI中的HttpResponse对象获取错误消息?
- ASP.NET Web.api如何处理名称以GET开头的两个方法?
- 简单的WEB API REST项目