如何手动创建嵌套的POST参数?(例如,我在.Net中创建请求以联系Rails后端)

Gre*_*reg 1 c# ruby-on-rails http

如何为http Web请求手动创建嵌套的POST参数?我有一个.NET C#客户端,正在为其创建对Rails页面的HTTP请求。到目前为止,一切都很好,但是我已经注意到,为请求创建的参数(键/值对)应该嵌套。我实际上也很难尝试在控制器before_filter中解决如何对原始请求内容进行“放入”,以查看成功请求的格式。

RAILS BACKEND EXPECT(成功的登录文件,当我从浏览器(不是.net)调用时)

 action_controller.request.request_parameters: !map:HashWithIndifferentAccess
   commit: Save
   webfile: !map:HashWithIndifferentAccess
     path: winter
     file: &id005 !ruby/object:File
       content_type: image/jpeg
       original_path: Winter.jpg
Run Code Online (Sandbox Code Playgroud)

C#参数创建:

    var form = new NameValueCollection();
    form["path"] = "winter";  ==> THIS DOESN'T WORK BECAUSE I THINK IT MAY HAVE TO BE NESTED WITHIN THE "webfile" HASH
Run Code Online (Sandbox Code Playgroud)

C#例程:

    public static HttpWebResponse Upload(HttpWebRequest req, UploadFile[] files, NameValueCollection form)
    {
        List<MimePart> mimeParts = new List<MimePart>();

        try
        {
            foreach (string key in form.AllKeys)
            {
                StringMimePart part = new StringMimePart();

                part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
                part.StringData = form[key];

                mimeParts.Add(part);
            }

            int nameIndex = 0;

            foreach (UploadFile file in files)
            {
                StreamMimePart part = new StreamMimePart();

                if (string.IsNullOrEmpty(file.FieldName))
                    file.FieldName = "file" + nameIndex++;

                part.Headers["Content-Disposition"] = "form-data; name=\"" + file.FieldName + "\"; filename=\"" + file.FileName + "\"";
                part.Headers["Content-Type"] = file.ContentType;

                part.SetStream(file.Data);

                mimeParts.Add(part);
            }

            string boundary = "----------" + DateTime.Now.Ticks.ToString("x");

            req.ContentType = "multipart/form-data; boundary=" + boundary;
            req.Method = "POST";

            long contentLength = 0;

            byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");

            foreach (MimePart part in mimeParts)
            {
                contentLength += part.GenerateHeaderFooterData(boundary);
            }

            req.ContentLength = contentLength + _footer.Length;

            byte[] buffer = new byte[8192];
            byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
            int read;

            using (Stream s = req.GetRequestStream())
            {
                foreach (MimePart part in mimeParts)
                {
                    s.Write(part.Header, 0, part.Header.Length);

                    while ((read = part.Data.Read(buffer, 0, buffer.Length)) > 0)
                        s.Write(buffer, 0, read);

                    part.Data.Dispose();

                    s.Write(afterFile, 0, afterFile.Length);
                }

                s.Write(_footer, 0, _footer.Length);
            }

            return (HttpWebResponse)req.GetResponse();
        }
        catch
        {
            foreach (MimePart part in mimeParts)
                if (part.Data != null)
                    part.Data.Dispose();

            throw;
        }
    }
Run Code Online (Sandbox Code Playgroud)

谢谢

PS。特别是,我想我的目标是:* Rails如何将嵌套的表单参数/哈希序列化为实际的HTTP Request主体,和/或*指向在Rails代码库中执行此操作的特定类的指针(所以我可以看一下,然后在我的.net客户端中进行仿真)

EmF*_*mFi 5

您不确定要在这里做什么。因此,我认为我们无法为您解决问题。

最好的建议是您使用监视请求的工具(例如Firebug)通过Web提交表单。它会告诉您确切的HTTP请求内容,而不是Rails解释的内容。您可以使用该信息来构建所需的HTTP请求。

FYI Rails在键中使用成对的方括号来表示参数中的嵌套和数组。空方括号表示列表,而空心方括号表示另一层嵌套。具有无差别访问权限的哈希是一种哈希,它对用于访问哈希的所有键的字符串和符号进行隐式的to_s调用。

例:

当您创建这样的表单时:

var form = new NameValueCollection();
form["user[name]"] = "EmFi";
form["user[phone_number]" = "555-555-1234";
form["user[friend_ids][]" = "7";
form["user[friend_ids][]" = "8";
form["user[address][street_number]" = "75";
form["user[address][street_name]" = "Any St.";
form["user[address][province]" = "Ontario";
form["user[address][country]" = "Candad";
Run Code Online (Sandbox Code Playgroud)

然后将其传递给问题中发布的子例程,这是将为控制器提供的params hash rails:

params = {
  "user" => {
    "name" => "EmFi,
    "phone_number" => "555-555-1234",
    "friend_ids" => ["7","8"],
    "address" => {
      "street_number" => "75",
      "street_name" => "any St.",
      "province" => "Ontario",
      "country" => "Canada",
    }
  }
}
Run Code Online (Sandbox Code Playgroud)