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

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

ただいまの
回答率

90.61%

  • JavaScript

    15898questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • C#

    6847questions

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

  • Webサーバー

    426questions

    Webサーバーとは、HTTPリクエストに応じて、クライアントに情報を提供するシステムです。

C#のhttpserverでテキストを保存したい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,036

cancat

score 239

こんにちは。 
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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

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();
            }
        }
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 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

    起動直後にwhileのなかを実行するようです。

    キャンセル

  • 2017/01/13 18:36

    IEでアクセスしても同様です。
    debugで見ていると、whileのなかを実行しているようですが、IEには何も表示しません。

    キャンセル

  • 2017/01/13 18:39

    回答のコードはコンソールアプリなのでWPFだとそのままは無理ですね。コンソールアプリで作ってみて下さい。
    あとは管理者権限で動作させる必要が有ります。

    キャンセル

  • 2017/01/13 18:48

    要点はHTMLのFormでPOSTしたものを、Requestのinputストリームから取り出してファイルに保存する流れです。
    HttpListenerなどのサンプルはいっぱいあるのでそちらを参考にして下さい。

    キャンセル

  • 2017/01/13 18:58

    コンソールで管理者権限ですね、時間作って試します。
    classつくってもWPFではだめですか?
    サンプル見てみます。
    ありがとうございます。

    キャンセル

  • 2017/01/13 19:01

    正しく実装すればWPFでも問題ないですが、管理者権限は必要だと思います。
    先ずはコアとなる動きを正しく理解した方が良いかと思い、シングルスレッドのコンソールアプリにしてます。

    キャンセル

  • 2017/01/19 18:31

    その後、manifestを作ったりしてテストしています。
    しかし、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

    Test.txtはできていますが、表示できず入力できないので、当然中身は空です。

    キャンセル

  • 2017/01/20 01:02

    私が書いたコードをブラウザで開き、右クリックでコードを、表示した場合何が表示されますか?

    キャンセル

  • 2017/01/20 01:09

    internet explorer(ie)で動作させた場合どうですか?私はieでしか確認してません。
    htmlをしっかり書いていないので、、、

    また、ieでコードを表示とかすると何が見えますか?

    ちなみに、本当は
    case "index.html":
    を作り、そこでindex.htmlファイルを読み込み、ストリームに流してあげるのがもう少しましな方法です。

    キャンセル

  • 2017/05/13 16:42

    回答に大変時間がかかってしまいお待たせしました。
    やっともういちどサーバーをつくるタイミングがやってきて、あらためてコンソール版から動かしてみたところ、いただいたコードで動かすことができました。
    おなじコードを、WPFに組み込んでも大丈夫でした。
    動かせなかったのは、sw.WriteLineで複数行を出力していたためのようです。
    あらためて感謝です。

    キャンセル

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をしたほうが安全です。同時に書き込むとファイルが消し飛ぶはず。要件として、そんな事態はないと思うなら、気にしなくてもいいことですが。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/13 18:09

    コメントありがとうございます。
    よのなか面倒くさいことしかないですが、わたしは使い慣れないソフトを使うほうが、ずっと面倒だと感じるようです。
    System.IO.Fileは使っていますが、これWebページで使えるのですか?

    キャンセル

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

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    15898questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • C#

    6847questions

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

  • Webサーバー

    426questions

    Webサーバーとは、HTTPリクエストに応じて、クライアントに情報を提供するシステムです。