Как вручную создать параметры POST, которые являются вложенными? (например, я создаю запрос в .Net для связи с бэкэндом Rails) - PullRequest
1 голос
/ 07 декабря 2009

Как вручную создать вложенные параметры POST для веб-запроса http? У меня есть клиент .NET C #, для которого я создаю HTTP-запрос к странице Rails. Пока все хорошо, однако я заметил, что параметры, которые я создаю для запроса (пары ключ / значение), как ожидается, будут вложенными. Я на самом деле также испытываю трудности, пытаясь выработать в контроллере before_filter, как выполнить «вставку» необработанного содержимого запроса, чтобы увидеть, как успешный запрос форматирует его.

ОЖИДАНИЕ НАЗАД ЖЕЛЕЗНОДОРОЖНЫХ (успешный вход в систему, когда я звонил из браузера (не .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

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

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;
        }
    }

Спасибо

PS. В частности, я думаю, что я после того, как: * как Rails сериализует параметр / хэш вложенной формы в фактическое тело HTTP-запроса и / или * указатель на определенный класс в кодовой базе Rails, который делает это (поэтому я могу посмотреть, а затем эмулировать в моем клиенте .net)

Ответы [ 2 ]

4 голосов
/ 07 декабря 2009

Вам не совсем понятно, что вы пытаетесь сделать здесь. Поэтому я не думаю, что мы сможем решить эту проблему для вас.

Лучшее, что я могу предложить, - это отправить форму через Интернет с помощью инструмента, который отслеживает запросы, например Firebug . Он точно скажет вам, что находится в 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";

затем передайте его подпрограмме, размещенной в вопросе, это хеш-коды params предоставят контроллеру:

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",
    }
  }
}
1 голос
/ 07 мая 2012

отправляю вложенные параметры карты в groovy

// параметры def attrs = [a: 'A', m: [b: 'B'], c: 'C']

def http = новый HTTPBuilder ('http://www.websitexyz.com')

    http.request(Method.POST, ContentType.TEXT) { req ->
            send ContentType.URLENC, attrs
 // executed for all successful responses:
 response.success = { resp, reader ->
   println 'my response handler!'
   assert resp.statusLine.statusCode == 200
   println resp.statusLine
   System.out << reader // print response stream
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...