ASP.NET中的读取请求正文

ASP.NET中的读取请求正文,asp.net,rest,httpwebrequest,Asp.net,Rest,Httpwebrequest,如何读取ASP.NET中的请求正文?我正在使用Firefox的REST客户端加载项对本地托管的站点上的资源形成GET请求,在请求正文中,我只是放置字符串“test”以尝试在服务器上读取它 在服务器代码(这是一个非常简单的MVC操作)中,我有以下内容: var reader = new StreamReader(Request.InputStream); var inputString = reader.ReadToEnd(); 但当我调试到它时,inputString总是空的。我不确定还有什么

如何读取ASP.NET中的请求正文?我正在使用Firefox的REST客户端加载项对本地托管的站点上的资源形成GET请求,在请求正文中,我只是放置字符串“test”以尝试在服务器上读取它

在服务器代码(这是一个非常简单的MVC操作)中,我有以下内容:

var reader = new StreamReader(Request.InputStream);
var inputString = reader.ReadToEnd();

但当我调试到它时,
inputString
总是空的。我不确定还有什么其他方法(比如FireBug)来确认请求主体确实被正确发送了,我想我只是假设插件正确地发送了请求主体。也许我读错了值?

也许我记错了我的学校教育,但我认为GET请求实际上没有主体

HTML规范从技术上定义了“GET”和“POST”之间的区别,因此前者意味着表单数据将(通过浏览器)编码到URL中,而后者意味着表单数据将显示在消息体中

所以,也许你做的事情是正确的,但是为了有一个消息体,你必须发布数据

更新 对于您的评论,最“正确”的RESTful方式是将每个值作为自己的参数发送:

site.com/MyController/MyAction?id=1&id=2&id=3...
如果使用相同的名称为其指定数组参数,则您的操作将自动绑定这些参数:

public ActionResult MyAction(int[] id) {...}

或者,如果你是受虐狂,你可以尝试从
Request.QueryString
中一次提取一个值。

我会尝试使用HttpClient(可通过Nuget获得)来做这类事情。它比System.Net对象容易得多

除了GET/POST问题之外,我确实发现您需要将Request.InputStream位置设置回起始位置。多亏我找到了

特别是评论

Request.InputStream//请确保在读取后重置位置,否则以后的读取可能会失败

我翻译成

Request.InputStream.Seek(0,0)

我最近想起了这个老问题,并希望根据我自己工作中最近的实现添加另一个完整性答案

供参考,最近

从本质上讲,这个问题的核心是“如何将更大、更复杂的搜索条件传递给资源,以获得经过筛选的对象列表?”最终归结为两种选择:

  • 一组GET查询字符串参数
  • 请求正文中带有DTO的帖子
  • 第一个选项并不理想,因为实现很难看,URL可能会在某个点超过最大长度。第二个选项虽然很实用,但在“宁静”的意义上却不适合我。毕竟,我得到了数据,对吗

    但是,请记住,我不仅仅是在获取数据。我正在创建一个对象列表。每个对象都已存在,但列表本身不存在。这是一个全新的东西,通过向服务器上完整的对象存储库发布搜索/筛选条件创建。(毕竟,请记住,对象集合本身仍然是一个对象。)

    这纯粹是语义上的差异,但绝对重要。因为,最简单地说,这意味着我可以轻松地使用POST向服务器发布这些搜索条件。响应是我收到的数据,所以我正在“获取”数据。但我并不是在“获取”数据,因为我实际上是在执行一个创建操作,创建一个对象列表的新实例,该列表恰好由预先存在的元素组成


    我完全承认,限制从来不是技术性的,只是语义上的。它只是从来没有“坐对”过我。非技术性问题需要非技术性解决方案,在本例中是语义解决方案。从稍微不同的语义角度来看这个问题,得到了一个更干净的解决方案,这恰好是我最初使用的解决方案。

    直接从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);
    }
    
    /*返回表示正文内容的字符串
    HTTP请求的名称*/
    公共静态字符串GetFromBodyString(此HttpRequestBase请求)
    {
    字符串结果=string.Empty;
    if(request==null | | request.InputStream==null)
    返回结果;
    request.InputStream.Position=0;
    /*在内存中创建新线程以保存原始线程
    阅读许多
    当前HTTP请求的主体*/
    使用(MemoryStream MemoryStream=new MemoryStream())
    {
    请求.InputStream.CopyToMemoryStream(memoryStream);
    使用(StreamReader StreamReader=新StreamReader(memoryStream))
    {
    结果=streamReader.ReadToEnd();
    }
    }
    返回结果;
    }
    /*从给定流MemoryStream复制字节并写入
    把他们送到另一条小溪*/
    公共静态void CopyToMemoryStream(此流源、MemoryStream目标)
    {
    if(source.CanSeek)
    {
    int pos=(int)destination.Position;
    int-length=(int)(source.length-source.Position)+pos;
    destination.SetLength(长度);
    while(pos
    按请求正文签出,你真的是指正文还是包括标题在内的所有内容?@Adam Tuliper:正文。我没有这个请求的任何自定义标题或任何类似的特殊内容。最终目标是能够将ID列表传递给RESTful资源。作为路由本身的一部分,传递单个ID很容易,但我不确定如何传递ID列表。虽然我当然愿意接受这样的可能性,我在这里走错了方向。(也就是说,正文中应该有一个XML字符串。)但是,在GET请求中如何做到这一点?这将在querystring中,否则它将是一个post请求,不是吗?我同意下面关于这一点的讨论,这很有趣