如何在ASP.NET中读取请求正文?我正在使用Firefox的REST客户端插件为我在本地托管的网站上的资源形成GET请求,而在请求正文中我只是将字符串“test”试图读取它服务器。
在服务器代码中(这是一个非常简单的MVC动作)我有这个:
var reader = new StreamReader(Request.InputStream);
var inputString = reader.ReadToEnd();
但是当我调试它时,inputString
总是空的。我不确定如何(例如在FireBug中)确认请求正文确实正确发送,我想我只是假设附加组件正确地执行了此操作。也许我错误地读了这个值?
答案 0 :(得分:4)
也许我错误地记住了我的学业,但我认为GET请求实际上没有一个团体。 This page states
HTML规范在技术上定义了“GET”和“POST”之间的区别,因此前者意味着表单数据将被(通过浏览器)编码为URL,而后者意味着表单数据将出现在消息体。
所以也许你正确地做事,但你必须发布数据才能有一个消息体?
在回复您的评论时,最“正确”的RESTful方式是将每个值作为自己的参数发送:
site.com/MyController/MyAction?id=1&id=2&id=3...
如果你给它一个相同名称的数组参数,你的动作将自动绑定这些:
public ActionResult MyAction(int[] id) {...}
或者,如果你是一个受虐狂,你可以尝试一次从Request.QueryString
中提取一个值。
答案 1 :(得分:2)
我最近想起了这个老问题,并希望根据我自己工作中最近的实现添加另一个完整性的答案。
最近参考I've blogged on the subject。
基本上,这个问题的核心是,#34;我如何将更大,更复杂的搜索条件传递给资源以获取过滤的对象列表?"它最终沸腾到两个选择:
第一个选项并不理想,因为实现很难看,并且URL在某些时候可能会超过最大长度。第二种选择,虽然功能齐全,但并没有和我一起坐在" RESTful"感。毕竟,我 GETting 数据,对吧?
但是,请记住,我只是 GETting数据。我创建对象列表。每个对象都已存在,但列表本身并不存在。它是一个全新的东西,通过向服务器上的完整对象存储库发出搜索/过滤条件来创建。 (毕竟,请记住,对象集合本身仍然是一个对象。)
它纯粹是语义上的差异,但却是一个非常重要的差异。因为,最简单的是,这意味着我可以轻松地使用POST将这些搜索条件发布到服务器。回复是我收到的数据,所以我得到了#34;数据。但我不是" GETting"我实际上在执行创作行为的意义上的数据,创建了一个恰好由预先存在的元素组成的对象列表的新实例。
我完全承认这种限制从来都不是技术性的,只是语义上的。它永远不会正确地坐在"与我一起。非技术问题需要非技术解决方案,在这种情况下是语义解决方案。从稍微不同的语义观点来看问题导致了一个更清晰的解决方案,这恰好是我最初使用的解决方案。
答案 2 :(得分:1)
除了GET / POST问题之外,我确实发现您需要将Request.InputStream位置设置回到开头。感谢this answer我找到了。
特别是评论
Request.InputStream //确保在读取后重置位置或稍后读取可能失败
我将其翻译成
Request.InputStream.Seek(0,0)
答案 3 :(得分:0)
我会尝试使用HttpClient(可通过Nuget获得)来执行此类操作。它比System.Net对象
容易得多答案 4 :(得分:0)
从Request.InputStream直接读取是危险的,因为即使数据存在,重新读取也会变为null。这在实践中得到了验证。 可靠读数如下:
/*Returns a string representing the content of the body
of the HTTP-request.*/
public static string GetFromBodyString(this HttpRequestBase request)
{
string result = string.Empty;
if (request == null || request.InputStream == null)
return result;
request.InputStream.Position = 0;
/*create a new thread in the memory to save the original
source form as may be required to read many of the
body of the current HTTP- request*/
using (MemoryStream memoryStream = new MemoryStream())
{
request.InputStream.CopyToMemoryStream(memoryStream);
using (StreamReader streamReader = new StreamReader(memoryStream))
{
result = streamReader.ReadToEnd();
}
}
return result;
}
/*Copies bytes from the given stream MemoryStream and writes
them to another stream.*/
public static void CopyToMemoryStream(this Stream source, MemoryStream destination)
{
if (source.CanSeek)
{
int pos = (int)destination.Position;
int length = (int)(source.Length - source.Position) + pos;
destination.SetLength(length);
while (pos < length)
pos += source.Read(destination.GetBuffer(), pos, length - pos);
}
else
source.CopyTo((Stream)destination);
}