1.21 jigowatts

Great Scott!

ASP.NET MVCはじめました~データベースより値を取得し詳細を表示する

概要

前回は一覧表示をしたので、今回は詳細の表示です。

環境

Visual Studio 2010
ASP.NET MVC2
SQLServer2008 R2

今回の要件は

  1. データベースより値を取得
  2. ブラウザに詳細を表示

として、サンプルコードを書いてみました。

実装

ビューは新規作成ですが、それ以外は前回のコードに追記です。

コントローラーの用意
using System;
using System.Web.Mvc;
using Mvc2App.Models;
using Mvc2App.Services;
using Mvc2App.Services.Abstractions;
using Mvc2App.ViewModels.Peple;

namespace Mvc2App.Controllers
{
    [Authorize]
    public class PepleController : Controller
    {
        IPepleService _service;

        public PepleController() : this(new PepleService())
        { 
        
        }

        public PepleController(IPepleService service)
        {
            _service = service;
        }

        ...

        public ActionResult Details(int id)
        {
            try
            {
                var model = _service.GetById(id);
                return View(model);
            }
            catch (ArgumentException)
            {
                return RedirectToAction("NotFound", "Home");
            }
        }
    }
}
サービスインタフェースとサービスクラスの用意
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Mvc2App.Models;
using Mvc2App.ViewModels.Peple;

namespace Mvc2App.Services.Abstractions
{
    public interface IPepleService
    {
        ...
        PepleViewModel GetById(int id);
    }
}
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Mvc2App.Models;
using Mvc2App.Repositories;
using Mvc2App.Repositories.Abstractions;
using Mvc2App.Services.Abstractions;
using Mvc2App.ViewModels.Peple;

namespace Mvc2App.Services
{  
    public class PepleService : IPepleService
    {
        private IPepleRepository _repository;
        public PepleService():this(new PepleRepository())
        { 
        }

        public PepleService(IPepleRepository repository)
        {
            _repository = repository;
        }

        ...

        public PepleViewModel GetById(int id)
        {
            var data = _repository.GetById(id);
            
            if (data == null)
            {
                throw new ArgumentException("Data not found.");
            }

            return ModelMapper(data);
        }

        private static PepleViewModel ModelMapper(Person data)
        {
            var model = new PepleViewModel();
            model.ID = data.ID;
            model.Name = data.Name;
            model.Address = data.Address;
            model.PhoneNumber = data.PhoneNumber;
            model.UpdatedBy = data.UpdatedBy;
            model.UpdateDate = data.UpdateDate;
            return model;
        }
    }
}
リポジトリインタフェースとリポジトリクラスの用意
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mvc2App.Models;

namespace Mvc2App.Repositories.Abstractions
{
    public interface IPepleRepository
    {
        ...
        Person GetById(int id);
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Mvc2App.Repositories.Abstractions;
using Mvc2App.Models;

namespace Mvc2App.Repositories
{
    public class PepleRepository : IPepleRepository
    {
        DevEntities dbContext = new DevEntities();

        ...

        public Person GetById(int id)
        {
            var query = from x in dbContext.Peple
                        where x.ID == id
                        select x;

            var person = query.FirstOrDefault<Person>();
            return person;
        }
    }
}
ビューの用意
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
 Inherits="System.Web.Mvc.ViewPage<Mvc2App.ViewModels.Peple.PepleViewModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Details
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Details</h2>        
    <table>
        <tr>
            <td>
                <div class="display-label">ID</div>        
            </td>
            <td>
                <div class="display-field"><%: Model.ID %></div>        
            </td>
        </tr>
        <tr>
            <td>
                <div class="display-label">Name</div>
            </td>
            <td>
                <div class="display-field"><%: Model.Name %></div>
            </td>
        </tr>
        <tr>
            <td>
                <div class="display-label">Address</div>        
            </td>
            <td>
                <div class="display-field"><%: Model.Address %></div>
            </td>
        </tr>
        <tr>
            <td>
                <div class="display-label">PhoneNumber</div>
            </td>
            <td>
                <div class="display-field"><%: Model.PhoneNumber %></div>                     
            </td>
        </tr>
        <tr>
            <td>
                <div class="display-label">UpdatedBy</div>
            </td>
            <td>
                <div class="display-field"><%: Model.UpdatedBy %></div>
            </td>
        </tr>
        <tr>
            <td>
                <div class="display-label">UpdateDate</div>
            </td>
            <td>
                <div class="display-field"><%: Model.UpdateDate %></div>
            </td>
        </tr>        
    </table>

    <p>
        <%: Html.ActionLink("Edit", "Edit", new { id=Model.ID }) %> |
        <%: Html.ActionLink("Back to List", "Index") %>
    </p>

</asp:Content>
Not Foundページの用意

存在しないリソースにアクセスされてしまった時のために、自前で404 Not Foundページを用意しました。一般的にはどうするんでしょうか??
ASP.NET MVC3以降であればHttpNotFoundResultクラスを返しておけばいいのかな(・ω・)

using System.Web.Mvc;

namespace Mvc2App.Controllers
{
    public class HomeController : Controller
    {
        ...
        public ActionResult NotFound()
        {
            return View();
        }
    }
}
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	NotFound
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>404 NotFound</h2>

    <%: Html.ActionLink("Homeへ戻る","Index","Home") %>

</asp:Content>

実行結果

まずは/Peple/Indexにアクセスし一覧画面を表示します。


f:id:sh_yoshida:20141107171026p:plain
次に一覧画面から[Details]リンクを押下すると、詳細画面に遷移します。URLは/Peple/Details/1になります。

f:id:sh_yoshida:20141107171047p:plain
画面表示はGETによるリクエストなので、手入力などで存在しないIDを指定(e.g./Peple/Details/14)された場合、自前の404 Not Foundページへリダイレクトします。

f:id:sh_yoshida:20141107171101p:plain