Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用.NET 4.0任务模式使用HTTPClient.ReadAsAsync将JSON反序列化为数组或列表_C#_Json_Asp.net Mvc 4_Task Parallel Library_Dotnet Httpclient - Fatal编程技术网

C# 使用.NET 4.0任务模式使用HTTPClient.ReadAsAsync将JSON反序列化为数组或列表

C# 使用.NET 4.0任务模式使用HTTPClient.ReadAsAsync将JSON反序列化为数组或列表,c#,json,asp.net-mvc-4,task-parallel-library,dotnet-httpclient,C#,Json,Asp.net Mvc 4,Task Parallel Library,Dotnet Httpclient,我正在尝试反序列化从http://api.usa.gov/jobs/search.json?query=nursing+作业使用.NET 4.0任务模式。它返回这个JSON('加载JSON数据'@http://jsonviewer.stack.hu/) 索引操作: public class HomeController : Controller { public ActionResult Index() { Jobs model = null; v

我正在尝试反序列化从
http://api.usa.gov/jobs/search.json?query=nursing+作业
使用.NET 4.0任务模式。它返回这个JSON('加载JSON数据'@
http://jsonviewer.stack.hu/

索引操作:

  public class HomeController : Controller
  {
    public ActionResult Index()
    {
      Jobs model = null;
      var client = new HttpClient();
      var task = client.GetAsync("http://api.usa.gov/jobs/search.json?query=nursing+jobs")
        .ContinueWith((taskwithresponse) =>
        {
          var response = taskwithresponse.Result;
          var jsonTask = response.Content.ReadAsAsync<Jobs>();
          jsonTask.Wait();
          model = jsonTask.Result;
        });
      task.Wait();
      ...
     }
如何使用.NET4.0任务模式处理此站点的JSON?在进入.NET4.5中的
await async
模式之前,我想让它工作起来

答案更新:

下面是一个使用.NET4.5AsyncWait模式和Brumcouse答案的示例

 public async Task<ActionResult>Index()
 {
    List<Job> model = null;
    var client = newHttpClient();

    // .NET 4.5 async await pattern
    var task = await client.GetAsync(http://api.usa.gov/jobs/search.json?query=nursing+jobs);
    var jsonString = await task.Content.ReadAsStringAsync();
    model = JsonConvert.DeserializeObject<List<Job>>(jsonString);
    returnView(model);
 }
公共异步任务索引()
{
列表模型=null;
var client=newHttpClient();
//.NET 4.5异步等待模式
var task=await client.GetAsync(http://api.usa.gov/jobs/search.json?query=nursing+工作);
var jsonString=await task.Content.ReadAsStringAsync();
model=JsonConvert.DeserializeObject(jsonString);
返回视图(模型);
}
您需要引入
System.Threading.Tasks
命名空间。

注意:在
.Content
上没有可用的
.ReadAsString
方法,这就是我使用
.ReadAsStringAsync
方法的原因。

尝试使用类似Json2csharp.com的网站,而不是手动启动模型。粘贴一个示例JSON响应,越完整越好,然后拉入生成的类。这至少可以去掉一些移动的部分,让您在csharp中看到JSON的形状,让序列化程序更容易,而且您不必添加属性

只要让它工作起来,然后对类名进行修改,以符合命名约定,并在以后添加属性

编辑: 好了,在稍微搞乱之后,我已经成功地将结果反序列化到作业列表中(我使用Json2csharp.com为我创建了这个类)

公共类作业
{
公共字符串id{get;set;}
公共字符串位置_title{get;set;}
公共字符串组织_name{get;set;}
公共字符串速率\u间隔\u代码{get;set;}
公共整数最小值{get;set;}
公共整数最大值{get;set;}
公共字符串开始日期{get;set;}
公共字符串结束日期{get;set;}
公共列表位置{get;set;}
公共字符串url{get;set;}
}
并编辑您的代码:

        List<Job> model = null;
        var client = new HttpClient();
        var task = client.GetAsync("http://api.usa.gov/jobs/search.json?query=nursing+jobs")
          .ContinueWith((taskwithresponse) =>
          {
              var response = taskwithresponse.Result;
              var jsonString = response.Content.ReadAsStringAsync();
              jsonString.Wait();
              model = JsonConvert.DeserializeObject<List<Job>>(jsonString.Result);

          });
        task.Wait();
列表模型=null;
var client=新的HttpClient();
var task=client.GetAsync(“http://api.usa.gov/jobs/search.json?query=nursing+工作“)
.继续((带响应的任务)=>
{
var response=taskwithresponse.Result;
var jsonString=response.Content.ReadAsStringAsync();
jsonString.Wait();
model=JsonConvert.DeserializeObject(jsonString.Result);
});
task.Wait();
这意味着您可以摆脱包含对象。值得注意的是,这不是一个与任务相关的问题,而是一个反序列化问题

编辑2:

有一种方法可以在VisualStudio中获取JSON对象并生成类。只需复制所选的JSON,然后编辑>粘贴特殊>将JSON粘贴为类。这里用了整整一页来讨论这一点:

var response=taskwithresponse.Result;
var jsonString=response.ReadAsAsync().Result;

返回类型取决于服务器,有时响应实际上是一个JSON数组,但以文本/普通格式发送

在请求中设置accept标头应获得正确的类型:

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
然后可以将其序列化为JSON列表或数组。 感谢@svick的评论,这让我很好奇它是否会起作用

我在没有配置accept标头的情况下得到的异常是System.Net.Http.UnsupportedMediaTypeException

以下代码比较干净,应该可以工作(未经测试,但在我的情况下可以工作):

var-client=new-HttpClient();
client.DefaultRequestHeaders.Accept.Add(新的MediaTypeWithQualityHeaderValue(“应用程序/json”);
var response=wait client.GetAsync(“http://api.usa.gov/jobs/search.json?query=nursing+工作);;
var model=await response.Content.ReadAsAsync();

您是否尝试过
ReadAsAsync()
?不起作用,在taskwithresponse的.Result上产生此错误。错误1“System.Threading.Tasks.Task”不包含“Result”的定义,并且找不到接受类型为“System.Threading.Tasks.Task”的第一个参数的扩展方法“Result”(是否缺少using指令或程序集引用?),这没有任何意义,请在
ReadAsAsync()中更改类型
无法在代码运行之前更改代码的方式。它确实做到了。它嵌入在ContinueWith语句中。请创建一个新的MVC4应用程序(在VS 2012中工作)并粘贴到此控制器和两个类?你能重复这个错误吗?如果是这样的话,你能建议一个经过测试的解决方案来解决这个问题吗?我使用Fiddler来发现JSON,它显示返回了多个{}。Json2csharp.com是一个很好的工具,但它没有显示有多个{}。我已经成功地将JsonProperty属性用于其他URL,因此我的问题不在于JsonProperty属性,而在于如何使用.NET 4.0中的任务模式将返回的JSON反序列化到数组或列表中。是的,正如我从一开始就说过的,这是一个JSON反序列化问题。捕获字符串,然后JSONVERTING完成了这个技巧,现在它可以工作了。无需修改作业类型,我使用JsonProperty属性保留了我的原始作业类型。如果您只想同步而不等待它们完成,那么使用异步方法获取数据是没有意义的。如果您只是要同步等待,那么最好从一开始就使用同步方法。如果你是
 public async Task<ActionResult>Index()
 {
    List<Job> model = null;
    var client = newHttpClient();

    // .NET 4.5 async await pattern
    var task = await client.GetAsync(http://api.usa.gov/jobs/search.json?query=nursing+jobs);
    var jsonString = await task.Content.ReadAsStringAsync();
    model = JsonConvert.DeserializeObject<List<Job>>(jsonString);
    returnView(model);
 }
public class Job
{
        public string id { get; set; }
        public string position_title { get; set; }
        public string organization_name { get; set; }
        public string rate_interval_code { get; set; }
        public int minimum { get; set; }
        public int maximum { get; set; }
        public string start_date { get; set; }
        public string end_date { get; set; }
        public List<string> locations { get; set; }
        public string url { get; set; }
}
        List<Job> model = null;
        var client = new HttpClient();
        var task = client.GetAsync("http://api.usa.gov/jobs/search.json?query=nursing+jobs")
          .ContinueWith((taskwithresponse) =>
          {
              var response = taskwithresponse.Result;
              var jsonString = response.Content.ReadAsStringAsync();
              jsonString.Wait();
              model = JsonConvert.DeserializeObject<List<Job>>(jsonString.Result);

          });
        task.Wait();
var response = taskwithresponse.Result;
          var jsonString = response.ReadAsAsync<List<Job>>().Result;
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
    var client = new HttpClient();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    var response = await client.GetAsync("http://api.usa.gov/jobs/search.json?query=nursing+jobs");
    var model = await response.Content.ReadAsAsync<List<Job>>();