C#のhttpserverでテキストを保存したい
解決済
回答 2
投稿
- 評価
- クリップ 0
- VIEW 3,999
こんにちは。
Windows10でC#のアプリケーションを開発しています。
Visual Studio 2015 Communityを使っています。
前提・実現したいこと
C#でWebServerをつくり、ローカル環境からアクセスし、ローカル内のマシンからのtextinputを受け取ってファイルに記録したいです。
試したこと
http://qiita.com/nandai@github/items/0e06f101c408c2026709
を参考に、サーバーを作りました。
下記のように、ページを作り、とりあえず自マシンで、IEでhttp://localhost:8080/を開いたところ、ページを開けました。
発生している問題・エラーメッセージ
inputの内容をそのフォルダにtextfile(yyyyMMdd_HHmmss.txt)として保存したいです。
ほぼC#しか使えないのですが、それには何を使って、どうしたらよいでしょう。
つまり、もしinputのname=inputboxとしたら、C#で書けば、
File.AppendAllText("tweet.txt", inputbox.Text);
みたいな感じです。
JavaScriptとかでしょうか?
該当のソースコード
if (0 <= pos) {
message =
"<title>diary-tweet SERVER</title>" +
"<h1>easy tweet Webサーバー</h1>" +
System.DateTime.Now+"<br>"+
"<input></input><button>send</button>";
}
補足情報(言語/FW/ツール等のバージョンなど)
Microsoft Visual Studio Community 2015
Version 14.0.25424.00 Update 3
Microsoft .NET Framework
Version 4.6.01038
インストールしているバージョン:Community
Visual C# 2015 00322-20000-00000-AA575
Microsoft Visual C# 2015
です。
よろしくお願いします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
自力で頑張りつつ、簡単な方法はHttpListenerです。
シングルスレッドなのでLockなど不要。
htmlの中では入力FROMでGETするようにするにして、Getされた時のQueryを読み取ってファイルに保存する。
- 最低限のコードだけ
- 動作確認済み
- エラー処理無し
- 自前で頑張るお勧めしないコード
- いろいろ問題あり
- 実際には関数仕様を確認すること
using System.IO;
using System.Net;// http://127.0.0.1:8123 にアクセスしテキストを入力するとText.txtに内容が保存される
namespace WebLinkSample
{
class Program
{
static void Main(string[] args)
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://+:8123/");
listener.Start();
StreamWriter writer = new StreamWriter(@"Test.txt");
while (true)
{
HttpListenerContext context = listener.GetContext();
HttpListenerResponse res = context.Response;switch (context.Request.Url.AbsolutePath)
{
case "/test.cgi":
{
StreamReader reader = new StreamReader(context.Request.InputStream);
string str = reader.ReadToEnd();
writer.WriteLine(str);
writer.Flush();
}
break;
}
byte[] html = System.Text.Encoding.GetEncoding(932).GetBytes(@"<form action='test.cgi' method='post'><input type='text' name='name'></form>");
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.ContentType = "text/html";
context.Response.OutputStream.Write(html, 0, html.Length);
res.Close();
}
}
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
Webサーバをやりたいのなら、 NancyFx( http://nancyfx.org/ )
を使うといいと思う。面倒なこと自分で書きすぎ。バグる未来しかない。
ファイルの保存自体は、System.Io.File(https://msdn.microsoft.com/ja-jp/library/system.io.file(v=vs.110).aspx) ここにあるのを使えばいいと思う。
Webサーバは、非同期に動くはずなので、ファイル書き込むときは、Lockをしたほうが安全です。同時に書き込むとファイルが消し飛ぶはず。要件として、そんな事態はないと思うなら、気にしなくてもいいことですが。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.10%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2017/01/13 18:30
頑張るわけではないですが、簡単なものだし、外部のソフトをインストールするより、ずっと楽しいと思います。
さてそれでいただいたコード試してみたのですがうまく動かないです。
http://+:8123/だと、
例外がスローされました: 'System.Windows.Markup.XamlParseException' (PresentationFramework.dll の中)
となります。
あ。wpfで使っています。
HttpServer.HttpServer()クラスのhttpserverstart()メソッドとして組み込みました。
namespace tweetManager {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
SetTaskTray();
var server = new HttpServer.HttpServer();
server.httpserverstart();
}
として実行しました。
listener.Prefixes.Add("http://127.0.0.1:8123/");
とすれば動作するのですが、Edgeで
http://127.0.0.1:8123/
http://127.0.0.1:8123/test
にアクセスしても、何も表示しません。
Debugフォルダに空のTest.txtファイルはできました。
何か抜けている手順がありますか?
2017/01/13 18:31
2017/01/13 18:36
debugで見ていると、whileのなかを実行しているようですが、IEには何も表示しません。
2017/01/13 18:39
あとは管理者権限で動作させる必要が有ります。
2017/01/13 18:48
HttpListenerなどのサンプルはいっぱいあるのでそちらを参考にして下さい。
2017/01/13 18:58
classつくってもWPFではだめですか?
サンプル見てみます。
ありがとうございます。
2017/01/13 19:01
先ずはコアとなる動きを正しく理解した方が良いかと思い、シングルスレッドのコンソールアプリにしてます。
2017/01/19 18:31
しかし、webBrowser(Edge)で127.0.0.1:8123にアクセスしてもhtmlを表示できずにいます。
単なる文字であれば表示できました。現在次の通りで、[test]を表示しています。
よろしければアドバイスお願いします。
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://+:8123/");
listener.Start();
StreamWriter writer = new StreamWriter(@"Test.txt");
while (true) {
HttpListenerContext context = listener.GetContext();
HttpListenerResponse res = context.Response;
switch (context.Request.Url.AbsolutePath) {
case "/test.cgi": {
StreamReader reader = new StreamReader(context.Request.InputStream);
string str = reader.ReadToEnd();
writer.WriteLine(str);
writer.Flush();
}
break;
}
//byte[] html = System.Text.Encoding.GetEncoding(932).GetBytes(@"<html><body><form action='test.cgi' method='post'><input type='text' name='name'></form></body></html>");
//context.Response.StatusCode = (int)HttpStatusCode.OK;
//context.Response.ContentType = MediaTypeNames.Text.Html;
//context.Response.OutputStream.Write(html, 0, html.Length);
//res.Close();
HttpListenerRequest req = context.Request;
res.StatusCode = (int)HttpStatusCode.OK;
res.ContentType = MediaTypeNames.Text.Html;
res.ContentEncoding = Encoding.UTF8;
StreamWriter sw = new StreamWriter(res.OutputStream);
sw.WriteLine("test");//<-これは表示できた。
sw.WriteLine(@"<html><body><form action='test.cgi' method='post'><input type='text' name='name'></form></body></html>");//<-これは表示ダメ。
sw.WriteLine(@"<form action='test.cgi' method='post'><input type='text' name='name'></form>");//<-これも表示ダメ。
sw.Flush();
res.Close();
}
2017/01/19 18:32
2017/01/20 01:02
2017/01/20 01:09
htmlをしっかり書いていないので、、、
また、ieでコードを表示とかすると何が見えますか?
ちなみに、本当は
case "index.html":
を作り、そこでindex.htmlファイルを読み込み、ストリームに流してあげるのがもう少しましな方法です。
2017/05/13 16:42
やっともういちどサーバーをつくるタイミングがやってきて、あらためてコンソール版から動かしてみたところ、いただいたコードで動かすことができました。
おなじコードを、WPFに組み込んでも大丈夫でした。
動かせなかったのは、sw.WriteLineで複数行を出力していたためのようです。
あらためて感謝です。