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

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

ただいまの
回答率

90.83%

  • C#

    6301questions

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

  • ASP.NET

    467questions

    ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

  • MVC

    200questions

    MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

  • Razor

    13questions

    RazorはASP.NET Web PagesとASP.NET MVCで使われているビュー・エンジンです。HTMLマークアップとC#またはVisual Basicのコードに対応しています。マークアップとコードの間の切り替えは"@"で記されています。

ASP.NET MVC において ViewからController等への値渡し

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 206

nanairo_7_

score 4

 前提・実現したいこと

C#でASP.NET MVC5を用いた掲示板機能を作成しようとしており、新規トピック作成機能の実装で、viewでユーザーが選択した値をDBに登録する機能を実装しようとしています。
ViewにRazorを用いて記した@HtmlxxxFor群の値をController側のActionResultに送るにはどうしたらよいでしょうか。

以下の例ですと、Razorで記した@Html.TextBoxForの.textプロパティの値をTopicテーブルのTitleに保存したいです。

初歩的な質問ではないだろうかということは承知なのですが自力で解決できないため、アドバイスを戴けないだろうかと思い投稿しました。宜しくお願いします。

追記
質問欄にていただいたことをもとに詳細を記しました。ご指摘ありがとうございます。
また、TextBoxForを用いていますが、プログラミング初心者の為有用なものの区別がついてないだけでこだわりはないです。
そのためEditFor等他の有用な方法でもご教授頂けるだけでたいへん有り難いです。

 発生している問題・エラーメッセージ

The parameterized query '(@title nvarchar(4000)(' expects the parameter '@title', which was not supplied.

 該当のソースコード

  @Html.TextBoxFor(
      model => Model.Title,
      new { @name = "Title", @placeholder = "タイトルを入力してください" }
   )


  @Html.ActionLink(
     "新規トピックを投稿する",  //  リンク・テキスト
     "NewTopicSubmit",   //  アクション名
     "Forum" //  コントローラー名
  )
using System;
using System.Configuration;
using System.Data.SqlClient;
using System.Web.Mvc;

namespace Forum.Controllers
{
    public class ForumController : Controller
    {
        // 上述したRazorのコードはNewTopic上にある
        public ActionResult NewTopic()
        {
            return View();
        }


        // 上述したHtml.ActionLinkの"新規トピックを投稿する"をクリックすると実行する
        public ActionResult NewTopicSubmit()
        {

            string htmltitle = Request["Title"];

            // 接続文字列の取得。
            var connectionString = ConfigurationManager.ConnectionStrings["ForumConnection"].ConnectionString;


            using (var connection = new SqlConnection(connectionString))
            {

                try
                {

                    // データベースの接続開始
                    connection.Open();

                    using (var transaction = connection.BeginTransaction())
                    using (var command = new SqlCommand() { Connection = connection, Transaction = transaction })
                    {

                        try
                        {

                            // 親テーブルを挿入するSQLの準備
                            command.CommandText = @"INSERT INTO Topic (Title) VALUES (@title)";
                            command.Parameters.Add(new SqlParameter("@title", htmltitle));

                            // 親テーブルを挿入するSQLの実行
                            command.ExecuteNonQuery();

                            // コミット
                            transaction.Commit();


                        }
                        catch
                        {
                            // ロールバック
                            transaction.Rollback();
                            throw;

                        }
                    }
                }
                catch (Exception exception)
                {
                    Console.WriteLine(exception.Message);
                    throw;
                }
                finally
                {
                    // データベースの接続終了
                    connection.Close();
                }
            }
            return View();
        }
   }
}
using System.Collections.Generic;
using System.Data.Entity;

namespace Forum.Models
{
    public class ForumModels
    {

    }
    public class NewTopic
    {
        public string Nickname { get; set; }
        public string Category { get; set; }
        public string Region { get; set; }
        public string Title { get; set; }
        public string Comment { get; set; }
    }

    public class TopicTitle
    {
        public int Id { get; set; }
        public string Title { get; set; }
    }

    public class ForumConnection : DbContext
    {
        public DbSet<TopicTitle> TopicTitles { get; set; }
    }

    public class MvcBasicInitializer : CreateDatabaseIfNotExists<ForumConnection>
    {
        protected override void Seed(ForumConnection context)
        {
            base.Seed(context);

            var topics = new List<TopicTitle>
            {
                new TopicTitle
                {
                    Id = 4,
                    Title ="たいとるー1"
                }
            };
            topics.ForEach(m => context.TopicTitles.Add(m));
            context.SaveChanges();
        }
    }
}

 試したこと

webformでは用いることのできたname属性を一致させることでRequest[]に値を授受すること等は試したのですが.cshtmlファイルから.csファイルに値の受け渡しをすることはできませんでした。

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

VS2017
Windows7
.Net Framework 4.6.1
MVC5
テンプレートは用いてないです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2018/06/14 22:16

    開発環境(OS, .NET, MVC のバージョン、テンプレートは何を使ったかなど)を書いてください。使うのは TextBoxFor で良いのですか?(EditorFor ではなくて) Controller のアクションメソッドのコード全体をアップしてください。

    キャンセル

  • nanairo_7_

    2018/06/15 09:49

    投稿マナーを教えていただきありがとうございます。お手数をかけて申し訳ありまっせんがお手隙の際に追記や補足等も読んでいただけたら幸いです。よろしくお願いします。

    キャンセル

回答 1

checkベストアンサー

+1

Model を定義し、それから Entity Framework Code First の機能を利用して LocalDB に DB を作ったようですね。

Controller と View は質問者さんが自力でコードを書いて実装したのでしょうか? 両方とも ASP.NET MVC5 の普通の書き方ではない(はっきり言って、問題あり)なのでそう思いました。

Model と DB が上手くできていれば、Visual Studio のスキャフォールディング機能を利用して自力でコードを書かなくても基本的な Controller と View のコードは自動生成されて、今回のような問題に悩む必要はないはずです。

・・・が、とりあえず、それは置いといて、質問に書かれている View とアクションメソッドのコードをベースに表題の「ViewからController等への値渡し」についてレスします。

// 上述したHtml.ActionLinkの"新規トピックを投稿する"をクリックすると実行する

上の操作は、アクションメソッド NewTopicSubmit を HTTP 動詞 GET で呼び出しているだけですよね。

だとすると、View の @Html.TextBoxFor( ... の値(正確には、それが html に変換されてブラウザに送られた <input type="text" name="Title" ... /> にユーザーが入力した値)は送信されてないはずです。

念のため、Visual Studio でデバッガを使って、NewTopicSubmit メソッドの、

string htmltitle = Request["Title"];

で、値が取得できているかどうかチェックしてください。

もし、値が取得できているとすると、どうやってやったかは分かりませんが、表題の「ViewからController等への値渡し」はできているということになります。あとは ADO.NET のコードの書き方の問題ですので、それを質問者さんの方で調べてください。

値が取得できていないとすると、View を書き換えて、@Html.TextBoxFor( ... の値をアクションメソッド NewTopicSubmit に送信できるようにするという対処が必要だと思います。

具体例は以下のコードを見てください。これは @IT の記事(URL 下記)の Model をベースに Visual Studio Community 2015 で MVC5 プロジェクトを作り、EF6 Code First で LocalDB にデーターベースを作り、それを元にスキャフォールディング機能を利用して Controller と View のコードを自動生成させたものです。(注:アップしたのは今回の質問と関係する Create 部分のみです)

第2回 Entity Frameworkコード・ファーストでモデル開発
http://www.atmarkit.co.jp/fdotnet/aspnetmvc3/aspnetmvc3_03/aspnetmvc3_03_01.html

View

@model Mcv5App2.Models.Book

@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Create</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Book</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Isbn, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Isbn, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Isbn, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Publish, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Publish, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Publish, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Published, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Published, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Published, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Controller / Action Method

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Mcv5App2.Models;

namespace Mcv5App2.Controllers
{
    public class BooksController : Controller
    {
        private MyMvcContext db = new MyMvcContext();

        // ・・・中略・・・

        // GET: Books/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Books/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Isbn,Title,Price,Publish,Published")] Book book)
        {
            if (ModelState.IsValid)
            {
                db.Books.Add(book);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(book);
        }

        // ・・・中略・・・
}

疑問があればコメント欄で質問してください。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/06/17 09:03 編集

    問題の原因はクリアになったでしょうか? 参考にアップしたコードは、最低限必要なものばかりとは言え、質問の課題に対するピンポイントな対応策は見つけにくかったかもしれません。もし、ピンポイントな対処方法が不明でしたら 質問してください。

    キャンセル

  • 2018/06/17 14:50

    返信が遅くなり申し訳ありません、問題の原因はクリアになりました!
    回答を読み終え、
    >>上の操作は、アクションメソッド NewTopicSubmit を HTTP 動詞 GET で呼び出しているだけですよね。
    ということを知らなかったことが分かったのがとても大きかったです。

    また、回答からModelはうまくできているようだということが確信を持つことが出来、以下のご指摘を受けて、スキャフォールディング機能を利用してみたところweb上の入力フォームからデータベースに書き込むことに成功し、歓喜の声を上げてしまいました。本当に丁寧な回答をありがとうございました!!
    >>Model と DB が上手くできていれば、Visual Studio のスキャフォールディング機能を利用して自力でコードを書かなくても基本的な Controller と View のコードは自動生成されて、今回のような問題に悩む必要はないはずです。

    キャンセル

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

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

関連した質問

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

  • C#

    6301questions

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

  • ASP.NET

    467questions

    ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

  • MVC

    200questions

    MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

  • Razor

    13questions

    RazorはASP.NET Web PagesとASP.NET MVCで使われているビュー・エンジンです。HTMLマークアップとC#またはVisual Basicのコードに対応しています。マークアップとコードの間の切り替えは"@"で記されています。