1

Помогите пожалуйста со следующим вопросом:

Есть приложение Xamarin которое отправляет данные на сайт методом POST, На сайте проверяю, если ли такой параметр POST но вот проверка не проходит, как будто и нет параметра, проверял отправку данных через метод GET все работает отлично.

В текущем примере на сериализацию пускаю отдельный класс, в котором есть сериализуемый мне класс KVMglob.korzinaModel

Реализация класса korzinaModel ниже

Код отправки данных на сервер

string json = JsonConvert.SerializeObject(KVMglob.korzinaModel);

HttpContent content = new StringContent(json);

HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync(url, content);

HttpContent responseContent;


if (response.StatusCode == HttpStatusCode.OK)
{
    responseContent = response.Content;
    var json_new = await responseContent.ReadAsStringAsync();

}

Код класса, который сериализуется в JSON:

public class KorzinaModel 
{
    //...
    public int TotalSum { get; set; }
    //...
}

Обработчик на сайте PHP:

if(isset($_POST['TotalSum']))
{
    echo "true post";
}

UPD

при конвертировании моего объекта в JSON StringContent(json), он имеет тип text/plain и в коде PHP метод $_POST['TotalSum'] не сработает, подскажите, каким образом тогда можно отправить данные, чтобы его можно было прочитать в PHP через переменную $_POST['TotalSum']

  • 1
    Возможный дубликат вопроса: Отправить POST запрос – tym32167 Oct 20 '18 at 11:08
  • Сейчас попробую спасибо, если заработает отпишусь – Денис Oct 20 '18 at 11:18
  • если не заработает - тоже пишите, что попробовали и что не завелось - пишите это только в вопросе, а не в комментах – tym32167 Oct 20 '18 at 11:29
  • 1
    @tym32167 Ну вообще оно заработает, куда ж оно денется... но только если идти черезз FormUrlEncodedContent то тогда json не нужен, избыточен. Альтернатива - швырять прямо json, а на той стороне читать при помощи FromBody Так что топикстартеру нужно сначала определиться какой дорогой идти, а потом уже делать. И если объект "плоский", то можно и через FormUrlEncodedContent , а вот если объект сложный, с вложениями разных уровней - лучше FromBody. – A K Oct 20 '18 at 12:38
  • @tym32167 Коллеги, пример который был приложен в 1 комментарии мне не подходит, у меня сложный объект, класс, в котором пару переменных и один список, соответственно мне необходимо передать все данные класса на сервер, как мне это можно сделать? пример который я пытался реализовать, находится по ссылке:https://metanit.com/sharp/xamarin/10.3.php Но вот при отправке данных через POST условие существования переменной не срабатывает в PHP коде... – Денис Oct 20 '18 at 12:45
  • 1
    @Денис Вся ваша проблема в том, что вы не понимаете какой тип отправляете и пытаетесь принять. $_POST['TotalSum'] принимает данные application/x-www-form-urlencoded или multipart/form-data. StringContent(json) отправляет данные в text/plain. Так что тут вы должны выбрать то, что все же хотите отправить! Если text/plain - переписывайте PHP (я с ним не знаком, но вот как пример). Если же хотите принимать $_POST['TotalSum'] - переписывайте отправку данных. – EvgeniyZ Oct 20 '18 at 12:54
  • Уважаемый, я же вам документацию скинул. $_POST принимает только application/x-www-form-urlencoded или multipart/form-data. Как их отправить из C# вам в первом же комментарии ответили. Не устраивает этот вид данных, тогда отказывайтесь от $_POST, ибо он не предназначен для этого! Попробуйте использовать $HTTP_RAW_POST_DATA... – EvgeniyZ Oct 20 '18 at 13:09
  • @EvgeniyZ Нет, в этом случае надо из php://input (это предпочтительнее, чем HTTP_RAW_POST_DATA) - где-то у меня был ответ, когда я больше на php писал, чем на c#... Добавил в ответ ссылку. – A K Oct 20 '18 at 13:39
  • 1
    @AK Ну или так, я в PHP особо не разбираюсь. Просто странно видеть что после моего комментария с ссылкой на документацию, где явно написано о принимаемых типах появляется обновление в вопросе с текстом отправить данные, чтобы его можно было прочитать в PHP через переменную $_POST['TotalSum']. Тогда чем не устраивает первая ссылка, не пойму... – EvgeniyZ Oct 20 '18 at 13:46
  • Товарищи, связываться с JSON скорее всего не буду, т.к. небольшой парсинг на javascript придется писать в PHP

    @EvgeniyZ первый способ чем мне не нравился, что мне придется свой парс писать на вставку значений из массива, но видимо по всему придется его написать, в процессе реализации, как задачку решу, обязательно отмечу задачку решенной и приложу решение. Спасибо за вашу активную помощь

    – Денис Oct 20 '18 at 13:51
  • 2
    @Денис JSON это очень хороший вариант для передачи данных, но опять же, $_POST не принимает обычный текст, он создан для форм. Я бы на вашем место попросту переписал бы метод в PHP для приема текста. Можете пойти костыльным способом, отправляйте FormUrlEncodedContent с одним значением (скажем string Data) и в него засовывайте JSON. Тогда да, на PHP вы сможете сделать $_POST['Data']. Так что решайте, все необходимое мы вас вроде как разъяснили и показали... – EvgeniyZ Oct 20 '18 at 14:26
  • @EvgeniyZ опыта в отправке данных на сервер ранее не было, распарсить в C# и отправить данные так, чтобы читалось в PHP через $_POST получилось, но мне этот вариант не очень нравится, прислушаюсь к вашему совету, и "научу" PHP работать с JSON , ВСЕМ спасибо за помощь! =) – Денис Oct 20 '18 at 14:33
  • 1
    PHP не надо учить json, он уже давно умеет: см. json_decode – A K Oct 20 '18 at 14:43
  • @AK Благодарю, в теле вопроса внес информацию о том, как решил задачку, огромное спасибо)) – Денис Oct 20 '18 at 15:58
  • Не надо вносить в тело вопроса ваш ответ: вам нужно создать ещё один ответ и на нем уже поставить галку. – A K Oct 20 '18 at 16:46

2 Answers2

2

Есть два варианта отправки POST, вам нужно определиться какой вам больше подходит.

Первый вариант - это отправка данных через FormUrlEncodedContent, удобно для "плоских" данных вида ключ-значение.

Например, у вас есть плоский класс с десятками полей int или string:

public class MyRequest
{
    public int Id { get; set; }
}

Процедура отправки:

public async Task<string> Send(object request)
{
    var client = new HttpClient();
    const string serverUrl = "https://localhost:44365/api/values";

    var content = new FormUrlEncodedContent(request.AsDictionary().ToDictionary(x => x.Key, y => y.Value.ToString()));

    var response = await client.PostAsync(serverUrl, content);
return await response.Content.ReadAsStringAsync();
}

(Где extension .AsDictionary() - можно посмотреть здесь)

И, например, если у вас на той стороне asp.net то приёмник - примитивный экшн:

[HttpPost]
public ActionResult<string> Post(MyRequest request)
{
}

Второй вариант - когда у вас MyRequest - объект с многими уровнями вложенности и очень хочется отправить через Json.

Отправка (сериализуем при помощи Json.Net):

public async Task<string> Send(object request)
{
    var client = new HttpClient();
    const string serverUrl = "https://localhost:44365/api/values";

    var content = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json");

    var response = await client.PostAsync(serverUrl, content);

    return await response.Content.ReadAsStringAsync();
}

Приёмка:

[HttpPost]
public ActionResult<string> Post([FromBody]MyRequest request)
{
}

Если же у вас на той стороне сайт на PHP - то читайте php://input - у меня был подобный ответ, отправляю туда.

tym32167
  • 32,857
A K
  • 28,718
1

UPD что в итоге получилось) Код в C# не менял, так же сериализую свой класс в JSON

На стороне PHP обрабатываю данные следующим образом:

// получение данных в POST 
$postData = file_get_contents('php://input');
// преобразование в JSON , параметр true означает, что преобразовать в ассоциативный массив
$data = json_decode($postData, true);


// пример получения данных из ассоциативного массива
// в моев случае это был 1 массив типа объекта и 1 параметр, это общая сумма
$Name_item=$data['ItemsBuy'][0]['Name']; // 
$TotalSum=$data['TotalSum'];

ЗЫ Если возникло непонимание, почему мы не можете добраться до своих данных, то вот вам онлайн декодер JSON http://freeonlinetools24.com/json-decode Вставьте туда параметр $postData и он вам распарсит вашу строку Надеюсь кто сюда наткнется, получит ответ на свой вопрос

Еще раз всем огромное спасибо за помощь! =)