从 .NET 控制台调用 JSON WebService 的最佳方式

Posted

技术标签:

【中文标题】从 .NET 控制台调用 JSON WebService 的最佳方式【英文标题】:Best way to call a JSON WebService from a .NET Console 【发布时间】:2012-01-06 09:56:14 【问题描述】:

我在 ASP.Net MVC3 中托管一个 Web 服务,它返回一个 Json 字符串。从 c# 控制台应用程序调用 web 服务并将返回解析为 .NET 对象的最佳方法是什么?

我应该在我的控制台应用程序中引用 MVC3 吗?

Json.Net 有一些很好的方法来序列化和反序列化 .NET 对象,但我没有看到它有从 web 服务发布和获取值的方法。

或者我应该创建自己的帮助方法来发布和获取网络服务吗?如何将我的 .net 对象序列化为键值对?

【问题讨论】:

【参考方案1】:

我使用 HttpWebRequest 从 Web 服务获取,它返回一个 JSON 字符串。对于 GET,它看起来像这样:

// Returns JSON string
string GET(string url) 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    try 
        WebResponse response = request.GetResponse();
        using (Stream responseStream = response.GetResponseStream()) 
            StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8);
            return reader.ReadToEnd();
        
    
    catch (WebException ex) 
        WebResponse errorResponse = ex.Response;
        using (Stream responseStream = errorResponse.GetResponseStream())
        
            StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.GetEncoding("utf-8"));
            String errorText = reader.ReadToEnd();
            // log errorText
        
        throw;
    

然后我使用JSON.Net 来动态解析字符串。 或者,您可以使用此 codeplex 工具从示例 JSON 输出静态生成 C# 类:http://jsonclassgenerator.codeplex.com/

POST 看起来像这样:

// POST a JSON string
void POST(string url, string jsonContent) 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";

    System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    Byte[] byteArray = encoding.GetBytes(jsonContent);

    request.ContentLength = byteArray.Length;
    request.ContentType = @"application/json";

    using (Stream dataStream = request.GetRequestStream()) 
        dataStream.Write(byteArray, 0, byteArray.Length);
    
    long length = 0;
    try 
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
            length = response.ContentLength;
        
    
    catch (WebException ex) 
        // Log exception and throw as for GET example above
    

我在我们的网络服务的自动化测试中使用这样的代码。

【讨论】:

JsonClassGenerator 很棒。反序列化很容易,因为您只需通过传递 json 字符串来构造强类型对象。 如果你有非ascii字符集,你的代码需要修改一下。 ContentLength 表示发布内容的字节数,所以技术上 request.ContentLength 应该设置为 byteArray.Length,而不是 jsonContent.Length。 Encoding.GetEncoding("utf-8") 可以替换为Encoding.UTF8 谢谢,这很有帮助 将设置授权令牌的一部分,但如果需要测试,我们可能还必须传递标头。像这个 request.Method = "GET"; request.Timeout = 20000; request.ContentType = "应用程序/json"; request.Headers.Add("授权", "持有你的令牌:【参考方案2】:

WebClient 从远程 url 获取内容,javascriptSerializer 或 Json.NET 将 JSON 反序列化为 .NET 对象。例如,您定义一个反映 JSON 结构的模型类,然后:

using (var client = new WebClient())

    var json = client.DownloadString("http://example.com/json");
    var serializer = new JavaScriptSerializer();
    SomeModel model = serializer.Deserialize<SomeModel>(json);
    // TODO: do something with the model

您还可以查看一些 REST 客户端框架,例如 RestSharp。

【讨论】:

@BrokeMyLegBiking,哪一个?它与 ASPAjax 无关。如果您谈论的是 JavaScriptSerializer 类,它是在 System.Web.Extensions 程序集中的 .NET 中构建的,因此您无需下载或安装任何东西。 有没有办法将 c# 对象的所有属性名/属性值转换为 POST 键值对(或 GET 键值对)?这样我就可以有效地将 c# 对象用作我的 webservice 方法的输入值? @BrokeMyLegBiking,这将取决于您拥有什么对象以及网络服务如何期望输入。 我非常喜欢 RestSharp 库。感谢您提及。 达人能不能更新一下,client.downloadstring()已经不行了。【参考方案3】:

虽然现有的答案是有效的方法,但它们已经过时了。 HttpClient 是使用 RESTful Web 服务的现代界面。检查链接中页面的示例部分,它有一个非常简单的异步 HTTP GET 用例。

using (var client = new System.Net.Http.HttpClient())

    return await client.GetStringAsync("https://reqres.in/api/users/3"); //uri

【讨论】:

以上是关于从 .NET 控制台调用 JSON WebService 的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

从应用程序内部触发推送通知

没有 ASP.NET 的 C# JSON-RPC 网络服务器

如何从 ASP.NET MVC 控制器方法返回由 JSON.NET 序列化的 camelCase JSON?

如何在 C# Asp.Net 中从相当复杂的 Json 响应中创建 Dto

从 MVC .Net 核心控制器读取 JSON 时出现问题

将 JSON 从视图发送到控制器 ASP.NET MVC 会给出空值