2015-10-11 2 views
3

Мне нужно взаимодействовать с конечной точкой третьей стороны, которая принимает только форму, закодированную полезную нагрузку. Конечной хочет сложные типы данных в этой конечной точке, а это означает что-то вроде этого (но образуют закодированы, а не JSON):Как использовать FormUrlEncodedContent для сложных типов данных?

{ 
    "foo": "bar", 
    "baz": { 
     "zip": "zap" 
    } 
} 

Мой прибегая к помощи и документы для конечной точки указывает на то, что это должно быть форма кодируется следующим образом:

foo=bar&baz[zip]=zap 

Я использую HttpClient и я хочу использовать FormUrlEncodedContent но когда я делаю это заменой моей [] с уцелевшими символами.

public class Tests 
{ 
    [Fact] 
    public void Test() 
    { 
     var content = new Dictionary<String, String> 
     { 
      { "foo", "bar" }, 
      { "baz[zip]", "zap" } 
     }; 
     var formContent = new FormUrlEncodedContent(content); 
     Assert.Equal("foo=bar&baz[zip]=zap", formContent.ReadAsStringAsync().Result); 
    } 
} 

То, что я в конечном итоге вместо этого:

foo=bar&baz%5Bzip%5D=zap 

ответ

1

Есть два вопроса, в вашем вопросе. Номер один:

Мой прибегая к помощи указывает на то, что это должно быть форма кодируется следующим образом:

foo=bar&baz[zip]=zap 

Нет. Там нет конвенции или стандарт, который преобразует Многомерные структуру ключ-значение в одномерный.

Если вы думаете об этом, такое преобразование очень быстро станет очень громоздким. Семантика объекта: много более выразительная, чем семантика URL-кодирования. FWIW, они даже не могут договориться о том, как кодировать простые массивы в URL-адреса, хотя это было бы легко возможно.

Поскольку нет стандарта, это сводится к созданию соглашения, с которым может жить сервер и клиент. Соглашение, что вызвало бы наименьшую головную боль и наименьший шанс неприятных ошибок будет (*):

  • сериализовать объект в JSON. Это дает вам строку.
  • Перенести эту строку как значение в параметр URL.
  • Сделайте реверс на принимающем конце.

Так что в JS вы могли бы сделать:

encodeURIComponent(JSON.stringify({ 
    "foo": "bar", 
    "baz": { 
     "zip": "zap" 
    } 
})); 

который дает

"%7B%22foo%22%3A%22bar%22%2C%22baz%22%3A%7B%22zip%22%3A%22zap%22%7D%7D" 

Это могут быть переданы безопасно в качестве параметра URL и обрабатывается с минимальными усилиями.

Для .NET вы можете выбрать несколько вариантов сериализации, два из которых являются DataContractJsonSerializer и JavaScriptSerializer, discussed over here.

Я бы настоятельно рекомендовал против вашей собственной схемы сериализации для этой задачи.


Номер два:

но когда я делаю это замена моим [] с уцелевшими символами.

Конечно. Ключи в парах ключ-значение, закодированные URL-адресами, подчиняются тем же правилам, что и значения. Пара, подобная {"a&b": "c&d"}, будет кодироваться как a%26b=c%26d. Фактически, вы можете отправить его как %61%26%62=%63%26%64. Другими словами, значения URL-декодирования, но забывающие об именах ключей URL-декодирования на принимающей стороне, являются ошибкой. Так что забудьте о URL-адресе , кодируя имена. Обсуждение того, какие символы можно использовать в какой форме в URL-адресе, - over here.


(*) Короткие «передачи данных, как Content-Type: application/json непосредственно, что является предпочтительным для выдавливания его в строку запроса.

+0

Как я уже упоминал в моем вопросе, я взаимодействовать с третьей стороной api, поэтому я не могу выбрать формат сериализации. В их документах есть пример скручивания с помощью '-d bar [zip] = zap', и Google предлагает, что, хотя он не является стандартным, это самый распространенный механизм для отправки сложных форм объектов, закодированных (Я думаю, что jquery делает это так) Я согласен с тем, что api не должен этого делать, но тем не менее мне приходится иметь дело с этим. –

+0

Как уже упоминалось в ответе, нет стандарта, и все основанный на конвенции. Нет. Функция .NET предоставит вам этот формат из коробки. Если ваша конечная точка документирует соглашение, которое она ожидает, вам нужно будет написать соответствующий сериализатор самостоятельно. – Tomalak

+0

@ Мика Извините, что это не то, что вам хотелось бы услышать, однако это не меняет того факта, что ответ правильный. :) – Tomalak

Смежные вопросы