Когда HTTP-POST имеет тело, параметр url имеет значение null - PullRequest
2 голосов
/ 16 марта 2012

Это веб-API RESTful MVC4 для собственного размещения, единственный маршрут - api/{controller}/{state}.Когда я отправляю HTTP-POST с телом, аргумент состояния принимает значение NULL.Если я удаляю тело, переменная состояния присутствует.

То, как я думал, что это работает для HTTP-POST, состояло в том, что параметры url отображаются, тогда тело сериализуется в дополнительный параметр, который в данном случае является даннымипараметр.Содержимое - это просто строковые данные, которые я должен был написать в собственном MediaTypeFormatter (который мне показался странным, он не мог обработать обычную строку).

Вот моя подпись контроллера

public class MyController : ApiController
{
    public void Post(string state, string data)
    {
    }
}

Кто-нибудь видел такое поведение раньше или может объяснить мне, почему присутствие тела влияет на мой параметр url?

1 Ответ

1 голос
/ 16 марта 2012

Одно решение: Я попытался изменить параметр данных в сложный тип (просто класс с открытым свойством) и отправить содержимое в виде text / xml вместо text / plain, и это сработало, как и ожидалось. Параметр состояния не был нулевым, и у меня был строго типизированный объект с данными. Я полагаю, что MVC хочет десериализовать что-то вроде XML или JSON для тела http-запроса ...

Больше исследований: У меня была возможность провести еще несколько тестов. Если телом поста является XML / JSON, то сначала он попытается сопоставить свойства объекта body с параметрами метода, например, так. Если свойства по-прежнему не сопоставлены, остальные свойства будут сопоставлены со свойствами любых строго типизированных объектов в параметрах метода

PostMethod(string p1, string p2, myClass obj) // if myClass has a p3 property it will be mapped from the xml body.
{
}

// xml in body of http-post
<Xml>
   </p1>
   </p2>
   </p3>
</Xml>

Если все параметры не были отображены, он попытается отобразить параметры URL. Связать это непосредственно с моей первоначальной проблемой. Лучшее и простое решение, которое я вижу на данный момент, - это отправить текст / xml следующим образом.

PostMethod(string state, string data)
{
}

<data>put data here</data>

Пары ключ / значение Urlencoded также работают очень хорошо.

var r = client.PostAsync(url, new StringContent("data=Something", Encoding.UTF8, "application/x-www-form-urlencoded"));

Мое лучшее предположение заключается в том, что природа ключа / значения в JSON и XML, FormEncoded, помогает ему сопоставляться с параметрами, поэтому ему не нравятся простые строки.

Это наверняка вызвало у меня головную боль, и я нахожу документацию MVC4 довольно скудной (она все еще находится в бета-версии), но я надеюсь, что это может помочь кому-то еще, у кого может быть такая же проблема.

...