ASP.NET MVC5(C#)でモデルを使ってPOSTデータを受け取ろう
ASP.NET MVCではコントローラーとビューはよく使うのですが、モデルは実はあまり使いません。そもそもASP.NET MVCのモデルは通常状態ではそんなに機能を持っていません。拡張機能(プラグイン)を使うといろいろ便利になるそうですが、Visual Studio Expressだとインストールできるものが非常に限られています。
使えるようにする方法もありますが、あまり公式にないことをするとライセンス的に怖いのでデフォルトの機能を使ってモデルを活用してみましょう!
単純にデータベースのテーブルでm_commentテーブルを作成しました。
(追記) pkiji_idとcomment_noを主キーにしてください。
Modelesフォルダを右クリックして「追加」の「クラス」を選択します。
「CommentModels.cs」としました。
初期に書かれているコードを全て削除して下記のコードを記述します。
namespaceはお使いの環境に合わせてください。
using System.ComponentModel.DataAnnotations; namespace WebSite.Models { public class CommentModel { [Required] [Display(Name = "記事番号")] public string PkijiID { get; set; } [Required] [Display(Name = "お名前")] public string UserName { get; set; } [Required] [Display(Name = "コメント")] public string UserComment { get; set; } } }続いてモデルからユーザーが送信したコメントデータを受け取ってデータベースにコメントデータを格納するコントローラーを作成します。Controllersを右クリックして「追加」でコントローラーを追加します。
MVC 5 Controller - Emptyを選択して名前は「PostController.cs」としました。
using System.Web.Mvc; using WebSite.Models; using mdlCommon; namespace WebSite.Controllers { public class PostController : Controller { // GET: Post public ActionResult Index() { return View(); } public ActionResult Comment(CommentModel modelComment, string returnUrl) { return Json(""); } } }上記のようにしました。
これでhttp://yigao.jp/post/comment/宛にデータが送信(POST)されると、このComment()メソッドでそれをキャッチし、コメントデータを受け取ることができます。コメントデータをインサートするためにSQL文を実行するメソッドを作成しましょう。mdlDatabase.csに
// クエリ実行 public bool DB_SqlExeNonQuery(string strSql) { SqlCommand sqlCmn = new SqlCommand(); try { sqlCmn = new SqlCommand(strSql, DB_Connection); sqlCmn.ExecuteNonQuery(); return true; } catch (Exception ex) { return false; } } // 一つの項目だけ取得 public bool DB_SqlExeScalar(string strSql, ref string strValue) { SqlCommand sqlCmn = new SqlCommand(); try { sqlCmn = new SqlCommand(strSql, DB_Connection); sqlCmn.Connection = DB_Connection; if (sqlCmn.ExecuteScalar() != null) { strValue = sqlCmn.ExecuteScalar().ToString(); } sqlCmn.Dispose(); return true; } catch (Exception ex) { return false; } }上記の2つのコードを追加してください。上のメソッドでは渡されたSQL文(INSERTやDELETEなど)のクエリを実行します。 下のメソッドは一つのデータのみを取得する場合に使います。
警告! 下記のコードをそのまま使ってサイトを運用するのはかなり危険よ。
POSTされてくるデータは必ずサニタイズ(ダブルクオーテーションやアポストロフィーなどの特殊記号を別の文字に置き換える)して、データベースに格納するの。これはSQL Serverに限らずMySQLなど全てのDBに言えることよ。
// コメントデータ挿入 public bool SET_CommentData(string pkiji_id, string strName, string strComment) { StringBuilder strSql = new StringBuilder(); string strSubmitTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss "); string strNewCommentNo = GET_CommentNo(pkiji_id); strSql.Append("INSERT INTO m_comment "); strSql.Append("(pkiji_id "); strSql.Append(", comment_no "); strSql.Append(", comment_name "); strSql.Append(", comment_data "); strSql.Append(", comment_date) "); strSql.Append("VALUES "); strSql.Append("('"); strSql.Append(pkiji_id); strSql.Append("' "); strSql.Append(","); strSql.Append(strNewCommentNo); strSql.Append(", '"); strSql.Append(strName); strSql.Append("' "); strSql.Append(", '"); strSql.Append(strComment); strSql.Append("' "); strSql.Append(", '"); strSql.Append(strSubmitTime); strSql.Append("' "); strSql.Append(") "); if (!db.DB_Connect()) { return false; } try { if (!db.DB_SqlExeNonQuery(strSql.ToString())) { return false; } return true; } catch (Exception ex) { return false; } finally { db.DB_Close(); } } // 最新のコメント番号を返す public string GET_CommentNo(string pkiji_id) { string strNewCommentNo = "0"; SqlDataReader sqlRdr = null; StringBuilder strSql = new StringBuilder(); strSql.Append("SELECT TOP 1 comment_no "); strSql.Append("FROM m_comment "); strSql.Append("WHERE pkiji_id = "); strSql.Append(pkiji_id + " "); strSql.Append("ORDER BY comment_no DESC "); try { if (!db.DB_Connect()) { return strNewCommentNo = ""; } if (!db.DB_SqlExeScalar(strSql.ToString(), ref strNewCommentNo)) { return "1"; } strNewCommentNo = (int.Parse(strNewCommentNo) + 1).ToString(); return strNewCommentNo; } catch (Exception ex) { return ""; } finally { if (sqlRdr != null) { if (!sqlRdr.IsClosed) { sqlRdr.Close(); } } db.DB_Close(); } }用意したメソッドをPostController.csで呼び出します。
using System.Web.Mvc; using WebSite.Models; using mdlCommon; namespace WebSite.Controllers { public class PostController : Controller { CmnOpn mdlCmn = new CmnOpn(); // GET: Post public ActionResult Index() { return View(); } public ActionResult Comment(CommentModel modelComment, string returnUrl) { mdlCmn.SET_CommentData(modelComment.PkijiID, modelComment.UserName, modelComment.UserComment); return Json(""); } } }Default.cshtmlに下記のコメントフォームを追加しました。
ここで注意!
これのvalueが「0101001」とベタ書きしていますが、本来ならデータベースにあるpkiji_idをコントローラー側で取得して@RenderSection("pkiji_id")などして動的にvalueを設定しなければなりません。
今回はモデルの使い方を勉強するためにとりあえずコメントデータをデータベースに格納することだけに趣を置いています。
コメントの送信はJavaScriptのライブラリjQueryを使いましょうか。
/* コメント投稿 */ $(function () { $('#Commentsubmit').click(function () { commentpost(); }); function commentpost() { var data = { UserName: $("#UserName").val() , UserComment: $("#UserComment").val() , PkijiID: $("#PkijiID").val() } $.ajax({ type: "POST", url: "/post/comment/", data: data, success: function (data) { }, error: function (data) { } }) } });ページを開いてテスト用のコメントを投稿してみます。
コメントデータがデータベースに格納されていることを確認できました。
当ページではコメントが投稿される過程を記したものです。SQLインジェクションなどの攻撃に全く対応していません。当サイトで記述されているコードは勉強用のものです。そのまま実用するのは危険ですので、コードの改修をしてセキュリティを意識してください。