自動生成されたソースコードに手を加え、より見栄え良くなるように修正します。
以下の修正を行います。
Drugs/Index
に遷移するよう修正_Layout.cshtml
@{
ViewBag.ApplicationName = "薬品情報検索";
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - @ViewBag.ApplicationName</title>
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="~/Scripts/modernizr-2.6.2.js"></script>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink((string)ViewBag.ApplicationName, "Index", "Drugs", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
</ul>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - @ViewBag.ApplicationName</p>
</footer>
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
</body>
</html>
以下の修正を行います。
メタデータクラス を使用して Drugs
, Classifications
に DisplayName
を設定します。
Models/DrugsMetadata.cs
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace WebApplication1.Models
{
[MetadataType(typeof(DrugsMetadata))]
public partial class Drugs
{
}
public class DrugsMetadata
{
[DisplayName("薬品ID")]
public int DrugId { get; set; }
[DisplayName("薬品コード")]
public string DrugCode { get; set; }
[DisplayName("薬品名")]
[Required(ErrorMessage = "薬品名は必須項目です。")]
public string Name { get; set; }
[DisplayName("会社名")]
public string Company { get; set; }
}
}
Models/ClassificationsMetadata.cs
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace WebApplication1.Models
{
[MetadataType(typeof(ClassificationsMetadata))]
public partial class Classifications
{
}
public class ClassificationsMetadata
{
[DisplayName("薬効分類ID")]
public int ClassificationId { get; set; }
[DisplayName("薬効分類コード")]
[Required(ErrorMessage = "薬効分類コードは必須項目です。")]
[StringLength(3, ErrorMessage = "薬効分類コードは3桁以内で入力してください。")]
public string ClassificationCode { get; set; }
[DisplayName("薬効分類")]
[Required(ErrorMessage = "薬効分類名称は必須項目です。")]
public string Name { get; set; }
}
}
partial
キーワードによって、クラスや構造体、メソッドの定義を複数のソースファイルに分割できます。
ここでは、EntityFramework で自動生成したモデルクラスに メタデータクラスの定義を追加する目的で使用しています。
MetadataType
属性は 指定したクラス (メタデータクラス) と
自身の名称が一致するプロパティについて、メタデータクラスの属性を適用します。
これにより、自動生成されたモデルクラスに手を入れることなく
DisplayName
などの属性を定義することができます。
メタデータクラス の名称は何でも構いませんが わかりやすさから、対象モデルクラス名 + Metadata とするのが慣習です。
薬効分類コードだけでなく、名称を併記するように修正します。
また、th
タグに class="col-xs-N"
を指定して、各列の幅を調整しています。
(class
の詳細については Bootstrap - Grid system を参照してください。)
Views/Drugs/Index.cshtml
@model IEnumerable<WebApplication1.Models.Drugs>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th class="col-xs-1">
@Html.DisplayNameFor(model => model.DrugCode)
</th>
<th class="col-xs-4">
@Html.DisplayNameFor(model => model.Name)
</th>
<th class="col-xs-2">
@Html.DisplayNameFor(model => model.Company)
</th>
<th class="col-xs-3">
@Html.DisplayNameFor(model => model.Classifications.Name)
</th>
<th class="col-xs-2"></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.DrugCode)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Company)
</td>
<td>
@Html.DisplayFor(modelItem => item.Classifications.ClassificationCode) :
@Html.DisplayFor(modelItem => item.Classifications.Name)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.DrugId }) |
@Html.ActionLink("Details", "Details", new { id=item.DrugId }) |
@Html.ActionLink("Delete", "Delete", new { id=item.DrugId })
</td>
</tr>
}
</table>
@model
ディレクティブはそのViewファイルに渡されるデータ (コントローラーの View
メソッドの引数) の型を表します。
コントローラーの View
メソッドで渡されてきたデータは Model
というプロパティに格納されます。Index.cshtml
の場合は Drugs
のリストが格納されています。
HTMLヘルパーメソッド では、特にコード上で指定していませんが、 Model
の内容を
ヘルパーに指定された ラムダ式 の引数として渡します。
DisplayNameFor
のラムダ式で指定されている model
には Drugs
クラスが入ります。
DisplayNameFor
で必要なのはモデルクラスの Metadata なので、リストが渡されてきた場合でも
モデルクラスから Metadata を参照して DisplayName
を返します。
DisplayFor
では、モデルクラスに格納されているデータが必要となります。
ラムダ式の modelItem
には Model
(Drugs
のリスト) が渡されてきますが
それは使用せず、foreach
で取り出した item
のプロパティを参照しています。
薬効分類コードのみ表示されているので、名称も表示するように修正します。
Views/Drusg/Details.cshtml
@model WebApplication1.Models.Drugs
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>Drugs</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.DrugCode)
</dt>
<dd>
@Html.DisplayFor(model => model.DrugCode)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Name)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Company)
</dt>
<dd>
@Html.DisplayFor(model => model.Company)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Classifications.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Classifications.ClassificationCode) :
@Html.DisplayFor(model => model.Classifications.Name)
</dd>
</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.DrugId }) |
@Html.ActionLink("Back to List", "Index")
</p>
コンボボックスに薬効分類コードのみ表示されているので、名称も表示するように修正します。
Drugs/Create
の GET
に対応するアクションメソッドを修正します。
Controllers/DrugsController.cs
// GET: Drugs/Create
public ActionResult Create()
{
ViewBag.ClassificationId = db.Classifications.Select(item => new SelectListItem
{
Text = item.ClassificationCode + ":" + item.Name,
Value = item.ClassificationId.ToString()
});
return View();
}
SelectListItem
はコンボボックスの各要素を表します。Text
に 薬効分類コードと名称を、 Value
に ID を指定しています。
@Html.DropDownList() は第2引数に null
を渡した場合、 ViewBag
に 第1引数と同じキーの項目があれば、それをセットしてくれます。
ViewBag
の項目名は変更していないので、Create.cshtml
には何も変更を行わなくとも期待する動作となります。
コンボボックスに薬効分類コードのみ表示されているので、名称も表示するように修正します。
Create
と同様、コンボボックスの各要素の生成処理を修正します。
Controllers/DrugsController.cs
// GET: Drugs/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Drugs drugs = db.Drugs.Find(id);
if (drugs == null)
{
return HttpNotFound();
}
ViewBag.ClassificationId = db.Classifications.Select(item => new SelectListItem
{
Text = item.ClassificationCode + ":" + item.Name,
Value = item.ClassificationId.ToString(),
Selected = item.ClassificationId == drugs.ClassificationId
});
return View(drugs);
}
Selected = item.ClassificationId == drugs.ClassificationId
は
コンボボックスの初期値の指定です。
自動生成されたソースコードで DropDownListFor
を使用していないのは、初期選択値を渡せないためです。
薬効分類コードのみ表示されているので、名称も表示するように修正します。
また、確認メッセージが英語になっているので、日本語に変更します。
Views/Drugs/Delete.cshtml
@model WebApplication1.Models.Drugs
@{
ViewBag.Title = "Delete";
}
<h2>Delete</h2>
<h3>以下のデータを削除します。よろしいですか?</h3>
<div>
<h4>Drugs</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.DrugCode)
</dt>
<dd>
@Html.DisplayFor(model => model.DrugCode)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Name)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Company)
</dt>
<dd>
@Html.DisplayFor(model => model.Company)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Classifications.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Classifications.ClassificationCode) :
@Html.DisplayFor(model => model.Classifications.Name)
</dd>
</dl>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-default" /> |
@Html.ActionLink("Back to List", "Index")
</div>
}
</div>
自動生成されたアプリケーションの修正について解説しました。
今回は見た目の修正を行いましたが、次回は機能の追加・修正について解説します。