みなさんこんにちは
ひろぽんです!
ASP.NETでWEB開発をしていて、ViewからControllerにModel以外の引数を渡したい!って思うことありませんか?
私は割とあります。
例えば、記事一覧ページからコメントを投稿する場合等、リレーションの設定をしたい場合に!
上記のように記事一覧ページからコメントを投稿する場合、Controllerはあくまでもコメントになり、メソッドはCreateになります。
ですが普通にModelだけ投げてしまうと、コメントと記事が紐づきません。
そんな時に、Modelと記事のIdを投げてあげると、コメントのController内でコメントと記事の紐づけができますよね!
今回はそんな場合等に使える、ASP.NETでViewからControllerにActionLinkを使ってModel以外の値を投げる方法について書いていきます!
前提となるMODEL
public class Article
{
public int id { get; set; }
public string title { get; set; }
public string body { get; set; }
public DateTime created { get; set; }
public DateTime updated { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
記事のModelはこんな感じですね!
public class Comment
{
public int id { get; set; }
public string title { get; set; }
public string body { get; set; }
public DateTime created { get; set; }
public DateTime updated { get; set; }
public virtual Article Article { get; set; }
}
コメントのModelも記事と同じです。
基本的にタイトルがあって本文がある。といった形です。
記事1対コメント多になっているのが特徴ですかね!
では続いてスキャフォールドですが今回必要なのは、CommentのControllerのCreateとArticlesのDetailsのViewなので、その部分のみ書いていきます!
まずはCommentのCreateメソッドから!
// POST: Comments/Create
// 過多ポスティング攻撃を防止するには、バインド先とする特定のプロパティを有効にしてください。
// 詳細については、https://go.microsoft.com/fwlink/?LinkId=317598 を参照してください。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "id,title,body,created,updated")] Comment comment)
{
if (ModelState.IsValid)
{
db.Comments.Add(comment);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(comment);
}
このCreateメソッドにArticleIdを引数に受け取るようにして、Create実行時に記事と紐づくようにすると以下のようになります。
// POST: Comments/Create
// 過多ポスティング攻撃を防止するには、バインド先とする特定のプロパティを有効にしてください。
// 詳細については、https://go.microsoft.com/fwlink/?LinkId=317598 を参照してください。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "id,title,body,created,updated")] Comment comment,int articleId)
{
var article = db.Articles.FirstOrDefault(a => a.id == articleId);
if (ModelState.IsValid)
{
comment.Article = article;
db.Comments.Add(comment);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(comment);
}
引数にarticleIdを設定して、Create実行時にデータベースから引数のarticleIdの記事を取得し、CommentのArticleにセットする。
これだけで、リレーションが登録されるってめちゃくちゃ便利ですね。
SQLならなかなかややこしいことを書かないといけないのに、Asp.Netではその辺はあまり意識することないので、便利ですね!!!
では続いて、ArticleのDetailsのViewからCommentのCreateを呼び出し引数articleIdを渡す作業!
@model WebApplication1.Models.Article
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>Article</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.title)
</dt>
<dd>
@Html.DisplayFor(model => model.title)
</dd>
<dt>
@Html.DisplayNameFor(model => model.body)
</dt>
<dd>
@Html.DisplayFor(model => model.body)
</dd>
<dt>
@Html.DisplayNameFor(model => model.created)
</dt>
<dd>
@Html.DisplayFor(model => model.created)
</dd>
<dt>
@Html.DisplayNameFor(model => model.updated)
</dt>
<dd>
@Html.DisplayFor(model => model.updated)
</dd>
</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.id }) |
@Html.ActionLink("Back to List", "Index")
</p>
なんの変哲もないArticleのDetailsのViewにコメント追加リンクを追加します!
@model WebApplication1.Models.Article
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>Article</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.title)
</dt>
<dd>
@Html.DisplayFor(model => model.title)
</dd>
<dt>
@Html.DisplayNameFor(model => model.body)
</dt>
<dd>
@Html.DisplayFor(model => model.body)
</dd>
<dt>
@Html.DisplayNameFor(model => model.created)
</dt>
<dd>
@Html.DisplayFor(model => model.created)
</dd>
<dt>
@Html.DisplayNameFor(model => model.updated)
</dt>
<dd>
@Html.DisplayFor(model => model.updated)
</dd>
</dl>
</div>
@Html.ActionLink("コメントを追加","Create",new { Controller = "Comments",articleId = Model.id})
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.id }) |
@Html.ActionLink("Back to List", "Index")
</p>
実際に触ってみるとこんな感じになります!
トップ画面には、ArticleのIndexを設定しました!
ArticleのDetailsを見てみると
コメント追加リンクが設定されています!
ここから実際にコメントを追加してみます!
コメントが登録されました!
これでArticleIdが実際に紐づいていたらOKですね!
紐づいている!
OKです!
以上
コメント