Как отправить JSON на сервер с помощью С#?
Вот код, который я использую:
// create a request
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create(url); request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.Method = "POST";
// turn our request string into a byte stream
byte[] postBytes = Encoding.UTF8.GetBytes(json);
// this is important - make sure you specify type this way
request.ContentType = "application/json; charset=UTF-8";
request.Accept = "application/json";
request.ContentLength = postBytes.Length;
request.CookieContainer = Cookies;
request.UserAgent = currentUserAgent;
Stream requestStream = request.GetRequestStream();
// now send it
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
// grab te response and print it out to the console along with the status code
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string result;
using (StreamReader rdr = new StreamReader(response.GetResponseStream()))
{
result = rdr.ReadToEnd();
}
return result;
Когда я запускаю это, я всегда получаю 500 внутренних ошибок сервера.
Что я делаю неправильно?
Ответы
Ответ 1
Я делаю это и работаю так:
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"user\":\"test\"," +
"\"password\":\"bla\"}";
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Я написал библиотеку для более простого выполнения этой задачи, она находится здесь: https://github.com/ademargomes/JsonRequest
Надеюсь, это поможет.
Ответ 2
Решение Ademar можно улучшить, используя метод JavaScriptSerializer
Serialize
, чтобы обеспечить неявное преобразование объекта в JSON.
Кроме того, можно использовать функциональные возможности оператора using
по умолчанию, чтобы явно не вызывать Flush
и Close
.
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
user = "Foo",
password = "Baz"
});
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Ответ 3
Тип HttpClient
является более новой реализацией, чем WebClient
и HttpWebRequest
.
Вы можете просто использовать следующие строки.
string myJson = "{'Username': 'myusername','Password':'pass'}";
using (var client = new HttpClient())
{
var response = await client.PostAsync(
"http://yourUrl",
new StringContent(myJson, Encoding.UTF8, "application/json"));
}
![enter image description here]()
Когда вам нужен HttpClient
более одного раза, он рекомендует создать только один экземпляр и использовать его повторно или использовать новый HttpClientFactory
.
Ответ 4
В дополнение к сообщению Sean нет необходимости встраивать операторы using. По using
StreamWriter он будет очищен и закрыт в конце блока, поэтому нет необходимости явно вызывать методы Flush()
и Close()
:
var request = (HttpWebRequest)WebRequest.Create("http://url");
request.ContentType = "application/json";
request.Method = "POST";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
user = "Foo",
password = "Baz"
});
streamWriter.Write(json);
}
var response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Ответ 5
Позаботьтесь о том, какой тип контента вы используете:
application/json
Источники:
RFC4627
Другие сообщения
Ответ 6
Если вам нужно вызвать асинхронно, используйте
var request = HttpWebRequest.Create("http://www.maplegraphservices.com/tokkri/webservices/updateProfile.php?oldEmailID=" + App.currentUser.email) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "text/json";
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the stream request operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
// Create the post data
string postData = JsonConvert.SerializeObject(edit).ToString();
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
//Start the web request
request.BeginGetResponse(new AsyncCallback(GetResponceStreamCallback), request);
}
void GetResponceStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
{
string result = httpWebStreamReader.ReadToEnd();
stat.Text = result;
}
}
Ответ 7
Недавно я придумал гораздо более простой способ опубликовать JSON с дополнительным шагом перехода от модели в моем приложении. Обратите внимание, что вы должны сделать модель [JsonObject] для вашего контроллера, чтобы получить значения и выполнить преобразование.
Запрос:
var model = new MyModel();
using (var client = new HttpClient())
{
var uri = new Uri("XXXXXXXXX");
var json = new JavaScriptSerializer().Serialize(model);
var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await Client.PutAsync(uri,stringContent).Result;
...
...
}
Модель:
[JsonObject]
[Serializable]
public class MyModel
{
public Decimal Value { get; set; }
public string Project { get; set; }
public string FilePath { get; set; }
public string FileName { get; set; }
}
Серверная сторона:
[HttpPut]
public async Task<HttpResponseMessage> PutApi([FromBody]MyModel model)
{
...
...
}
Ответ 8
Эта опция не упоминается:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:9000/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var foo = new User
{
user = "Foo",
password = "Baz"
}
await client.PostAsJsonAsync("users/add", foo);
}
Ответ 9
Некоторый разный и чистый способ достичь этого - использовать HttpClient следующим образом:
public async Task<HttpResponseMessage> PostResult(string url, ResultObject resultObject)
{
using (var client = new HttpClient())
{
HttpResponseMessage response = new HttpResponseMessage();
try
{
response = await client.PostAsJsonAsync(url, resultObject);
}
catch (Exception ex)
{
throw ex
}
return response;
}
}
Ответ 10
Я наконец вызвал в режиме синхронизации, включив .Result
HttpResponseMessage response = null;
try
{
using (var client = new HttpClient())
{
response = client.PostAsync(
"http://localhost:8000/....",
new StringContent(myJson,Encoding.UTF8,"application/json")).Result;
if (response.IsSuccessStatusCode)
{
MessageBox.Show("OK");
}
else
{
MessageBox.Show("NOK");
}
}
}
catch (Exception ex)
{
MessageBox.Show("ERROR");
}
Ответ 11
var data = Encoding.ASCII.GetBytes(json);
byte[] postBytes = Encoding.UTF8.GetBytes(json);
Используйте ASCII вместо UFT8
Ответ 12
ПРЕДУПРЕЖДЕНИЕ! У меня очень сильный взгляд на эту тему.
Существующие веб-клиенты .NET не являются дружественными для разработчиков! WebRequest & WebClient - это яркий пример того, как "расстроить разработчика". Они многословны & сложно работать с; когда все, что вы хотите сделать, это простой запрос Post в С#. HttpClient решает некоторые проблемы, но все равно не дотягивает. Кроме того, документация Microsoft плохая… действительно плохая; если вы не хотите просеивать страницы и страницы технической рекламы.
Открытый исходный код для спасения. В качестве альтернативы есть три отличных бесплатных библиотеки NuGet с открытым исходным кодом. Слава Богу! Все они хорошо поддерживаются, документируются и, да, легко - исправляются... очень легко - работать с ними.
- ServiceStack.Text - быстро, легко и надежно.
- RestSharp - простой клиент API REST и HTTP
- Flurl - свободная, портативная, тестируемая клиентская библиотека HTTP
Между ними не так много, но я бы дал ServiceStack.Text небольшое преимущество...
- Звезды Github примерно одинаковы.
- Открытые проблемы & главное как быстро какие-то проблемы закрылись? ServiceStack получает здесь награду за самое быстрое решение проблемы и усиление. нет открытых вопросов.
- Документация? У всех есть отличная документация; однако ServiceStack выводит его на следующий уровень & ‘Золотой стандарт документации.
Хорошо, так как же выглядит Post Post в JSON в ServiceStack.Text?
var response = "http://example.org/login"
.PostJsonToUrl(new Login { Username="admin", Password="mypassword" });
Это одна строка кода. Краткий легко! Сравните приведенное выше с библиотеками .NETs Http.