C#中的JSON调用

36

我正在尝试使用C#进行json调用。我尝试了一下创建调用,但它没有起作用:

public bool SendAnSMSMessage(string message)
{
    HttpWebRequest request = (HttpWebRequest)
                             WebRequest.Create("http://api.pennysms.com/jsonrpc");
    request.Method = "POST";
    request.ContentType = "application/json";

    string json = "{ \"method\": \"send\", "+
                  "  \"params\": [ "+
                  "             \"IPutAGuidHere\", "+
                  "             \"msg@MyCompany.com\", "+
                  "             \"MyTenDigitNumberWasHere\", "+
                  "             \""+message+"\" " +
                  "             ] "+
                  "}";

    StreamWriter writer = new StreamWriter(request.GetRequestStream());
    writer.Write(json);
    writer.Close();

    return true;
}
任何关于如何使这个工作的建议将不胜感激。

1
你是否收到任何错误信息?你的“message”看起来是什么样子的?你是否使用了正确的API密钥? - Richard Marskell - Drackir
@Drackir - 我正在使用正确的API密钥(我使用电子邮件版本的API进行了测试,它可以正常工作)。我没有收到任何错误信息。我只是没有收到短信。消息只是一些简单的测试消息文本(“testing sms”(但不带引号))。 - Vaccano
1
你的回应在哪里?你发出了请求,但是你没有使用GetResponseStream吗? - Shiv Kumar
2
@Vaccano,您使用的是哪个版本的C#?如果您使用的是3.5 / 4.0版本,请看一下WCF REST Starter kit。他们有一个HttpClient类,使调用JSON(和其他)服务变得非常容易。您不必忙于处理原始的HttpWebRequest等。请查看此文档http://msdn.microsoft.com/en-us/library/ee391967.aspx向下滚动到使用HttpClient消费RESTful服务部分(靠近底部)。 - Shiv Kumar
@Shiv Kumar - 我不知道我需要一个响应(或如何获得它)。我对整个WebRequest的东西都很新。---我会看一下REST Starter kit。这是我所有代码中唯一的json调用,所以我不想添加太多基础设施来调用它。如果可以在不对我的代码库进行太多添加的情况下完成,则认为我会喜欢它。---我更改了我的代码以使用text/json,但仍然无法工作。但感谢您提供的提示。 - Vaccano
显示剩余2条评论
5个回答

42

在你的代码中,你没有获取HttpResponse,因此你看不到服务器端返回给你的内容。

你需要以类似于获取(构造)请求的方式获取响应。所以

public static bool SendAnSMSMessage(string message)
{
  var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://api.pennysms.com/jsonrpc");
  httpWebRequest.ContentType = "text/json";
  httpWebRequest.Method = "POST";

  using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
  {
    string json = "{ \"method\": \"send\", " +
                      "  \"params\": [ " +
                      "             \"IPutAGuidHere\", " +
                      "             \"msg@MyCompany.com\", " +
                      "             \"MyTenDigitNumberWasHere\", " +
                      "             \"" + message + "\" " +
                      "             ] " +
                      "}";

    streamWriter.Write(json);
  }
  var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
  using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
  {
    var responseText = streamReader.ReadToEnd();
    //Now you have your response.
    //or false depending on information in the response
    return true;        
  }
}

我还注意到在pennysms的文档中,他们期望的内容类型是"text/json"而不是"application/json"。这可能没有什么区别,但值得尝试,以防它不起作用。


我正在寻找的是 text/json。我有一个 REST 服务,但它总是返回 XML,因为没有设置 application/json。??? - Davut Gürbüz

8

我只是在继续@Mulki的代码

public string WebRequestinJson(string url, string postData)
{
    string ret = string.Empty;

    StreamWriter requestWriter;

    var webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
    if (webRequest != null)
    {
        webRequest.Method = "POST";
        webRequest.ServicePoint.Expect100Continue = false;
        webRequest.Timeout = 20000;

        webRequest.ContentType = "application/json";
        //POST the data.
        using (requestWriter = new StreamWriter(webRequest.GetRequestStream()))
        {
            requestWriter.Write(postData);
        }
    }

    HttpWebResponse resp = (HttpWebResponse)webRequest.GetResponse();
    Stream resStream = resp.GetResponseStream();
    StreamReader reader = new StreamReader(resStream);
    ret = reader.ReadToEnd();

    return ret;
}

7
这里是Shiv Kumar答案的一个变体,使用Newtonsoft.Json(又称Json.NET):
public static bool SendAnSMSMessage(string message)
{
    var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://api.pennysms.com/jsonrpc");
    httpWebRequest.ContentType = "text/json";
    httpWebRequest.Method = "POST";

    var serializer = new Newtonsoft.Json.JsonSerializer();
    using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
    {
        using (var tw = new Newtonsoft.Json.JsonTextWriter(streamWriter))
        {
             serializer.Serialize(tw, 
                 new {method= "send",
                      @params = new string[]{
                          "IPutAGuidHere", 
                          "msg@MyCompany.com",
                          "MyTenDigitNumberWasHere",
                          message
                      }});
        }
    }
    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
    {
        var responseText = streamReader.ReadToEnd();
        //Now you have your response.
        //or false depending on information in the response
        return true;        
    }
}

4
如果您的函数位于MVC控制器中,您可以使用以下代码和要转换为JSON的字典对象。
Json(someDictionaryObj, JsonRequestBehavior.AllowGet);

如果您正在使用 .net 3.5,请尝试查看 system.web.script.serialization.javascriptserializer

至于您的 Web 请求……乍一看似乎没问题。

我会使用类似这样的东西……

public void WebRequestinJson(string url, string postData)
    {
    StreamWriter requestWriter;

    var webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
    if (webRequest != null)
    {
        webRequest.Method = "POST";
        webRequest.ServicePoint.Expect100Continue = false;
        webRequest.Timeout = 20000;

        webRequest.ContentType = "application/json";
        //POST the data.
        using (requestWriter = new StreamWriter(webRequest.GetRequestStream()))
        {
            requestWriter.Write(postData);
        }
    }
}

也许你可以将帖子和JSON字符串作为参数,并将其用作通用Web请求方法,以处理所有调用。

这是什么意思:var webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest; 为什么不直接写成:HttpWebRequest webRequest = System.Net.WebRequest.Create(url); - Richard Marskell - Drackir
4
@Drackir,WebRequest是一个抽象类。它的静态Create方法(本质上是一个工厂方法)根据Uri方案创建适当类的实例。也就是说,如果Uri方案被确定为“http”,那么它将创建HttpWebRequest的实例。如果是“ftp”,它将创建FtpWebRequest的实例。通过使用"as"语句,变量webRequest会被定义为HttpWebRequest的实例,这样特定于该类的属性和方法就可以使用了。这有意义吗?我建议将变量命名为httpWebRequest(只是为了更清晰明了)。 - Shiv Kumar
这是MSDN文档,以防万一。http://msdn.microsoft.com/en-us/library/bw00b1dc.aspx - Shiv Kumar
唉,我没有使用MVC。不过我会尝试你对我的Web请求所做的更改。 - Vaccano

1
这只是一个示例,展示了如何在BIDS 2008中使用System.Net.WebRequest发布Json数据并获取Json数据,而不使用newtonsoft。这只是一个示例代码,肯定可以进行优化(经过充分测试,它可以完美地完成我的测试目的)。仅供您参考。请注意保留html标签。我想要这个线程,但找不到相关信息,因此发布此贴。这些是我从中获取信息的主要来源:链接1链接2
有效的代码(已经进行了单元测试):
           //Get Example
            var httpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("https://abc.def.org/testAPI/api/TestFile");
            httpWebRequest.ContentType = "application/json";
            httpWebRequest.Method = "GET";

            var username = "usernameForYourApi";
            var password = "passwordForYourApi";

            var bytes = Encoding.UTF8.GetBytes(username + ":" + password);
            httpWebRequest.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(bytes));
            var httpResponse = (System.Net.HttpWebResponse)httpWebRequest.GetResponse();
            using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                string result = streamReader.ReadToEnd();
                Dts.Events.FireInformation(3, "result from readng stream", result, "", 0, ref fireagain);
            }


            //Post Example
            var httpWebRequestPost = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("https://abc.def.org/testAPI/api/TestFile");
            httpWebRequestPost.ContentType = "application/json";
            httpWebRequestPost.Method = "POST";
            bytes = Encoding.UTF8.GetBytes(username + ":" + password);
            httpWebRequestPost.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(bytes));

            //POST DATA newtonsoft didnt worked with BIDS 2008 in this test package
            //json https://dev59.com/Tm025IYBdhLWcg3wIyKf
            // fill File model with some test data
            CSharpComplexClass fileModel = new CSharpComplexClass();
            fileModel.CarrierID = 2;
            fileModel.InvoiceFileDate = DateTime.Now;
            fileModel.EntryMethodID = EntryMethod.Manual;
            fileModel.InvoiceFileStatusID = FileStatus.NeedsReview;
            fileModel.CreateUserID = "37f18f01-da45-4d7c-a586-97a0277440ef";
            string json = new JavaScriptSerializer().Serialize(fileModel);
            Dts.Events.FireInformation(3, "reached json", json, "", 0, ref fireagain);
            byte[] byteArray = Encoding.UTF8.GetBytes(json);
            httpWebRequestPost.ContentLength = byteArray.Length;
            // Get the request stream.  
            Stream dataStream = httpWebRequestPost.GetRequestStream();
            // Write the data to the request stream.  
            dataStream.Write(byteArray, 0, byteArray.Length);
            // Close the Stream object.  
            dataStream.Close();
            // Get the response.  
            WebResponse response = httpWebRequestPost.GetResponse();
            // Display the status.  
            //Console.WriteLine(((HttpWebResponse)response).StatusDescription);
            Dts.Events.FireInformation(3, "Display the status", ((HttpWebResponse)response).StatusDescription, "", 0, ref fireagain);
            // Get the stream containing content returned by the server.  
            dataStream = response.GetResponseStream();
            // Open the stream using a StreamReader for easy access.  
            StreamReader reader = new StreamReader(dataStream);
            // Read the content.  
            string responseFromServer = reader.ReadToEnd();
            Dts.Events.FireInformation(3, "responseFromServer ", responseFromServer, "", 0, ref fireagain);

在我的BIDS 2008测试脚本任务中(具有SP1和3.5框架),存在引用。 在此输入图片描述


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