ラベル JSON の投稿を表示しています。 すべての投稿を表示
ラベル JSON の投稿を表示しています。 すべての投稿を表示

2019年2月22日金曜日

サイズの大きいデータをPOSTすると404エラーが発生する

ASP.NETで作成したWeb APIに対し、HttpClientを使用して、JSONデータをPOSTするコードを書きました。

using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Clear();
    client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

    var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
    var task= client.PostAsync(uri, content).ContinueWith(x =>
    {
        var response = x.Result;
        if (!response.IsSuccessStatusCode)
        {
            throw new Exception(response.ReasonPhrase);
        }

        ・・・
    });
    try
    {
        task.Wait();
    }
    catch (AggregateException ex)
    {
        throw ex.Flatten();
    }
    catch
    {
        throw;
    }
}

40MB近くあるデータをPOSTしたところ、レスポンスに「Not Found」、いわゆる404エラーが返ってきました。












送信データサイズが小さい場合は問題はなく、エラーの原因がサイズの大きさにあることは明らかなのですが、
サーバーが受け取るリクエストの最大サイズはmaxRequestLengthですでに指定しています。
調べてみると、どうやらそれだけでは不十分で、リクエスト内のコンテンツ最大長(maxAllowedContentLength)の指定も
必要だということが分かりました。
web.configにmaxAllowedContentLengthを追加し、送信データサイズ以上の値を指定すると、エラーが返ることはなくなりました。

  <system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="52428800"></requestLimits>
      </requestFiltering>
    </security>
  </system.webServer>

またいつか、どこかで。

2018年7月20日金曜日

IBM Cloud上でFlaskを使用してWebAPIを作る(後編)

前回、JSONデータをやり取りするWeb APIを作成しましたが、{"user":"太郎"}のように日本語を指定するとエラーが発生します。
ログを確認すると、


user = str(request.json['user'])
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)


というエラーが出力されていました。

ググってみると「str文字列」だの「unicode文字列」だの・・・
ん?それってPython2の話ですよね?

もしやと思い、Pythonのバージョンを出力して確認してみると、やはりPython2.x系でした。


import sys
print('{}.{}.{}'.format(sys.version_info.major, sys.version_info.minor, sys.version_info.micro))


> 2.7.13


runtime.txtというファイルを新しく作成し、そこに

python-3.6.2

と記述してバージョンアップすると、エラーなく日本語も扱えるようになりました。

またいつか、どこかで。

2018年7月13日金曜日

IBM Cloud上でFlaskを使用してWebAPIを作る(前編)

IBM Cloud上でFlaskを使用し、JSONデータをやり取りするWeb APIを作成しています。
その方法をメモ。

Starter Kitsの中から「Python Flask」を選択し、アプリケーションを作成します。


























作成したアプリのソースをダウンロードします。

PythonもFlaskも未経験ですが、いろいろ調べながら下記のようなコードを作成しました。
受け取ったデータを結果とともにそのまま返すだけです。


from flask import Flask, jsonify, request

@app.route('/api/sample', methods = ['POST'])
def Sample():
    if request.is_json:
        if 'user' not in request.json:
            user = ''
        else:
            user = str(request.json['user'])
        return jsonify({'status':'success', 'user':user})
    else:
        return jsonify({'status':'error'})


{"user":"Taro"}というデータを送信したところ、内部エラーが発生しました。

FlaskのAPIドキュメントの「is_json」の項には「New in version 0.11.」と記載されています。
requirements.txtは「Flask==0.10.1」と記載されており、どうやらFlaskのバージョンが古いことが原因のようです。

「Flask==1.0.2」と書き換え、現時点の最新版にバージョンアップすると、{"status":"success","user":"Taro"}という結果が返ってくるようになりました。

またいつか、どこかで。

2017年4月20日木曜日

KOBE TodayのAPIを使ってみた!

「KOBE Today」って知ってますか?

今月、神戸市が開設した、神戸市内で開催されるイベント情報を発信するサイトです。
https://data.city.kobe.lg.jp/eventdata/

そのイベント情報を取得できるAPIが公開されているということなので、さっそく使ってみました。

データの形式はLinked Open Data (LOD)、それをSPARQLというSQLに似たクエリ言語を使って取得する、とのこと。
どちらも初めてお目にかかるので、何がなんやらという感じだったのですが、データ構造の理解に下記の情報が役立ちました。

SPARQLを利用した逆マッシュアップ-プログラミングを必要としないアプリ作成方法-

例えば、イベント名、開始・終了日、場所、URLを、終了日順に先頭から10件取得する場合は次のようなクエリを書きます。

 
PREFIX ic: <http://imi.go.jp/ns/core/rdf#>
PREFIX schema: <http://schema.org/>

select distinct ?name ?datef ?datet ?place ?url where {
?s ic:名称/ic:表記 ?name .
?s ic:期間 [ ic:開始日 ?datef; ic:終了日 ?datet ] .
?s ic:開催場所/ic:名称/ic:表記 ?place .
?s schema:url ?url .
}
ORDER BY ?datet
LIMIT 10


このクエリを改行も気にせずそのままURLエンコードして、

 
https://data.city.kobe.lg.jp/sparql?query=(エンコードしたクエリ)


のようにリクエストすればデータが取得できます。
取得したデータをアプリで表示してみました。

















私のような古い人間はとりあえずフォームアプリを作ってしまいがちですが、
ありさんがJavaScriptを使って、このページの右側に表示するようにしてくれました。

またいつか、どこかで。

2016年8月19日金曜日

Visual Studio 2015でWeb APIを作る(続き)

前回の続きです。

下記のJSONデータをPOSTしてみましょう。
{
  "Name" = "AIMEK",
  "Age" = 17
}

Postメソッドの引数valueに文字列が渡ってくるのかと思いましたが、valueはnullでした。
public void Post([FromBody]string value)
{
}
そこで、下記のクラスを作成します。
public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}
Postメソッドの引数をUserクラスに変更してみます。
public void Post([FromBody]User value)
{
}
すると、JSONデータがUserクラスにバインドされ、各プロパティに送信された値がちゃんと入っています。

ただ、送信されるデータごとにクラスを作成するとクラスが増える一方ですよね。
このような使い捨てのクラスであれば、匿名クラスを定義し、デシリアライズすることもできます。
また、匿名クラスで返してやれば、レスポンスとしてJSONデータが返ります。
public object Post([FromBody]object value)
{
    var type = new { Name = string.Empty, Age = 0, };
    var user = Newtonsoft.Json.JsonConvert.DeserializeAnonymousType(value.ToString(), type);
    return new { Result = 0, Status = "Success", };
}

またいつか、どこかで。