質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
UWP

UWPは、Universal Windows Platformの略。様々なデバイス向けに提供されているアプリケーションを共通のフレームワーク上で動作可能にする仕組みで、Windows10で導入されました。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Q&A

解決済

4回答

8140閲覧

C#でWebAPIからJSONを繰り返し取得できない

picotoyou8

総合スコア8

UWP

UWPは、Universal Windows Platformの略。様々なデバイス向けに提供されているアプリケーションを共通のフレームワーク上で動作可能にする仕組みで、Windows10で導入されました。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

0グッド

1クリップ

投稿2017/12/14 12:02

C#でWebAPIからjsonを繰り返し取得したいのですが、1回目の取得はうまくいきますがループで回すと同じ値しか取得できません。
ボタンを押すことで取得の開始を考えていますが、ボタンは不要でも良いとは考えています。
C#は使い始めたばかりで、UWPについてもほとんど知識がない状況です。
根本が間違っているかもしれませんが、よろしくお願いいたします。

C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Web.Http;
using Newtonsoft.Json.Linq;
using Windows.Devices.Gpio;
using System.Threading.Tasks;

// 空白ページのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 を参照してください

namespace MaterialMatching_WebAPI
{
/// <summary>
/// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
/// </summary>
public sealed partial class MainPage : Page
{
private GpioPin pin;
public MainPage()
{
this.InitializeComponent();
}

private async void Button_Click(object sender, RoutedEventArgs e) { //ここにボタンがクリックされた時の処理を書く for (; ; ) { string conKbn = "0"; string machine_cd = "XXXX-01"; string endpoint = string.Format( "http://xxx.xxx.xxx.xxx/WakoWebApi/DBService/getMachine_mst?conKbn={0}&machine_cd={1}", conKbn, machine_cd ); HttpClient client = new HttpClient(); HttpResponseMessage result = await client.GetAsync(new Uri(endpoint)); string json = await result.Content.ReadAsStringAsync(); //jsonを解析して結果を取得する string kekka = json; if (kekka == "0") { textBlock1.Text = ”OK"; } else { textBlock1.Text = "NG"; } } } }

}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

同じリクエストしかしないなら何度やっても同じ結果が返るのは当然ではないでしょうか?

投稿2017/12/14 12:30

Zuishin

総合スコア28656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

picotoyou8

2017/12/14 14:15

このWebAPIはデータベースの特定の項目の値を返すように作られています。 その特定項目は、フラグとなっていて条件により0か1が立つ仕組みです。 そのため、項目の値は条件により変わってくるので、現在のフラグの状況を取得しようとしています。 テストでは、特定項目の値を手で変えながら取得値を見ていたのですが、値を変えたにもかかわらず取得値が同じだったため、質問させていただきました。
Zuishin

2017/12/14 14:22

その情報に間違いがないとすれば仕様通りに動いていないので API の設置ミスでしょう。 C# は関係ありません。ブラウザでその URL にアクセスしてみてください。
picotoyou8

2017/12/14 14:27

回答ありがとうございます。 実は、APIの問題かと思い、ブラウザで確かめてみました。 結果、正常な値を取得できていました。 その為、C#の問題ではないかと考えたのです。
Zuishin

2017/12/14 14:32

意味が分からないのは conKbn, machine_cd が定数なのでリクエスト自体が定数になっていることです。 ならば string.Format() を使う意味がありません。 この値を変化させることが前提になっているのではありませんか? つまりブラウザでアクセスした時はこの値を変化させたのではありませんか?
picotoyou8

2017/12/14 14:37

確かにstring.format()を使う意味はないですね。 ただ、machine_noを簡単に変えたかったために使っているだけです。 ブラウザにアクセスした時は、conKbnやmachine_noは変えていません。 URLに入力後は、データベースの値を変えるたびに更新で値を取得して確認していました。
Zuishin

2017/12/14 14:39

ブラウザとプログラムで同じタイミングでアクセスして異なる結果が出ることを確かめてください。 もちろん URL は同じものを使ってください。
picotoyou8

2017/12/14 14:44

同じタイミングでの検証も行いました。 結果は、ブラウザは正しく出く出来ていましたが、プログラムでは初回に取得した値のままでした。
Zuishin

2017/12/14 14:47

その際に使ったプログラムはここに挙げられたものと同一ですか? またブラウザの結果はどう表示されましたか?
Zuishin

2017/12/14 14:47

同一であるならば json の値はどうなりましたか?
picotoyou8

2017/12/14 14:58

プログラムはstring json = await result.Content.ReadAsStringAsync();までは、同一ですが、そこから先は少し端折っています。 ブラウザの結果は申し訳ないですが正確に覚えていませんが、"code":"1",・・・だったと思います。 この"1"の部分がフラグの値となるはずなのです。 string json = await result.Content.ReadAsStringAsync();実行後にブレイクポイントを入れてjsonの値を見たところ、ブラウザとは違っていたのです。
Zuishin

2017/12/14 15:02

覚えているいないではなく実際に動かして確かめてください。 ブラウザとプログラムを同時に立ち上げて同じタイミングで取得してください。
picotoyou8

2017/12/14 15:04

申し訳ないですが、今はその環境がないのです。 明日、確かめてみます。
Zuishin

2017/12/14 15:12

大事なところをはしょったりうろ覚えの記憶にこだわったりせずきちんと確かめましょう。 ブラウザの結果が 1 となるならば NG になるはずです。 また端折った解析部分が間違っていても NG になります。
picotoyou8

2017/12/14 15:20

textblock1にどう表示されるかは問題ではなかったので、解析部分は端折りました。 string json = await result.Content.ReadAsStringAsync();実行後のjsonの内容を見ていて、その時点でデータベースに登録した値と違ったので原因を探っているのです。 Zuishinさん的には、プログラムには問題はなさそうという見解でしょうか? 明日、再度ブラウザとプログラムで同タイミングでの検証は行います。 また、APIの作成者とも話をしてみます。
Zuishin

2017/12/14 15:22

きちんと検証がなされていないというのはプログラムの問題以前の問題なので。
Zuishin

2017/12/14 23:23

少し言葉足らずだったかもしれないので補足します。プログラムの問題以前の問題というのはこういうことです。 私の目の前にプログラムの断片があります。 ・その断片は初心者の作ったものです。 ・その断片は様々なところが加工されたり省略されたりしています。 ・しかも加工や省略された部分はどこかわかりません。 ・プログラムを動かした結果のみがわかります。 ・ところがその結果はきちんと条件管理されているとは言えない曖昧なものです。 ・さらに結果の値すら不明で記憶による曖昧なものです。 この状況で不完全なソースと睨めっこするのは時間の無駄です。 まずは結果がきちんと取得できる環境、つまりデバッグがまともにできる環境が必要です。 今の状態では「たとえソースに誤りがなくとも」間違っていると判定される危険があります。
guest

0

ブラウザ、自作プログラムが「何をどう通信している」のか、fiddler などのツールで確認しながら作業するとよいと思います。

投稿2017/12/14 19:14

hidori

総合スコア402

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

picotoyou8

2017/12/15 01:14

ありがとうございます。 少しずつですが、勉強していきます。 fiddler、使わせていただきます。
guest

0

C#

1//ここにボタンがクリックされた時の処理を書く 2for (; ; )

ハンドラ内で無限ループはダメでしょ。
実験レベルのコードなんでしょうけど。。

通信処理の確認がしたいだけなら、コンソールプログラム書いた方が早いんじゃないでしょうか。

投稿2017/12/14 19:12

編集2017/12/14 19:14
hidori

総合スコア402

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

後出し情報が多すぎますが、コメント欄の症状を見る限りではHttpClientのキャッシュが原因では。

C#

1HttpClient client = new HttpClient();

1,アセンブリ参照にSystem.Net.Http.WebRequestを追加。
2,上記コードを以下のコードに変更。

C#

1HttpClient client = new HttpClient(new WebRequestHandler() 2{ 3CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore) 4});

□参考情報
ネットワークのトレースを行う


2017/12/20コメント欄のやり取りを元に追記。
HttpClientのキャッシュを無効化する、UWPアプリ用のソースコード。

C#

1using Windows.Web.Http.Filters; 2 3HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter(); 4filter.CacheControl.ReadBehavior = HttpCacheReadBehavior.NoCache; 5filter.CacheControl.WriteBehavior = HttpCacheWriteBehavior.Default; 6HttpClient client = new HttpClient(filter);

□参考情報
HttpBaseProtocolFilter Class
UWP - HttpClient in while loop only executed GET once and returns the same string as the first executed value

投稿2017/12/14 15:20

編集2017/12/20 13:12
umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

picotoyou8

2017/12/15 01:12

回答、ありがとうございます。 お恥ずかしい話ですが、C#でのプログラムは初めてで、アセンブリ参照にSystem.Net.Http.WebRequestを追加方法がわからないのです。 もちろん、これから勉強していかなくてはならないのですが、テストプログラムを出来るだけ早く作成するよう依頼されているため、恥を忍んでお聞きしています。
picotoyou8

2017/12/18 00:19

自分なりに下記のようにusingにSystem.Net.Httpを追加してみました。 HttpClient client = new HttpClient(new WebRequestHandler() のWebRequestHandlerと CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore)のCache、System.Net.Cacheにエラーが発生します。 WebRequestHandlerでは、見つかりませんでした、 System.Net.Cacheでは、CacheがSystem.Netに存在しないとのエラーが発生します。 C# using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; using Newtonsoft.Json.Linq; using Windows.Devices.Gpio; using System.Threading.Tasks; using System.Net; using System.Net.Http; using System.Net.Http.Headers; // 空白ページのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 を参照してください namespace MaterialMatching_WebAPI { /// <summary> /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。 /// </summary> public sealed partial class MainPage : Page { private GpioPin pin; public MainPage() { this.InitializeComponent(); } private async void Button_Click(object sender, RoutedEventArgs e) { //ここにボタンがクリックされた時の処理を書く for (; ; ) { string conKbn = "0"; string machine_cd = "DPBP-04"; string endpoint = string.Format( "http://172.30.0.142/WakoWebApi/DBService/getMachine_mst?conKbn={0}&machine_cd={1}", conKbn, machine_cd ); //HttpClient client = new HttpClient(); HttpClient client = new HttpClient(new WebRequestHandler() { CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore) }); HttpResponseMessage result = await client.GetAsync(new Uri(endpoint)); string json = await result.Content.ReadAsStringAsync(); string kekka = json; if (kekka == "0") { textWeather.Text = stArrayData2[0]; } else { textWeather.Text = "NG"; } await Task.Delay(10000); // 1000ミリ秒待機するという仕事の完了を待ち、 } } private void Button_Click_1(object sender, RoutedEventArgs e) { } } }
umyu

2017/12/18 05:13

「アセンブリ参照 C# 追加方法」でグーグル検索してみてくださいな。 ソリューションエクスプローラの参照設定を右クリック→メニューより参照の追加を選択→System.Net.Http.WebRequestの行をクリックして選択→選択行にあるチェックボックスをチェック→OKボタンを押下。
picotoyou8

2017/12/19 03:12

ありがとうございます。 参照追加を選択後System.Net.Http.WebRequestが見つからなかったため、違う方法かと思い、質問させていただきました。 もしかして、そもそもの設定が違うのでしょうか? System.Net.Http.WebRequest.dllをダウンロードして参照追加してみましたが、今度は別のエラーが発生しました。 HttpClient client = new HttpClient(new WebRequestHandler() { CachePolicy = new System.Net.Cache.HttpRequestCachePolicy(System.Net.Cache.HttpRequestCacheLevel.NoCacheNoStore) }); のWebRequestHandlerが見つかりませんでしたというエラーとSystem.Net.CacheでCacheがSystem.Netに存在しないというエラーです。
picotoyou8

2017/12/19 08:21

申し訳ございません。 UWPで作成していることを明記しておりませんでした。 もしかすると、通常のC#ではできることでも、UWPだとできないのかもと感じましたので、コメントさせていただきました。
umyu

2017/12/19 13:58

あ、ごめんなさいー。UWPですかー。。ぐぐってみましたが、以下のコードにしてみたらどうなりますか。 using Windows.Web.Http.Filters; HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter(); filter.CacheControl.ReadBehavior = HttpCacheReadBehavior.NoCache; filter.CacheControl.WriteBehavior = HttpCacheWriteBehavior.Default; HttpClient client = new HttpClient(filter); □参考情報 https://docs.microsoft.com/en-us/uwp/api/windows.web.http.filters.httpbaseprotocolfilter https://stackoverflow.com/questions/42512901/uwp-httpclient-in-while-loop-only-executed-get-once-and-returns-the-same-strin
picotoyou8

2017/12/19 23:13

ありがとうございます。 文法上のエラーはなくなりました。 これからテストを行ってみます。 調べていただいてまで回答いただき、誠にありがとうございます。 テスト結果は、またコメントさせていただきます。
picotoyou8

2017/12/20 05:11

umyuさん、ありがとうございました。 無事にテストプログラムが完成しました。 C#でプログラムを作成するのは初めてで、しかもUWPだったため、右も左もわからなかったところ、親切に教えていただき本当にありがとうございました。
umyu

2017/12/20 13:14

C#初めてで混乱するのは分かりますがー、質問の仕方のコツについてアドバイスするとしたら2点あります。 1,質問するときのヒントのページを見て今後は質問してくださいなー。 https://teratail.com/help/question-tips 2,デバックにが5分以上の時間が掛かる時は、系統的デバッグの手法が有効です。 「系統的デバック」とはデバックの過程(仮定と結果)を記録する手法です。 こうすることで、質問時にどういう事を既に試しているのかを質問内容に記載できます。 質問内容で良いポイントを上げるとしたら、質問タイトルは要件を書いていて明確でした。 いろいろ大変だと思いますが、がんばってくださいな。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問