这是我正在使用的代码:

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

我在做什么错?

评论

首先,请确保您发布的数据是服务器所期望的。

实际上,看起来我正在发布无效数据...

为了简化工作,您也可以将json库添加到Visual Studio中

@Arsen-服务器不应因格式错误的数据而崩溃。提交错误报告。

#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

希望对您有所帮助。

评论


我认为json字符串行应为:string json =“ {\” user \“:\” test \“,” +“ \” password \“:\” bla \“}”;看来您缺少\

–梦巷
13年2月26日在17:00

始终使用“ application / json”(除非出于某些其他原因需要文本/ json,例如:entwicklungsgedanken.de/2008/06/06/…)。撰写文章至:stackoverflow.com/questions/477816/…。

– Yaniv
2015年5月9日21:43

我本以为streamWriter.Flush();和streamWriter.Close();不需要,因为您位于using块内。在using块的末尾,流编写器将始终关闭。

–Ruchira
16年1月19日,0:04

不要手动构建JSON。容易犯允许JSON注入的错误。

–佛罗里达冬季
17年2月27日在14:08

@ user3772108请参阅stackoverflow.com/a/16380064/2279059。使用JSON库(例如Newtonsoft JSON.Net),并从对象渲染JSON字符串,或使用序列化。我知道这里为简化起见省略了此操作(尽管简单性获得的好处很小),但是格式化结构化数据字符串(JSON,XML等)太危险了,即使在琐碎的情况下也无法做到这一点,并且鼓励人们复制此类代码。

–佛罗里达冬季
17-10-25在8:37



#2 楼

通过使用JavaScriptSerializerSerialize方法来提供对象到JSON的隐式转换,可以改进Ademar的解决方案。另外,可以利用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();
}


评论


此代码与上面的代码有什么区别,我错过了什么吗?

– JMK
2014年6月24日19:07

这使用JavaScriptSerializer的Serialize方法创建有效的JSON,而不是手工制作。

–塞恩·安德森(Sean Anderson)
14年6月24日在22:26

请参阅下面的Jean F的答案-应该是评论。注意内容类型application / json是正确的。

–卢卡斯
2015年6月2日,2:30

@SeanAnderson我一直遇到“无法连接到远程服务器”错误。

–ralphgabb
15年6月2日在7:38

@LuzanBaral您只需要一个程序集:System.Web.Extensions

–诺布雷希特
17年5月24日在11:58

#3 楼

HttpClient类型是比WebClientHttpWebRequest更新的实现。
您可以简单地使用以下几行。
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

评论


关于HttpClient的一点说明,一般的共识是您不应该丢弃它。即使实现了IDisposable对象,该对象也是线程安全的,可以重用。 stackoverflow.com/questions/15705092/…

–吉恩·F。
18年11月14日在23:07

@JeanF。谢谢您的输入。正如我已经指出的那样,您应该只创建一个实例或使用HttpClientFactory。我没有阅读链接问题中的所有答案,但我认为它需要更新,因为它没有提及工厂。

– NtFreX
18年15月15日在8:03

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


评论


现在,这个答案与肖恩·安德森的答案完全相同,就像肖恩编辑了他的帖子一样。

– faza
18年4月8日在2:55

嘿,太好了,谢谢,但是如果我们在json上有子节点,我们该如何传递数据呢?

–user2728409
19年6月26日在5:09

序列化程序可以处理json中的子节点-您只需为其提供有效的json对象。

–大卫·克拉克(David Clarke)
19年6月26日在10:34

#5 楼

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

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

    }


评论


感谢您发布此解决方案Vivek。在我们的场景中,我们尝试了本文中的另一种解决方案,并最终在我们的应用程序中看到了System.Threading异常,这是由于我认为是同步帖子阻塞了线程。您的代码解决了我们的问题。

–肯·帕尔默(Ken Palmer)
16年11月22日在16:02

请注意,您可能不必转换为字节。您应该能够执行postStream.Write(postData);。 -并且取决于API,可能必须使用request.ContentType =“ application / json”;而不是text / json。

–vapcguy
4月22日下午5:19

#6 楼

照顾好您正在使用的Content-Type:

application/json


来源:


其他帖子

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


评论


从.Net 4.5.2开始,此选项不再可用。看到这里stackoverflow.com/a/40525794/2161568

– Downhillski
16 Dec 3'在0:58



那不是拒绝这个答案的好理由,因为不是每个人都使用最新版本的.net,因此这是一个有效的答案。

– Ellisan
18年8月6日在9:02

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


评论


很有帮助,但是从.NET 4.5.2开始,PostAsJsonAsync不再可用。请改用PostAsync。这里更多

– hbd
17年7月17日在19:02



通常不应该在这样的using语句中使用HttpClient

– p3tch
18-10-31在14:04

我认为它实现IDisposable接口是有原因的

–迪马·达隆(Dima Daron)
18年11月8日14:50



这在.net core 2.1中有效,并且是一个非常干净的选项。如果注入httpClient,它将变成1行json Post。

– Alex-v-s
8月6日0:50

#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 楼

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

.NET的现有Web客户端对开发人员不友好! WebRequest和WebClient是“如何挫败开发人员”的主要示例。它们冗长而复杂。当您要做的只是在C#中执行一个简单的Post请求。 HttpClient可以解决这些问题,但是仍然不足。最重要的是,Microsoft的文档很糟糕……确实很糟糕;除非您要浏览技术性文章的页面和其他页面。

开源以进行救援。有三种出色的开源免费NuGet库可供选择。谢天谢地!这些都得到了很好的支持和记录,是的,很容易-纠正...超级容易-可以使用。



ServiceStack.Text-快速,轻便和灵活。

RestSharp-简单的REST和HTTP API客户端

Flurl-一个流畅,可移植,可测试的HTTP客户端库

它们之间没有太多关系,但是我会给ServiceStack.Text带来一点优势…



Github的星号大致相同。

未解决的问题,而且重要的是,任何问题关闭的速度有多快? ServiceStack在这里以最快的问题解决速度和没有未解决的问题而获奖。

文档?所有人都有很好的文档。但是,ServiceStack将其提升到了一个新水平,并以其“黄金标准”而闻名。

好-那么在ServiceStack.Text中,JSON中的Post Request看起来如何?

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


那是一行代码。简洁易用!将以上内容与.NET的Http库进行比较。

#12 楼

我发现这是发布读取的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。

#13 楼

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

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

使用ASCII代替UFT8

评论


听起来是个坏主意,我想念什么吗?

–Cyber​​Fox
17年4月24日,1:15

JSON可以包含UTF8字符,这似乎是一个糟糕的主意。

–艾德里安·史密斯(Adrian Smith)
18-09-14在18:48