2016. 10. 31. 15:00

'Web API'의 인증을 세션으로 관리하는 것입니다.

'REST'와는 안 맞는 구조라고 생각돼서 쓸 일이 얼마나 있을지 모르겠네요.

 

0. 프로젝트 준비

템플릿은 빈 템플릿을 선택해 주시고 참조는 'Web API'만 추가해 줍니다.

 

'App_Start'의 'WebApiConfig.cs'를 열어 라우터를 아래와 같이 수정합니다.

1
2
3
4
5
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
cs

 

'Web API'만 참조하는 경우 '{action}'이 빠져있어 평상시 MVC처럼 사용하면 문제가 발생합니다.

그래서 '{action}'을 추가해 줘야 하죠.

 

1. 'Global.asax' 설정하기

세션을 사용하기 위해서는 'Global.asax'에 'Application_PostAuthorizeRequest'를 정의를 해야 합니다.

그리고 'HttpContext.Current.SetSessionStateBehavior'를 통해 세션을 어떻게 할지를 정해 줘야 합니다.

 

'Global.asax' 파일을 열고 'Application_Start' 함수 다음에 아래 코드를 넣습니다.

protected void Application_PostAuthorizeRequest()
{
    HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}

 

2. 데이터 객체 만들기

CRUD 테스트에 사용할 모델과 리스트를 만들어 봅시다.

 

2-1. 모델(Model) 만들기

'UserData'라는 이름으로 클래스를 하나 만듭니다.

이 클래스는 유저의 데이터를 넣기 위한 클래스입니다.

/// <summary>
/// 아이템
/// </summary>
public class UserData
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime WriteDate { get; set; }

    public UserData(int nId, string sName, DateTime dateWrite)
    {
        this.Id = nId;
        this.Name = sName;
        this.WriteDate = dateWrite;
    }
}//end UserData

 

2-1. 리스트 만들기

리스트를 만들고 위에서 만든 'UserData'를 리스트로 관리하기 위한 클래스를 만듭니다.

 

'CList'라는 이름으로 클래스를 하나 생성합니다.

내용은 싱글 톤으로 리스트 개체를 만들고 관리해줍니다.

 

원래 싱글 톤은 스태틱(static)으로된 인스턴스를 만들어서 관리하는 것이 일반적인데 우리는 세션을 테스트할 목적이라 세션에 인스턴스를 저장해 두었다가 필요할 때 캐스팅해서 사용하겠습니다.

public sealed class CList
{
    #region 싱글톤 처리
    private static readonly string SessionName = "CList";

    private CList()
    {
        List = new List<UserData>();
    }

    /// <summary>
    /// 
    /// </summary>
    public static CList Instance
    {
        get
        {
            //세션을 받아 온다.
            IHttpSessionState session
                = SessionStateUtility
                    .GetHttpSessionStateFromContext(HttpContext.Current);

            if (null == session[SessionName])
            {//만들어진 객체가 없다.
                CList olist = new CList();
                session[SessionName] = olist;
            }
                
            return (CList)session[SessionName];
        }
    }
    #endregion

    /// <summary>
    /// 사용할 리스트
    /// </summary>
    private List<UserData> List = null;

    /// <summary>
    /// 리스트를 받는다.
    /// </summary>
    /// <returns></returns>
    public List<UserData> GetList()
    {
        return this.List;
    }

    /// <summary>
    /// 지정한 인덱스의 아이템을 가지고 온다.
    /// </summary>
    /// <param name="nIndex"></param>
    /// <returns></returns>
    public UserData GetItem(int nIndex)
    {
        return this.List[nIndex];
    }

    /// <summary>
    /// 데이터를 추가 한다.
    /// </summary>
    /// <param name="nId"></param>
    /// <param name="sName"></param>
    /// <param name="dateWrite"></param>
    public void Add(int nId, string sName, DateTime dateWrite)
    {
        this.Add(new UserData(nId, sName, dateWrite));
    }

    public void Add(UserData oData)
    {
        this.List.Add(oData);
    }

    /// <summary>
    /// 지정한 인덱스의 아이템을 지웁니다.
    /// </summary>
    /// <param name="nIndex"></param>
    /// <returns></returns>
    public void Remove(int nIndex)
    {
        this.List.RemoveAt(nIndex);
    }
}//end CList

 

3. 컨트롤러 만들기

'Controllers'폴더에 'IndexController'를 생성해 줍니다.

아래 코드를 넣어 줍니다.

public class IndexController : ApiController
{
    [HttpGet]
    public IEnumerable<UserData> GetList_Get()
    {
        return CList.Instance.GetList().ToList();
    }

    [HttpGet]
    public UserData GetItem_Get(int id)
    {
        return CList.Instance.GetItem(id);
    }

    [HttpGet]
    public void Add_Get(int id, string sName)
    {
        CList.Instance.Add(id, sName, DateTime.Now);
    }

    [HttpGet]
    public void Remove_Get(int id)
    {
        CList.Instance.Remove(id);
    }
}

 

'Get'방식을 사용하여 Web API를 받아 올 것입니다.

(참고 : [Asp.net] Web API + jquery 사용하기 )

 

 

3. HTML 작성

테스트를 위해 간단하게 UI를 작성하고 제이쿼리(jquery)를 통해 Web API를 호출해 봅시다.

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <meta charset="utf-8" />

    <script src="http://code.jquery.com/jquery-3.1.1.min.js"
            integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
            crossorigin="anonymous"></script>
    <script>
        /* GET 방식 ◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐◐ */
        var funGetList_Get = function () {
            $.ajax({
                url: "/api/Index/GetList_Get",
                type: "GET",
                success: function (data) {
                    $('#tbPerson').empty();
                    for (var i = 0; i < data.length; i++) {
                        $("#tbPerson").append("<tr><td>" + data[i].Id + "</td><td>" + data[i].Name + "</td><td>" + data[i].WriteDate + "</td></tr>");
                    }
                },
                error: function (msg) {
                    alert(msg.responseText);
                }
            });
        }

        var funGetItem_Get = function () {
            $.ajax({
                url: "/api/Index/GetItem_Get/" + $("#txtIndex_Get").val(),
                type: "GET",
                success: function (data) {
                    $("#txtID_Result").val(data.Id);
                    $("#txtName_Result").val(data.Name);
                    $("#txtDate_Result").val(data.WriteDate);
                    alert('아이템 가저오기 성공');
                },
                error: function (msg) {
                    alert(msg.responseText);
                }
            });
        }

        var funAdd_Get = function () {
            $.ajax({
                url: "/api/Index/Add_Get/" + $("#txtID_Get").val()
                        + "/?sName=" + $("#txtName_Get").val(),
                type: "GET",
                success: function (data) {
                    alert('아이템 추가 성공');
                },
                error: function (msg) {
                    alert(msg.responseText);
                }
            });
        }

        var funRemove_Get = function () {
            $.ajax({
                url: "/api/Index/Remove_Get/" + $("#txtIndex_Get").val(),
                type: "GET",
                success: function (data) {
                    alert('아이템 지우기 성공');
                },
                error: function (msg) {
                    alert(msg.responseText);
                }
            });
        }
    </script>

    <style>
        body {
            line-height: 30px;
        }

        .InputTable {
            float: left;
            border: 3px solid #0094ff;
        }

            .InputTable tr td {
                border-bottom: 1px solid #0094ff;
            }

        .InputTable_Input {
            width: 250px;
        }

        .divResult {
        }

            .divResult div {
                display: block;
                float: left;
                border: 3px solid #ff6a00;
            }
    </style>
</head>
<body>
    <div>
        <table class="InputTable">
            <tr>
                <td><h3>Get 방식</h3></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td><button onclick="funGetList_Get()">리스트 호출</button></td>
            </tr>
            <tr>
                <td class="InputTable_Input">
                    id : <input id="txtID_Get" type="text" /><br />
                    name : <input id="txtName_Get" type="text" />
                </td>
                <td><button onclick="funAdd_Get()">아이템 추가</button></td>
            </tr>
            <tr>
                <td>index : <input id="txtIndex_Get" type="text" /></td>
                <td>
                    <button onclick="funGetItem_Get()">아이템 가저오기</button><br />
                    <button onclick="funRemove_Get()">아이템 지우기</button>
                </td>
            </tr>
        </table>
    </div>

    <br />
    <br />
    <br />
    <br />
    <div class="divResult">
        <div>
            <h3>조회된 리스트</h3><br />
            <table id="tbPerson"></table>
        </div>
        <div>
            <h3>조회된 아이템</h3>
            아이디 : <input id="txtID_Result" type="text" /><br />
            이름 : <input id="txtName_Result" type="text" /><br />
            생성날짜 : <input id="txtDate_Result" type="text" /><br />
        </div>
    </div>
</body>
</html>

 

'Index.html'파일을 생성하고 아래 코드를 넣어 줍니다.

 

 

5. 테스트해 보기

이제 동작하는 것을 확인해 봅시다.

잘되네요.

 

다른 세션도 같이 확인해 봅시다.

 

각각의 세션이 따로 움직이는 것을 볼 수 있습니다.

 

 

마무리

vs2015용 테스트 프로젝트입니다.

APISession.zip
다운로드

 

세션 아이디를 'Web API'에서도 보내주기 때문에 가능한 동작입니다.

이 포스팅의 예제가 좀 적절하지 못한 게 리스트 관리보다는 그냥 여러 세션에 값을 넣고 빼고 하는 걸 만드는 게 더 좋은데 기존 포스팅과 일관성을 유지해보려고 무리하게 이렇게 했습니다 -_-a

다음엔 이러지 말아야겠네요 ㅎㅎㅎ