edit가 조금 어렵다.

 

먼저, edit화면이다.

 

컨틀로러 먼저

 public ActionResult Edit(string id)
        {
            var student = (from row in _db.student
                           where row.hakbun == id
                           select row).FirstOrDefault();
            return View(student);
        }

 

 

그러고,  Create 카피해서 Edit만들고

 

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcBasic1.Models.student>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
 학생정보 수정
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <b><%= ViewData["errinfo"] %></b>
    <h2>학생정보 수정</h2>
     <%= Html.ValidationSummary("수정에 실패했습니다. 에러가 발생한 곳에서 다시 입력해 주세요") %>

    <%--<% using (Html.BeginForm()) {%>--%>
    <% using (Html.BeginForm()) {%>
        <%--<%=Html.AntiForgeryToken() %>--%>
        <fieldset>
            <legend>학생 정보</legend>
            <p>
                <label for="hakbun">학번:</label>
                <%= Html.Encode(Model.hakbun) %>

            </p>
            <p>
                <label for="name">이름:</label>
                <%= Html.TextBox("name", Model.name)%>
                <%= Html.ValidationMessage("name", "*")%>
            </p>
            <p>
                <label for="email">전화:</label>
                <%= Html.TextBox("phone", Model.phone)%>
                <%= Html.ValidationMessage("phone", "*")%>
            </p>
            <p>
                <label for="birth">주소:</label>
                <%= Html.TextBox("addr", Model.addr)%>
                <%= Html.ValidationMessage("addr", "*")%>
            </p>
           
            <p>
                <input type="submit" value="갱신" />
            </p>

             </fieldset>
    <% } %>
    <div>
        <%=Html.ActionLink("일람으로", "Index") %>
    </div>
</asp:Content>

 

그리고

[HttpPost]
        public ActionResult Edit(string id, FormCollection collection)
        {
            try
            {
                var student = (from row in _db.student
                               where row.hakbun == id
                               select row).FirstOrDefault();

                UpdateModel(student);
                _db.SaveChanges();
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

 

여기서 UpdateModel이라는 게 잘 이해가 안되지만, 그냥 그대로 쓰자!

'asp.net' 카테고리의 다른 글

Create(추가): 데이터 어노테이션 전까지...  (0) 2013.07.16
상세화면(Details)  (0) 2013.07.16
CNN World News  (0) 2013.04.26
XMLDataSource이용하기  (0) 2013.04.26
GLOBAL.ASAX  (0) 2013.04.23

일단, 이렇게 만들고,

public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Student/Create

        [HttpPost]
        public ActionResult Create(student std, FormCollection collection)
        {
            if (!ModelState.IsValid)
            {
                return View();
            }
           
            try
            {
                _db.AddObject("student", std);
                _db.SaveChanges();

                return RedirectToAction("Index");
            }
            catch(Exception ex)
            {
                ViewData["errinfo"] = ex.Message;
                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">
 신규작성
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <b><%= ViewData["errinfo"] %></b>
    <h2>신규작성</h2>
     <%= Html.ValidationSummary("신규등록에 실패했습니다. 에러가 발생한 곳에서 다시 입력해 주세요") %>

    <%--<% using (Html.BeginForm()) {%>--%>
    <% using (Html.BeginForm("Create", "Student", FormMethod.Post, new { id = "fm" })) {%>
        <%--<%=Html.AntiForgeryToken() %>--%>
        <fieldset>
            <legend>학생 정보</legend>
            <p>
                <label for="hakbun">학번:</label>
                <%= Html.TextBox("hakbun") %>
                <%= Html.ValidationMessage("hakbun", "*")%>
            </p>
            <p>
                <label for="name">이름:</label>
                <%= Html.TextBox("name")%>
                <%= Html.ValidationMessage("name", "*")%>
            </p>
            <p>
                <label for="email">전화:</label>
                <%= Html.TextBox("phone")%>
                <%= Html.ValidationMessage("phone", "*")%>
            </p>
            <p>
                <label for="birth">주소:</label>
                <%= Html.TextBox("addr")%>
                <%= Html.ValidationMessage("addr", "*")%>
            </p>
           
            <p>
                <input type="submit" value="신규작성" />
            </p>

             </fieldset>
    <% } %>
    <div>
        <%=Html.ActionLink("일람으로", "Index") %>
    </div>
</asp:Content>

 

어노테이션은 그냥... 먼저 만들고...

'asp.net' 카테고리의 다른 글

Edit(수정, 갱신)  (0) 2013.07.16
상세화면(Details)  (0) 2013.07.16
CNN World News  (0) 2013.04.26
XMLDataSource이용하기  (0) 2013.04.26
GLOBAL.ASAX  (0) 2013.04.23

네이버가 점검중이라 다음으로왔다.

 

 public ActionResult Details(string id)
        {
            var student = (from row in _db.student
                          where row.hakbun == id
                          select row).FirstOrDefault();
            return View(student);
        }

 

처음에는 FirstOrDefault()혹은 First()가 없어도 되는줄 알고 했는데,

야마다 상의 주옥같은 mvc2 강좌

http://www.atmarkit.co.jp/ait/articles/0905/22/news117_3.html

를 보고 반드시 필요하다는 것을 알게 되었다..

 

그리고

상세화면은

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
 학생 상세 정보
</asp:Content>

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

    <h2>학생 상세 정보</h2>
   
    <p>
        학번:
        <%= Html.Encode(Model.hakbun) %>
    </p>
    <p>
        이름:
        <%= Html.Encode(Model.name) %>
    </p>
    <p>
        전화:
        <%= Html.Encode(Model.phone) %>    
    </p>
    <p>
        주소:
        <%= Html.Encode(Model.addr) %>    
    </p>

    <p>
       
        <%=Html.ActionLink("편집", "Edit", new { id=Model.hakbun }) %> |
        <%=Html.ActionLink("일람", "Index") %>
    </p>
</asp:Content>

 

이렇게 하면 된다...

'asp.net' 카테고리의 다른 글

Edit(수정, 갱신)  (0) 2013.07.16
Create(추가): 데이터 어노테이션 전까지...  (0) 2013.07.16
CNN World News  (0) 2013.04.26
XMLDataSource이용하기  (0) 2013.04.26
GLOBAL.ASAX  (0) 2013.04.23

영어공부!


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="CNN.aspx.cs" Inherits="CNN" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>CNN World News</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        <ul>

        <asp:DataList ID="DataList1" runat="server" DataSourceID="XmlDataSource1">

            <ItemTemplate>

                <li><%# XPath("title") %></li>

            </ItemTemplate>

        </asp:DataList>

        </ul>

        <asp:XmlDataSource ID="XmlDataSource1" runat="server"

        DataFile="http://rss.cnn.com/rss/edition_world.rss" XPath="//rss/channel/item"></asp:XmlDataSource>

    </div>

    </form>

</body>

</html>



'asp.net' 카테고리의 다른 글

Create(추가): 데이터 어노테이션 전까지...  (0) 2013.07.16
상세화면(Details)  (0) 2013.07.16
XMLDataSource이용하기  (0) 2013.04.26
GLOBAL.ASAX  (0) 2013.04.23
App_Code폴더  (0) 2013.04.23

XML에서 데이터를 읽어와서 목록을 클릭하면

내용을 보여준다.


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="BList.aspx.cs" Inherits="BList" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title></title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        <asp:BulletedList ID="BulletedList1" runat="server" DisplayMode="LinkButton" 

            onclick="BulletedList1_Click" DataSourceID="XmlDataSource1" 

            DataTextField="Title">

            

        </asp:BulletedList>

        <asp:XmlDataSource ID="XmlDataSource1" runat="server" 

            DataFile="~/App_Data/FilmChoices.xml" XPath="FilmChoices/Film"></asp:XmlDataSource>

        <asp:XmlDataSource ID="XmlDataSource2" runat="server" 

            DataFile="~/App_Data/FilmChoices.xml" XPath="/a/b/c"></asp:XmlDataSource>


        <asp:DataList ID="DataList1" runat="server" DataSourceID="XmlDataSource2">

            <ItemTemplate>

                <p>제목: 

                    <asp:Label ID="Label1" runat="server" Text='<%# XPath("@Title") %>'></asp:Label></p>

                <p>개봉년도: <asp:Label ID="Label2" runat="server" Text='<%# XPath("@Year") %>'></asp:Label></p>

                <p>감독: <asp:Label ID="Label3" runat="server" Text='<%# XPath("@Director") %>'></asp:Label></p>

            </ItemTemplate>

        </asp:DataList>

        

    </div>

    

    </form>

</body>

</html>



using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;


public partial class BList : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {


    }

    protected void BulletedList1_Click(object sender, BulletedListEventArgs e)

    {

        //Label1.Text = "index: " + e.Index + ", item: " + BulletedList1.Items[e.Index].Text;

        XmlDataSource2.XPath = string.Format("FilmChoices/Film[@Title='{0}']", BulletedList1.Items[e.Index].Text);


    }

}



<?xml version="1.0" encoding="utf-8"?>

<FilmChoices>

  <Film

    Title="Close Encounters of the Third Kind"

    Year="1977"

    Director="Steven Spielberg" />

  <Film

    Title="Grease"

    Year="1978"

    Director="Randal Kleiser" />

  <Film

    Title="Lawrence of Arabia"

    Year="1962"

    Director="David Lean" />

</FilmChoices>


'asp.net' 카테고리의 다른 글

상세화면(Details)  (0) 2013.07.16
CNN World News  (0) 2013.04.26
GLOBAL.ASAX  (0) 2013.04.23
App_Code폴더  (0) 2013.04.23
Cross Page Posting  (0) 2013.04.20

말그대로 애플리케이션 전반에 걸친 작업이 필요할 때 작성(asp의 Global.asa)

==> JSP의 web.xml에 해당


Application_Start

애플리케이션이 맨처음 리퀘스트를 받았을 때 한번 실행됨.

애플리케이션 변수나 스테이트에 저장하는 곳(모든 사용자에게 유지되어야 하는 값)


Session_Start


Application_BeginRequest


Application_AuhenticateRequest


Application_Error


Session_End


Application_End



간단한 예

<%@ Application Language="C#" %>


<script runat="server">


    void Application_Start(object sender, EventArgs e) 

    {

        // 응용 프로그램이 시작될 때 실행되는 코드입니다.

        Application.Lock();

        Application["starttime"] = DateTime.Now;

        Application["appname"] = "HelloWorldApp";

        Application.UnLock();


    }

    

    void Application_End(object sender, EventArgs e) 

    {

        //  응용 프로그램이 종료될 때 실행되는 코드입니다.


    }

        

    void Application_Error(object sender, EventArgs e) 

    { 

        // 처리되지 않은 오류가 발생할 때 실행되는 코드입니다.


    }


    void Session_Start(object sender, EventArgs e) 

    {

        // 새 세션이 시작할 때 실행되는 코드입니다.

        Session["starttime"] = DateTime.Now;

        Session["ip"] = Request["REMOTE_ADDR"];

        Response.Write("Session_Start() <br>");


    }


    void Session_End(object sender, EventArgs e) 

    {

        // 세션이 끝날 때 실행되는 코드입니다. 

        // 참고: Session_End 이벤트는 Web.config 파일에서 sessionstate 모드가

        // InProc로 설정되어 있는 경우에만 발생합니다. 세션 모드가 StateServer 또는 SQLServer로 

        // 설정되어 있는 경우에는 이 이벤트가 발생하지 않습니다.


    }

       

</script>


'asp.net' 카테고리의 다른 글

CNN World News  (0) 2013.04.26
XMLDataSource이용하기  (0) 2013.04.26
App_Code폴더  (0) 2013.04.23
Cross Page Posting  (0) 2013.04.20
인라인 코딩과 코드 비하인드  (0) 2013.04.20

App_Code란 폴더는 클래스 파일(.cs)을 저장해 두는 곳이다.

App_Code는 없으므로 폴더를 만들면 회색으로 구분된다.(URL로 접속이 안됨)

==> JSP의 WEB-INF에 해당됨.


연습할 클래스 (Calculator 클래스)


using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;


/// <summary>

/// Calculator의 요약 설명입니다.

/// </summary>

public class Calculator

{

public Calculator()

{

//

// TODO: 여기에 생성자 논리를 추가합니다.

//

}


    static Exception divideByZeroException = new Exception("0으로 나누어서는 안됩니다");


    public int Add(int a, int b)

    {

        return (a + b);

    }


    public int Minus(int a, int b)

    {

        return (a - b);

    }


    public int Multi(int a, int b)

    {

        return (a * b);

    }


    public int Divide(int a, int b)

    {

        if (b == 0)

        {

            throw divideByZeroException;

        }


        return (a / b);

    }

}



Calculator Class를 사용하는 aspx 페이지


using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;


public partial class Calc : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

        try

        {

            Calculator myCalc = new Calculator();

            Label1.Text = myCalc.Add(12, 12).ToString() + "<br/>" +

                myCalc.Minus(12, 12).ToString() + "<br/>" +

                myCalc.Multi(12, 12).ToString() + "<br/>" +

                myCalc.Divide(12, 0).ToString() + "<br/>";

        }

        catch(Exception ex)

        {

            Label1.Text = ex.Message;

        }

    }

}


'asp.net' 카테고리의 다른 글

XMLDataSource이용하기  (0) 2013.04.26
GLOBAL.ASAX  (0) 2013.04.23
Cross Page Posting  (0) 2013.04.20
인라인 코딩과 코드 비하인드  (0) 2013.04.20
동영상 업로드  (0) 2013.04.01

Page1.aspx ==> Page2.aspx


이전에는 이렇게 하는 것이 어려웠다고 한다.

asp.net에서 명시적으로 action에 전달하지 않다보니 그런것같다.

하지만, 이제는 이것이 쉽고 간단하게 가능하게 되었다.

바로 PostBackUrl속성이 생긴것이다.


먼저 예제

Page1.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Page1.aspx.cs" Inherits="Page1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
   
        당신의 이름은:<br />
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <p>
        출발일:
            <br />
            <asp:Calendar ID="Calendar1" runat="server"></asp:Calendar>
        </p>
        <br />
        <asp:Button ID="Button1" runat="server" Text="Submit page to itself"
            onclick="Button1_Click" />
        <asp:Button ID="Button2" runat="server" Text="Submit page to page2.aspx"
            PostBackUrl="Page2.aspx" />
        <p>
            <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
        </p>
    </div>
    </form>
</body>
</html>


Page1.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class Page1 : System.Web.UI.Page
{
    public TextBox pp_TextBox1
    {
        get
        {
            return TextBox1;
        }
    }

    public Calendar pp_Calendar1
    {
        get
        {
            return Calendar1;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        Label1.Text = "Hello " + TextBox1.Text + "<br />" +
            "선택하신 날짜: " + Calendar1.SelectedDate.ToShortDateString();
    }
}



Page2.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Page2.aspx.cs" Inherits="Page2" %>
<%@ PreviousPageType VirtualPath="~/Page1.aspx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
    </div>
    </form>
</body>
</html>


Page2.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class Page2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //TextBox pp_Textbox1;
        //Calendar pp_Calendar1;

        //pp_Textbox1 = (TextBox)PreviousPage.FindControl("TextBox1");
        //pp_Calendar1 = (Calendar)PreviousPage.FindControl("Calendar1");

        if (PreviousPage != null && PreviousPage.IsCrossPagePostBack)
        {


            Label1.Text = "Hello " + PreviousPage.pp_TextBox1.Text + "<br />" +
               "선택하신 날짜: " + PreviousPage.pp_Calendar1.SelectedDate.ToShortDateString();
        }
        else
        {
            Response.Redirect("Page1.aspx");
        }
    }
}

'asp.net' 카테고리의 다른 글

GLOBAL.ASAX  (0) 2013.04.23
App_Code폴더  (0) 2013.04.23
인라인 코딩과 코드 비하인드  (0) 2013.04.20
동영상 업로드  (0) 2013.04.01
view helper  (0) 2013.04.01

인라인 코딩이 때로는 쉽고 편할때도 있지만, 일반적으로 코드 비하인드 모델이

큰 프로젝트에서 적합하겠다. 그래서 닥치고 코드비하인드


그래도 공부상

먼저 인라인코딩


Default.aspx

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<script runat="server">

protected void Button1_Click(object sender, EventArgs e)
    {
        Label1.Text = "Hello " + Textbox1.Text;
    }

</script>


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>

  
</head>
<body>
    <form id="form1" runat="server">
    당신의 이름은? <br />
        <asp:TextBox ID="Textbox1" runat="server"></asp:TextBox><br />
        <asp:Button ID="Button1" runat="server" Text="Submit" onClick="Button1_Click"/>
        <p><asp:Label ID="Label1" runat="server"></asp:Label></p>
    </form>
</body>
</html>


다음은 코드비하인드


Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    당신의 이름은? <br />
        <asp:TextBox ID="Textbox1" runat="server"></asp:TextBox><br />
        <asp:Button ID="Button1" runat="server" Text="Submit" onClick="Button1_Click"/>
        <p><asp:Label ID="Label1" runat="server"></asp:Label></p>
    </form>
</body>
</html>


Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        Label1.Text = "Hello " + Textbox1.Text;
    }
}



'asp.net' 카테고리의 다른 글

App_Code폴더  (0) 2013.04.23
Cross Page Posting  (0) 2013.04.20
동영상 업로드  (0) 2013.04.01
view helper  (0) 2013.04.01
Board Controller(mvc3)  (0) 2013.03.29


ASP.NET MVC 3 開発入門 (10) - 動画アップロードの実装

ASP.NET MVC 3 開発入門 - インデックス

前回、実装を行わなかった動画のアップロードを今回で実装していきます。動画のアップロードを実装しなかった理由ですが、ASP.NET MVC 3 ではファイルのアップロードへの対応が完全には出来ていないからでした。
具体的にどう対応していないかをまとめました。

  • <input type="file"> を生成する HTML ヘルパーが無い
    • タグを手書きするか自分でヘルパーを作成する必要がある
  • アップロードされたファイルの検証属性が無い
    • Required ぐらいは使える
  • HttpPostedFileBase 型をスキャフォールディングで認識しない
    • これは HTML ヘルパーが存在しないことに依存している予感

あまり知られていないのかもしれないですが、致命的なほどに機能が欠けていたりします。しかしモデルバインダは HttpPostedFileBase 型を認識して、アップロードされたファイルをちゃんとバインドしてくれますので、自分で検証を行うコードを書く必要がありますが、今までよりも楽にかけることは間違いないです。
ぐだぐだ言うのはこれぐらいにして、実際にコードを書いていきましょう。前述したように、ファイルアップロード自体はモデルバインダのおかげでお手軽に使えるようになりましたが、検証属性が用意されていないので今回は Request.Files プロパティを使うことにします。
アクションの引数に以下のように追加してもいいのですが、非常に不恰好ですね。

public ActionResult Create(Video video, HttpPostedFileBase file)
{
    // 実装は省略
}

まずはアップロードされたファイルを取得します。Request.Files は ASP.NET で利用できるプロパティで、input タグの name に指定したキー名を指定すると取得できます。これからファイルアップロードに使用するキー名は "File" で共通とします。

// file の型は HttpPostedFileBase になる
var file = Request.Files["File"];

注意する点としてはファイルがアップロードされなかったときには null が返ってくることですね。これでアップロードされたファイルが取得できましたので、ファイルの検証を実装しましょう。今回はアップロードされているかどうかとファイルの種類に対して検証を行います。
エラーメッセージは ModelState クラスの AddModelError メソッドで追加すると、Html.ValidationMessage などで出力することが出来ます。

if (file == null)
{
    ModelState.AddModelError("File", "ファイルを選択してください。");
    return View(video);
}
if (file.ContentType != "video/mp4" && file.ContentType != "video/x-m4v")
{
    ModelState.AddModelError("File", "ファイルの形式が不正です。");
    return View(video);
}

file が null の時はアップロードされていないので ModelState.AddModelError メソッドを呼び出してエラーメッセージを出力します。同様に ContentType が "video/mp4" でも "video/x-m4v" でもない時にはファイルの形式が不正というエラーを出力するようにします。
最後にアップロードされたファイルの保存を実装します。ファイルの保存したいは HttpPostedFileBase.SaveAs メソッドを使うだけで指定したパスに保存することが出来ますが、保存するディレクトリとファイル名の規約を決める必要があります。
今回はシンプルに ~/Videos ディレクトリを作成して、「(プライマリキー) + .mp4」 というファイル名で保存することにします。

// Video ディレクトリに 1.mp4, 2.mp4, ... のように名前を付けて保存する
var path = Server.MapPath(string.Format("~/Videos/{0}.mp4", video.VideoId));
file.SaveAs(path);

プライマリキーを必要としますので、リポジトリへの追加と反映が終わってから呼び出す必要があります。Server.MapPath メソッドは仮想パスをサーバの物理パスに変換してくれますので、それを利用して保存先のパスを作成しています。

それでは実装したアクション全体を確認してみましょう。ファイルの検証は手作業で行っているので、検証属性の便利さを実感するようなコードですね。ファイルアップロード用の検証属性は ASP.NET MVC 3 Futures に FileExtensionsAttribute という拡張子を調べるものはあるのですが、どう考えても機能不足なので使いませんでした。

//
// POST: /Video/Create
[HttpPost]
public ActionResult Create(Video video)
{
    try
    {
        if (!ModelState.IsValid)
        {
            return View(video);
        }
        // アップロードされたファイルを取得
        var file = Request.Files["File"];
        // ファイルを検証
        if (file == null)
        {
            ModelState.AddModelError("File", "ファイルを選択してください。");
            return View(video);
        }
        if (file.ContentType != "video/mp4" && file.ContentType != "video/x-m4v")
        {
            ModelState.AddModelError("File", "ファイルの形式が不正です。");
            return View(video);
        }
        // 作成、更新日時をセット
        video.CreatedAt = video.UpdatedAt = DateTime.Now;
        // データベースへ追加、反映
        _videoRepository.Add(video);
        _videoRepository.Save();
        // アップロードされた動画に名前を付けて保存
        var path = Server.MapPath(string.Format("~/Videos/{0}.mp4", video.VideoId));
        file.SaveAs(path);
        return RedirectToAction("Index");
    }
    catch
    {
        return View(video);
    }
}

ファイルのサイズとコンテントタイプを検証する属性は、以前私が作成したものもありますので参考にしていただけると嬉しいです。

  • ASP.NET MVC でアップロードされたファイルを検証する
  • ASP.NET MVC 3 と File API を利用してアップロード前に検証を行う
    • id:shiba-yan:20110209:1297183293
    • HTML5 File API を使ってクライアント検証も行います

あとは Web.config の system.web セクション内で、処理できる最大の HTTP リクエストサイズをそれなりに大きい値に指定しておきましょう。デフォルトでは 5MB などの小さい値になっているので、動画などのサイズの大きなファイルをアップロードしようとするとエラーになってしまいます。

<httpRuntime maxRequestLength="52428800"/>

これで Create アクションが動画アップロード機能含めて完成しました。Edit アクションも同様に実装することが出来ますので省略させていただきますが、ファイルは基本的に上書きされることに注意してください。

それでは次回から ASP.NET MVC 3 の目玉機能である Razor を利用してビューを作成していきたいと思います。お疲れ様でした。


'asp.net' 카테고리의 다른 글

Cross Page Posting  (0) 2013.04.20
인라인 코딩과 코드 비하인드  (0) 2013.04.20
view helper  (0) 2013.04.01
Board Controller(mvc3)  (0) 2013.03.29
mvc3 calculator  (0) 2013.03.29

+ Recent posts