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

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

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

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

2回答

12154閲覧

C#でhttpサーバーにてPOSTデータを受け取りたい

snowdropAPP

総合スコア41

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2021/08/06 02:44

編集2022/12/14 17:02

WindowsFormApplicationにてhttpサーバーを作成してクライアントから送られてくるPOSTデータを取得したいと思います

Visual Studio の Windows forms applicationにてHTTPサーバーを建てようと思っています。
クライアント側からPOSTMethodにてデータを送信。
受信したサーバー側はまずGET、POSTどちらのMethodでリクエストが来たかを取得してPOSTであればテキストボックスに値を表示する。
また、POST、GETに関わらず必ずテキストファイルの中身を返す。
このような簡易的なサーバーをテストで建ててみようと思います。
現状
①HttpListenerRequestにHttpMethodメソッドをstring型の変数に代入。
②代入した値を文字列比較。(POSTかそれ以外か)
③POSTならテキストボックスに表示。←ここが実装できない
④HttpListenerResponseのOutputStreamにてPATHの中のテキストファイルの中身を最後まで送る。
という感じです。

以下サイトを参考にしましたが、Request.Formが使えず困っています。
C#でHTTP Postデータを取得する方法は?
参照できていないのかと思ったので参照を追加しています。
名前空間にもSystem.webを入れていますがコンパイルエラーが解決しないので不思議に感じています。

Requestはいったい何者なんですかね...

そうか、変数名なのか!
そう思ったので以下リンクまでたどり着きましたが、フォームコレクション内の値を取得と書いていましたので違う...?
HttpRequest.Form プロパティ
今回ほしいのはあくまでBodyのUTF-8のデータが欲しい...
まだクライアント側作成していないのでbody内の話とFormの話が一緒なのかすらわかっていません(知識不足すいません)

POSTデータを取得したいと思いますがRequestがメソッドなのか変数なのか、使えるのか使えないのかがわかりません。
何か知っていることがあれば教え頂けると幸いです。

該当のソースコード

C#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.Threading.Tasks; 9using System.Windows.Forms; 10using System.Threading; 11using System.Net.Sockets; 12using System.Net; 13using System.Diagnostics; 14using System.Windows; 15using System.IO; 16using System.Net.Http; 17using System.Net.WebSockets; 18using System.Web; 19using System.Collections.Specialized; 20 21 22 23 24namespace webServerTest 25{ 26 public partial class Form1 : Form 27 { 28 public Form1() 29 { 30 InitializeComponent(); 31 } 32 33 private void button1_Click(object sender, EventArgs e) 34 { 35 Thread thread = new Thread(connect); 36 thread.Start(); 37 } 38 39 private void connect() 40 { 41 42 HttpListener listtner = new HttpListener(); 43 //とりあえずローカル 44 listtner.Prefixes.Add("http://*:80/"); 45 listtner.Start(); 46 47 48 while (true) 49 { 50 HttpListenerContext context = listtner.GetContext(); 51 52 HttpListenerRequest req = context.Request; 53 HttpListenerResponse res = context.Response; 54 55 //クライアントからの接続メソッド?判別 56 string str = req.HttpMethod; 57 58 59 if(str == "POST") 60 { 61           //string postData = Request.Form["key"]; ← Requestコンパイルエラーで使えない... 62 Invoke((Action)(() => 63 { 64 txtURL.Text = ""; //TODO postで送られたときにデータを格納 65 })); 66 } 67 68 //textファイルのパス 69 string path = @"C:\Users\TESTHTTP.txt"; 70 if (File.Exists(path)) 71 { 72 //textファイルの中身をバイト型の配列に格納 73 byte[] data = File.ReadAllBytes(path); 74 //dataの中身をRESPONSEとして返す 75 res.OutputStream.Write(data, 0, data.Length); 76 } 77 res.Close(); 78 79 } 80 } 81 82 } 83} 84 85

補足情報(FW/ツールのバージョンなど)

visualstudioは2015です

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

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

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

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

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

fiveHundred

2021/08/06 02:45

「コンパイルエラー」と記載するのではなく、エラー全文を記載してください。
snowdropAPP

2021/08/06 02:50

内容読まれましたでしょうか... エラーが出ているわけではありません なにをしたらRequest.Form()が使えるのか。 もしくは使えないのであればHTTPRequestはFormの中身を取得すると書いているがBodyの中身の話なのか もしくはそのほかを使うべきなのかを知りたいんですよね。 エラーの全文の記載であればそんなものは存在しませんと怒られています。
Zuishin

2021/08/06 03:07

質問のまとめをタイトルにし、最後にもまとめてください。 現状、次のような質問になっています。 > C#でhttpサーバーを作成しているときの出来事でした... > ASP.netでやるしかないんですね... それってあなたの日記ですよね。質問ではなく。
snowdropAPP

2021/08/06 03:10

かしこまりました。 修正します。
退会済みユーザー

退会済みユーザー

2021/08/06 04:04

きちんと書けないのですかね? ×: visualstudioのwindowsformapplicationにて 〇: Visual Studio の Windows forms application にて
退会済みユーザー

退会済みユーザー

2021/08/06 04:08

> このような簡易的なサーバーをテストで建ててみようと思います。 その簡易サーバーが実用になるとは思えませんけど、実用云々は考えてなくて、自分の勉強のためですか?
snowdropAPP

2021/08/06 04:10

dodox86様 リンク内拝見させていただきました。 これはかなり私の求めているものに近いと感じました。 BAで選びたいのでもしよろしければ解答に書いていただけるとありがたいです。 クライアント側の作成をしてみて動くか確認してみようと思います。
snowdropAPP

2021/08/06 04:11

SurferOnWww様 失礼いたしました修正いたしました。 まだ誤植、誤字等ありましたらご指摘ただけると幸いです。
snowdropAPP

2021/08/06 04:27

SuferOnWww >その簡易サーバーが実用になるとは思えませんけど、実用云々は考えてなくて、自分の勉強のためですか? 勉強のためです。 このサーバーを実用的に使用などというおこがましいことは考えられません。 セキュリティ面や知識において不足している点が多すぎます。 実を言いますと私が作成したいのはクライアント側です。 サーバーはRequestに対して毎回同じものをResponseしてもらえたらテスト自体ができますのでサーバーを立てているだけなのです。
退会済みユーザー

退会済みユーザー

2021/08/06 04:39 編集

> 実を言いますと私が作成したいのはクライアント側です。 > サーバーはRequestに対して毎回同じものをResponseしてもらえたらテスト自体ができますのでサーバーを立てているだけなのです。 であれば、「Visual Studio の Windows forms applicationにてHTTPサーバー」というような少々無理筋なことに時間と労力を費やすより、サーバー側は Visual Studio のテンプレートを使って ASP.NET MVC か Web API アプリを作ってそれで受けるようにすることをお勧めします。テンプレートを使えば実用になるレベルのアプリが簡単に作れますし、参考になるドキュメントも多々見つかりますので。
dodox86

2021/08/06 04:51

@質問者 snowdropAPPさん。 コメントをもとに回答しました。そちらをご参照ください。
snowdropAPP

2021/08/06 04:52

考えなしに始めたのが間違いでした... 参考ドキュメントも多々見つかるのはすでに感じております。 ご丁寧にありがとうございました。
guest

回答2

0

ベストアンサー

HttpListenerRequest req = context.Request;のコードを使うのであれば、このHTTPリクエストのコンテントボディ部を読み出せばよいです。

HttpListenerRequest.InputStream プロパティ - Microsoft Docs

例えば質問者さんのコードを流用するのであれば、こんなふうに使います。

C#

1...抜粋 2 3HttpListenerRequest req = context.Request; 4HttpListenerResponse res = context.Response; 5 6string str = req.HttpMethod; 7if (str == "POST") 8{ 9 //string postData = Request.Form["key"]; ← Requestコンパイルエラーで使えない... 10 11 byte[] bin = new byte[256]; 12 int readLen = req.InputStream.Read(bin, 0, bin.Length); 13 14 // 文字列のエンコーディングは適切に... ここではシンプルにASCII 15 string content = System.Text.Encoding.ASCII.GetString(bin, 0, readLen); 16 System.Diagnostics.Debug.WriteLine($"contentbody: {content}"); 17 Invoke((Action)(() => 18 { 19 txtURL.Text = content; 20 })); 21} 22...

で、例えばcurlコマンドでPOSTメソッドのHTTPリクエストを送信してあげれば、

terminal

1$ curl -X POST -H "Content-Type: text/plain" -d 'hogefugapiyo' localhost:8000/path

"hogefugapiyo" の文字列がコンテントボディ部から得られます。

投稿2021/08/06 04:50

dodox86

総合スコア9170

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

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

snowdropAPP

2021/08/06 05:03

丁寧にサンプル回答までいただきましてありがとうございます。 いまコマンドラインで実行してみたところうまくいきました! ありがとうございます。
guest

0

最初に

Q&A の記事のようなピンポイントな情報を宛てにしすぎないようにしましょう。
そちらの記事には Request というキーワードが記載されていますが、それが何の型なのか、何の名前空間なのかが記事からはまったく読み取れません。

基本は、情報がしっかり記載されているドキュメントを参照しましょう。
その上で Q&A の記事を少し見てみるという位の参考の仕方であればその記事も有効に利用することができるかもしれません。

本題

Request QueryString というワードで検索し、探してみると snowdropAPP さんも見つけている通り HttpRequest Class が引っかかります。

Enables ASP.NET to read the HTTP values sent by a client during a Web request.

上記引用から ASP.NET で使うクラスとわかります。
サンプルを見てもわかる通り、実際には

The following examples access the HttpRequest instance for the current request by using the Request property of the Page class.

You can use simplified syntax for accessing data from the QueryString, Form, Cookies, or ServerVariables collections. You can write Request["key"].

ASP.NET の Page クラスが Request プロパティを抱えていることがわかります。
Page.Request プロパティ

つまり、ASP.NET Web Forms を入れて、Page クラス内で Request プロパティを参照する必要があります。
Windows Forms の Form クラスでは参照できません。

また、Web Forms は古のものになりつつあります(.NET 5 以降は廃止)。
なので、仮に ASP.NET を使うのであれば ASP.NET MVC や ASP.NET Web API などの利用を推奨します。
ASP.NET Core MVC の概要

投稿2021/08/06 03:28

編集2021/08/06 03:36
BluOxy

総合スコア2661

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

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

snowdropAPP

2021/08/06 04:21

BluOxy様 解答丁寧な解説、ご回答ありがとうございます。 ネット上のサンプル等をむやみに鵜吞みにしすぎないようにしようと思います。 HTTPRequestはそもそもASP.NETのPageクラスにあるため使用できないのですね。 冷静に感がるとWindowsFormApplicationはFormクラスを継承しているため使えないですね... 後学のためにASP.NET MVCなど利用してみようかなと思います。 今現在は特に作成環境にこだわりがないためどちらでも作ってみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.53%

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

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

質問する

関連した質問