使用HttpClient发送POST请求时,服务器看到一个空的Json文件。

3
我将通过C#中的HttpClient发送序列化的Json,但是服务器看到的是一个空对象。
主要的工作部分如下所示:
public void create_user(string Email, string Pass)
    {
        try {
            login_information user = new login_information (){ email = Email, pass = Pass };
            MemoryStream stream = new MemoryStream ();
            json_functions.serializer (user, user.GetType (), ref stream);
            HttpContent content = new StreamContent (stream);
            HttpResponseMessage response = client.PostAsync ("user/create", content).Result;
            if (response.IsSuccessStatusCode) {

            }
        } catch (Exception e) {
            string err = e.ToString ();
        }
    }

我还使用了一个辅助函数将类序列化为MemoryStream,然后使用该字符串从StreamContent类创建我的HttpContent。

这是json序列化辅助函数:

static public void serializer (Object o, Type T, ref MemoryStream S)
    {
        System.Runtime.Serialization.Json.DataContractJsonSerializer s = new System.Runtime.Serialization.Json.DataContractJsonSerializer (T);
        s.WriteObject (S, o);
    }

被序列化的类:

[DataContract]
public class login_information
{
    [DataMember]
    public string email;
    [DataMember]
    public string pass;
}

以下是 Resting API 需要的内容:
{
email:"email@example.com",
pass:"$ExamPLePasSworD$"
}

据我所知,这是创建json文件并将其发送到REST API的正确方法。然而,服务器仍将其读取为空。任何帮助都将不胜感激!

请尝试在不使用异步的情况下编写代码。 - Scott Selby
1
他正在异步方法上调用 .Result,这将会阻塞直到它返回结果。 - NWard
4个回答

22

最可能的问题是您将数据写入了内存流中,但从未重置Position - 因此,当您调用new StreamContent(stream);时,在流的当前位置之后没有任何内容。

解决方法:重新创建内存流或重置位置:

stream.Position = 0;
HttpContent content = new StreamContent (stream);

我重置了流的位置,但在服务器上它仍然显示为空的Json文件。不过那是个好主意! - Xirdie
@Xirdie 使用 Fiddler(或您选择的其他 HTTP 调试工具)并观察您实际发送的内容... 进行调试并确保内存流实际包含正确的信息。 - Alexei Levenkov

3
如果有人在未来遇到这个问题,我最近找到了一个对我有效的解决方案!
我最终使用了json.net库来确保我的编码是正确的,这反过来给了我一个字符串而不是一个字符串。但是,这并没有帮助我。在StringContent类的构造函数中,我注意到您可以指定内容类型,并且默认为空格。所以
HttpContent content = new StreamContent (stream);

变成:

HttpContent content = new StringContent(content, Encoding.UTF8, "application/json")).Result;

一旦我指定它是一个JSON,接收Rest API就能读取内容。感谢大家的所有帮助,祝愿其他人编码愉快!


0
我认为你需要等待client.PostAsync。
忍者编辑(抱歉):
该行将如下所示:
HttpResponseMessage response = await client.PostAsync ("user/create", content).Result;

你还需要将方法签名更改为:

public async Task CreateUser(string Email, string Pass)

然后你必须等待这个方法!


0

StreamContent没有像接受的答案中StringContent那样方便地指定Content-Type头的构造函数。如果需要,您仍然可以使用流,在单独的一行上指定内容类型。

替换为:

HttpContent content = new StreamContent (stream);
HttpResponseMessage response = client.PostAsync ("user/create", content).Result;

使用这个:

HttpContent content = new StreamContent (stream);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpResponseMessage response = client.PostAsync ("user/create", content).Result;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接