LINQPad로 Facebook Graph API 빠르게 테스트하기

C#을 사용하면서 알아두면 여러모로 유용하게 활용할 수 있는 도구로 LINQPad가 있습니다. LINQPad Developer Edition부터는 NUGET 패키지를 Query에 포함시킬 수 있는 기능도 제공이 되는데, 이 기능을 활용하여 Outercurve Foundation이 관리하는 Facebook .NET SDK NuGet 패키지를 추가하여 빠르게 Facebook Graph API를 호출할 수 있습니다.

LINQPad에서 NuGet 패키지를 추가하려면, 쿼리 창에서 오른쪽 버튼을 클릭한 다음, NuGet Package Manager 메뉴를 선택합니다.

그 다음, 검색어에 Facebook을 입력하여 검색하면, Facebook이라는 이름의 NuGet 패키지가 검색 결과 제일 처음에 나타납니다. Add To Query 버튼을 눌러 패키지 캐시에 추가한 다음, 설치가 완료되면 Add Namespace 링크를 클릭하여 쿼리에서 편하게 쓸 수 있도록 합니다.

아래 코드 조각을 테스트하기 위해서는 App ID, App Secret, Access Token을 사전에 Facebook Developer 페이지를 통하여 획득하셔야 합니다. 아래 샘플 코드에서는 관리 권한이 있는 Facebook Page에 대해 간단하게 포스팅하고, 해당 포스트의 정보를 가져오는 코드이므로 대상 Page ID도 획득해야 합니다.

string appId = "";
string appSecret = "";
string accessToken = "";
string pageId = "";

FacebookClient client = new FacebookClient(accessToken)
{
  AppId = appId,
  AppSecret = appSecret
};
dynamic result = null;

result = client.Post($"/{page_id}/feed", new
{
  message = $"Random Message {DateTime.UtcNow.Ticks.ToString()}"
});
((object)result).Dump();

result = client.Get($"/{result.id}", new
{
  fields = new string[] { "id" }
});
((object)result).Dump();

Facebook의 Graph API가 반환하는 JSON 응답 객체를 Newtonsoft JSON 라이브러리를 이용하여 C# 객체로 변환하면, 이것을 DLR 바인딩에 연결하여 필요한 프로퍼티에 액세스할 수 있습니다. 그리고 이렇게 얻어온 응답 결과를 LINQPad의 내장 Extension 메서드인 Dump 메서드로 시각적으로 잘 정리된 형태의 표로 볼 수 있습니다.

한 가지 아쉬운 점은, DLR 컨텍스트에서는 LINQPad의 Dump 확장 메서드가 제대로 작동하지 않아서, object 타입으로 캐스팅하여 DLR 컨텍스트를 해제한 다음 Dump 메서드를 호출해주어야 합니다. 실행 결과는 아래와 같습니다.

Facebook이 아니어도, Newtonsoft JSON과 HttpClient를 활용하면 비슷한 방법으로 REST API들을 테스트해볼 수 있습니다.

 

Windows Azure Storage를 액세스하고 관리하는 빠른 방법

사이트 바로 가기: http://www.myazurestorage.com/


Windows Azure Platform의 핵심 기능들 중에서, Hosting Service (Compute) 영역 만큼 많은 비중을 차지하고 핵심적인 기능을 담당하는 것이 Storage Service (Storage) 영역입니다. 하지만 Storage Service를 단지 http://windows.azure.com/ 에서 제공하는 웹 프론트엔드로만 관리하는데에는 모자르는 점이 많은데요, 이를 효과적으로 보완하고 좀 더 쉽게 관리할 수 있는 웹 사이트를 소개합니다. 바로 myAzureStorage.com (http://www.myazurestorage.com) 이라는 사이트입니다.


myAzureStorage.com에 접속하면 아래와 같은 로그인 화면이 나타납니다. Windows Azure Platform이 노출하는 REST Service API와의 연결을 위하여 Windows Azure Storage의 계정 ID와 Primary Access Key를 묻는 것이며 이는 http://windows.azure.com/ 에서 Storage Service 항목에 나와있는 값을 대입하면 됩니다.




사이트에 로그인하고 나서는 아래 그림과 같이 Table, Queue, BLOB Storage에 대한 접근을 할 수 있게 되어있습니다. Table Storage의 경우 테이블 스키마를 정의하고 웹 상에서 직접 데이터를 검색할 수 있습니다.



테이블 관리 기능 외에도, 큐에 쌓여있는 메시지를 조회하거나, BLOB 컨테이너 내의 파일을 편집하거나 다운로드하거나, 외부 공개 권한 설정 등을 관리할 수도 있게 되어있습니다. 이 서비스는 Windows Azure REST API를 이용하여 관리하므로 Windows Azure Platform의 요금 정책에 관계없이 편리하게 이용할 수 있습니다.

jQuery를 이용하여 POST 방식의 WCF 서비스 호출하기

dojo와 더불어서 jQuery는 요즈음 웹 상에서 널리 사용되고 인기도가 높은 자바스크립트 프레임워크들 중 하나입니다. 작은 Foot-print를 유지하면서 무엇하나 모자람이 없는 기능을 제공하고 있고, 또한 ASP.NET 개발자들 사이에서는 ASP.NET MVC에서 공식 채택하기 이전부터 널리 사용되어온 자바스크립트 프레임워크입니다.


jQuery는 AJAX 기능 뿐만 아니라 비동기적으로 자바스크립트를 로드하고, 직렬화된 JSON 컨텐츠를 복원하여 메모리 상에 되살려놓을 수 있는 기능까지 내장하고 있습니다. 하지만 딱 한 가지 아쉬운 점이 있었는데 그 점은 바로 WCF가 노출하는 Contract들 중에서 POST 방식으로 호출해야 할 때 사용이 불편하다는 점입니다.


REST (GET) 방식으로 호출하는 방법은 대개 유용합니다. URL을 이용하여 호출하는 것이므로 프로그래밍하기에는 훨씬 간단한 방법일 수 있습니다. 하지만 경우에 따라서 전달해야 하는 매개 변수의 수가 많거나 복잡한 자료 구조를 전달해야 하는 경우 적절하지 않을 수 있습니다.


이 Article에서는 jQuery를 이용하여 POST 방식의 WCF 서비스를 호출하는 방법을 다뤄보기로 하겠습니다. 이 Article에서 사용하는 Code의 원본은 http://www.west-wind.com/weblog/posts/324917.aspx 에서 가져온 것임을 밝혀둡니다.



 public static void NoCaching(WebOperationContext context)
 {
     if (context == null)
         return;


     context.OutgoingResponse.Headers[“Pragma”] = “no-cache”;
     context.OutgoingResponse.Headers[“Cache-Control”] = “no-cache”;
 }


 [OperationContract]
 [WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
 public int CreateArticle(int boardID, string title, string contents)
 {
        NoCaching(WebOperationContext.Current);


        if (!Security.IsLoggedOn)
            return (-1);


        int? newArticleID = null;
        this.dataContext.CreateArticle(
            (int?)boardID,
            title,
            (int?)Security.CurrentUserID,
            contents,
            ref newArticleID);


        return newArticleID.HasValue ? newArticleID.Value : (-1);
 }


위의 코드는 Internet Explorer가 내장하는 XMLHttpRequest의 캐싱 기능을 사용하지 않도록 응답을 내보내는 POST 방식의 WCF Contract 코드 예제입니다. [WebGet] 대신 [WebInvoke]가 사용된 것을 확인하면 됩니다. 그리고 입력과 출력 형식을 모두 JSON으로 지정하였습니다.


이제 아래의 코드를 별도의 JavaScript 파일로 저장합니다.



jQuery.invokeWcf = function(serviceUri, method, data, callback, error, bare) {
    var json = JSON.stringify(data);
    var url = serviceUri + ‘/’ + method;


    $.ajax({
        url: url,
        data: json,
        type: ‘POST’,
        processData: false,
        contentType: ‘application/json’,
        timeout: 10000,
        dataType: ‘text’,
        success: function(rawResult) {
            if (!callback) {
                return;
            }


            var result = JSON.parse(rawResult);


            if (bare) {
                callback(result);
                return;
            }


            for (var eachProperty in result) {
                callback(result[eachProperty]);
                break;
            }
        },
        error: function(xmlHttpRequest) {
            if (!xmlHttpRequest) {
                return;
            }


            if (xmlHttpRequest.responseText) {
                var errorMessage = JSON.parse(xmlHttpRequest.responseText);
                if (errorMessage) {
                    error(errorMessage);
                } else {
                    error({ Message: ‘Unknown server error found.’ });
                }
            }


            return;
        }
    });
};


그리고 위의 코드를 사용하기 위하여 JSON2.js 파일이 별도로 필요합니다. JSON2.js는 http://www.json.org/js.html 페이지에서 다운로드할 수 있습니다. 마지막으로, jQuery 플러그인으로 개발된 위의 코드를 사용하기 위하여 jQuery를 추가해야 합니다. 위의 코드는 1.3.2 버전에서 테스트하였습니다.


이제 위의 코드를 호출해보기로 하겠습니다.


var editorInstance = FCKeditorAPI.GetInstance(‘<%= this.articleBody.ClientID %>’);
var data = {
    boardID: parseInt(boardID),
    title: $(‘#’ + ‘<%= this.articleTitle.ClientID %>’).attr(‘value’),
    contents: editorInstance.GetXHTML()
};

$.invokeWcf(‘Board.svc’, ‘CreateArticle’, data, function(result) {
    result = result.toString();
    if (result == ‘-1’) {
        window.alert(‘글 쓰기 도중 오류가 발생하였습니다.’);
        return;
    }
    if ($(‘#fileQueue > .uploadifyQueueItem’).size() > 0) {
        $(‘#fileUploads’).uploadifySettings(‘script’, ‘UploadHandler.ashx?ID=’ + result.toString());
        $(‘#fileUploads’).bind(‘uploadifyAllComplete’, function(event, data) {
            window.location.replace(‘ViewArticle.aspx?ID=’ + result.toString());
        });
        $(‘#fileUploads’).uploadifyUpload();
    } else {
        window.location.replace(‘ViewArticle.aspx?ID=’ + result.toString());
    }
}, function(result) { window.alert(result); });


실제 WCF가 제공하거나 입력시 필요로 하는 JSON 코드의 경우 jQuery가 내장하는 getJSON 함수로 다루기에는 까다로운 부분이 많았습니다. 하지만 위의 코드에서처럼 매개 변수를 동적으로 프로그래밍하고 함수 인자를 전달하는 것 만으로 모든 처리가 이루어지게 됩니다.


많은 도움이 되었기를 바라며 글을 마무리합니다.


ps. jQuery를 활용하는 RIA 기반 File Upload 솔루션을 찾고 있다면 uploadify (http://www.uploadify.com) 의 소스 코드를 활용해 보실 것을 권합니다. 무료로 사용 가능하며 약간의 테스트와 개발을 통하여 손쉽게 적용할 수 있습니다.