如何使用 C# 将 JSON 发布到服务器?

发布于 2025-01-02 22:10:17 字数 1078 浏览 0 评论 0 原文

这是我正在使用的代码:

// 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 内部服务器错误。

我做错了什么?

Here's the code I'm using:

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

When I'm running this, I'm always getting 500 internal server error.

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

原谅过去的我 2025-01-09 22:10:17

我这样做和工作的方式是:

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

The way I do it and is working is:

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

I wrote a library to perform this task in a simpler way, it is here: https://github.com/ademargomes/JsonRequest

小清晰的声音 2025-01-09 22:10:17

Ademar 的解决方案可以通过利用 JavaScriptSerializerSerialize 方法来改进,以提供对象到 JSON 的隐式转换。

此外,还可以利用 using 语句的默认功能来省略显式调用 FlushClose

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

Ademar's solution can be improved by leveraging JavaScriptSerializer's Serialize method to provide implicit conversion of the object to JSON.

Additionally, it is possible to leverage the using statement's default functionality in order to omit explicitly calling Flush and 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();
}
雨巷深深 2025-01-09 22:10:17

HttpClient 类型是较新的类型实现优于 WebClientHttpWebRequestWebClientWebRequest 均已被标记为过时。 [1]

您只需使用以下几行。

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

当您多次需要 HttpClient 时,建议仅创建一个实例并重用它或使用新的 HttpClientFactory[2]

对于FTP,由于HttpClient不支持,我们建议使用第三方库。

@learn.microsoft.com [3]


自 dotnet core 3.1 您可以使用 JsonSerializer 来自 System.Text.Json 创建 json 字符串。

string myJson = JsonSerializer.Serialize(credentialsObj);

The HttpClient type is a newer implementation than the WebClient and HttpWebRequest. Both the WebClient and WebRequest have been marked as obsolete. [1]

You can simply use the following lines.

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

When you need your HttpClient more than once it's recommended to only create one instance and reuse it or use the new HttpClientFactory. [2]

For FTP, since HttpClient doesn't support it, we recommend using a third-party library.

@learn.microsoft.com [3]


Since dotnet core 3.1 you can use the JsonSerializer from System.Text.Json to create your json string.

string myJson = JsonSerializer.Serialize(credentialsObj);
君勿笑 2025-01-09 22:10:17

根据 Sean 的帖子,没有必要嵌套 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();
}

Further to Sean's post, it isn't necessary to nest the using statements. By using the StreamWriter it will be flushed and closed at the end of the block so no need to explicitly call the Flush() and Close() methods:

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();
}
兮颜 2025-01-09 22:10:17

如果您需要异步调用,请使用

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

    }

If you need to call is asynchronously then use

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

    }
红尘作伴 2025-01-09 22:10:17

我最近想出了一种更简单的方法来发布 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)
{
    // ...
}

I recently came up with a much simpler way to post a JSON, with the additional step of converting from a model in my app. Note that you have to make the model [JsonObject] for your controller to get the values and do the conversion.

Request:

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

Model:

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

Server side:

[HttpPut]     
public async Task<HttpResponseMessage> PutApi([FromBody]MyModel model)
{
    // ...
}
度的依靠╰つ 2025-01-09 22:10:17

注意您正在使用的内容类型:

application/json

来源:

RFC4627

其他帖子

Take care of the Content-Type you are using :

application/json

Sources :

RFC4627

Other post

猥︴琐丶欲为 2025-01-09 22:10:17

到 .Net 4.5.1 此选项 可以工作:

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

Up to .Net 4.5.1 this option can work:

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);
}
夏见 2025-01-09 22:10:17

警告!我对此主题有非常强烈的看法。

.NET 现有的 Web 客户端对开发人员不友好! WebRequest & WebClient 是“如何让开发人员感到沮丧”的主要示例”。它们很冗长且冗长。操作复杂;当您只想用 C# 发送一个简单的 Post 请求时。 HttpClient 在解决这些问题方面有所作为,但它仍然存在不足。最重要的是,微软的文档很糟糕……真的很糟糕;除非你想筛选一页又一页的技术简介。

开源来救援。有三个优秀的开源、免费 NuGet 库作为替代方案。谢天谢地!这些都得到了很好的支持和记录,是的,很容易修正……超级容易使用。

  • ServiceStack.Text - 快速、轻便且有弹性。
  • RestSharp - 简单的 REST 和 HTTP API 客户端
  • Flurl - 一个流畅、可移植、可测试的 HTTP 客户端库

它们之间没有太多区别,但我认为 ServiceStack.Text 稍占优势……

  • Github 星 大致是相同的。
  • 未解决的问题和问题重要的是,问题解决的速度有多快? ServiceStack 因最快的问题解决和解决速度而荣获此奖。没有未解决的问题。
  • 文档?都有很棒的文档;然而,ServiceStack 将其提升到了一个新的水平。以其文档的“黄金标准”而闻名。

好的 - 那么 JSON 格式的 Post 请求在 ServiceStack.Text 中是什么样子的?

var response = "http://example.org/login"
    .PostJsonToUrl(new Login { Username="admin", Password="mypassword" });

这是一行代码。简洁&简单的!将以上内容与 .NET 的 Http 库进行比较。

WARNING! I have a very strong view on this subject.

.NET’s existing web clients are not developer friendly! WebRequest & WebClient are prime examples of "how to frustrate a developer". They are verbose & complicated to work with; when all you want to do is a simple Post request in C#. HttpClient goes some way in addressing these issues, but it still falls short. On top of that Microsoft’s documentation is bad … really bad; unless you want to sift through pages and pages of technical blurb.

Open-source to the rescue. There are three excellent open-source, free NuGet libraries as alternatives. Thank goodness! These are all well supported, documented and yes, easy - correction…super easy - to work with.

There is not much between them, but I would give ServiceStack.Text the slight edge …

  • Github stars are roughly the same.
  • Open Issues & importantly how quickly any issues closed down? ServiceStack takes the award here for the fastest issue resolution & no open issues.
  • Documentation? All have great documentation; however, ServiceStack takes it to the next level & is known for its ‘Golden standard’ for documentation.

Ok - so what does a Post Request in JSON look like within ServiceStack.Text?

var response = "http://example.org/login"
    .PostJsonToUrl(new Login { Username="admin", Password="mypassword" });

That is one line of code. Concise & easy! Compare the above to .NET’s Http libraries.

⊕婉儿 2025-01-09 22:10:17

实现此目的的一些不同且干净的方法是使用 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;
     }
}

Some different and clean way to achieve this is by using HttpClient like this:

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;
     }
}
戏蝶舞 2025-01-09 22:10:17

我最终通过包含 .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");
}

I finally invoked in sync mode by including the .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");
}
小糖芽 2025-01-09 22:10:17

我发现这是发布读取的 JSON 数据的最友好、最简洁的方式:

var url = @"http://www.myapi.com/";
var request = new Request { Greeting = "Hello world!" };
var json = JsonSerializer.Serialize<Request>(request);
using (WebClient client = new WebClient())
{
    var jsonResponse = client.UploadString(url, json);
    var response = JsonSerializer.Deserialize<Response>(jsonResponse);
}

我使用 Microsoft 的 System.Text.Json 来序列化和反序列化 JSON。请参阅 NuGet

I find this to be the friendliest and most concise way to post an read JSON data:

var url = @"http://www.myapi.com/";
var request = new Request { Greeting = "Hello world!" };
var json = JsonSerializer.Serialize<Request>(request);
using (WebClient client = new WebClient())
{
    var jsonResponse = client.UploadString(url, json);
    var response = JsonSerializer.Deserialize<Response>(jsonResponse);
}

I'm using Microsoft's System.Text.Json for serializing and deserializing JSON. See NuGet.

§普罗旺斯的薰衣草 2025-01-09 22:10:17

我就是这样做的

//URL
var url = "http://www.myapi.com/";

//Request
using var request = new HttpRequestMessage(HttpMethod.Post, url);

//Headers
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Cache-Control", "no-cache");

//Payload
var payload = JsonConvert.SerializeObject(
    new
    {
        Text = "Hello world"
    });
request.Content = new StringContent(payload, Encoding.UTF8, "application/json");

//Send
var response = await _httpClient.SendAsync(request);

//Handle response
if (response.IsSuccessStatusCode)
    return;

This is how I do it

//URL
var url = "http://www.myapi.com/";

//Request
using var request = new HttpRequestMessage(HttpMethod.Post, url);

//Headers
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Cache-Control", "no-cache");

//Payload
var payload = JsonConvert.SerializeObject(
    new
    {
        Text = "Hello world"
    });
request.Content = new StringContent(payload, Encoding.UTF8, "application/json");

//Send
var response = await _httpClient.SendAsync(request);

//Handle response
if (response.IsSuccessStatusCode)
    return;
墨洒年华 2025-01-09 22:10:17

Dot net core 解决方案

首先使用 Newtonsoft.Json,然后编写如下方法:

    public static string? LoginToken()
    {
        var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method = "POST";

        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        {
           //  write your json content here
            string json = JsonConvert.SerializeObject(new
            {
                userName = ApiOptions.Username,
                password = ApiOptions.Password
            }
            );


            streamWriter.Write(json);
        }

        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            var result = streamReader.ReadToEnd();
            return result;
        }

    }

该方法返回 string。如果您想将 string 结果反序列化为 JSON,只需在方法末尾添加此行:

var result = streamReader.ReadToEnd();               
var json_result = JsonConvert.DeserializeObject<LoginTokenResponse>(result); // + add this code
        

其中 LoginTokenResponse 是您的自定义类想要反序列化字符串结果

Dot net core solution

first using Newtonsoft.Json then write a method like this:

    public static string? LoginToken()
    {
        var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method = "POST";

        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        {
           //  write your json content here
            string json = JsonConvert.SerializeObject(new
            {
                userName = ApiOptions.Username,
                password = ApiOptions.Password
            }
            );


            streamWriter.Write(json);
        }

        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            var result = streamReader.ReadToEnd();
            return result;
        }

    }

This method return string. if you want to deserialize the string result to JSON, simply add this line at the end of the method:

var result = streamReader.ReadToEnd();               
var json_result = JsonConvert.DeserializeObject<LoginTokenResponse>(result); // + add this code
        

Which LoginTokenResponse is the custom class you want to Deserialize the string result

∞琼窗梦回ˉ 2025-01-09 22:10:17

var data = Encoding.ASCII.GetBytes(json);

byte[] postBytes = Encoding.UTF8.GetBytes(json);

使用 ASCII 而不是 UFT8

var data = Encoding.ASCII.GetBytes(json);

byte[] postBytes = Encoding.UTF8.GetBytes(json);

Use ASCII instead of UFT8

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文