네이버 오픈 API를 데이터 소스로 사용하여 Windows Forms에 Binding하는 샘플을 간단히 만들어보았습니다. 지난번에 예를 들었던 난수 생성을 위한 데이터 소스에서 언급했던 IListSource 인터페이스의 사용법을 기초로 발전시킨 샘플입니다. :-)
using System;
using System.IO;
using System.Net;
using System.Xml;
using System.Data;
using System.Text;
using System.Collections;
using System.Globalization;
using System.ComponentModel;
namespace OpenApiBinding
{
[ToolboxItem(true)]
[DesignTimeVisible(true)]
public partial class NaverSearchBinding : Component, IListSource
{
public NaverSearchBinding()
: this(null)
{
}
public NaverSearchBinding(Container container)
: base()
{
if (container != null)
container.Add(this);
this.InitializeComponent();
this.key = String.Empty;
this.target = NaverSearchTarget.WebDocuments;
this.query = String.Empty;
this.display = 100;
this.start = 1;
this.sort = NaverSortMode.Similarity;
}
private string key;
private NaverSearchTarget target;
private string query;
private int display;
private int start;
private NaverSortMode sort;
[NonSerialized]
private const string RequestUrl = "http://openapi.naver.com/search";
[Browsable(true)]
[DefaultValue("")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string Key
{
get { return this.key; }
set { this.key = (value ?? String.Empty).Trim(); }
}
[Browsable(true)]
[DefaultValue(NaverSearchTarget.WebDocuments)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public NaverSearchTarget Target
{
get { return this.target; }
set { this.target = value; }
}
[Browsable(true)]
[DefaultValue("")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string Query
{
get { return this.query; }
set { this.query = (value ?? String.Empty).Trim(); }
}
[Browsable(true)]
[DefaultValue(100)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int Display
{
get { return this.display; }
set { this.display = value; }
}
[Browsable(true)]
[DefaultValue(1)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int Start
{
get { return this.start; }
set { this.start = value; }
}
[Browsable(true)]
[DefaultValue(NaverSortMode.Similarity)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public NaverSortMode Sort
{
get { return this.sort; }
set { this.sort = value; }
}
public override string ToString()
{
return String.Format(
CultureInfo.CurrentCulture,
"{{ Target: '{0}', Query: '{1}' }}",
this.target,
this.query);
}
private Uri CreateUri()
{
if (String.IsNullOrEmpty(this.key))
return null;
StringBuilder buffer = new StringBuilder();
buffer.AppendFormat("key={0}&", this.key);
switch (this.target)
{
case NaverSearchTarget.Blog:
buffer.Append("target=blog&");
break;
case NaverSearchTarget.Cafe:
buffer.Append("target=cafe&");
break;
case NaverSearchTarget.CafeArticles:
buffer.Append("target=cafearticle&");
break;
case NaverSearchTarget.News:
buffer.Append("target=news&");
break;
default:
case NaverSearchTarget.WebDocuments:
buffer.Append("target=webkr&");
break;
}
buffer.AppendFormat("query={0}&", this.query);
buffer.AppendFormat("display={0}&", this.display);
buffer.AppendFormat("start={0}&", this.start);
switch (this.sort)
{
default:
case NaverSortMode.Similarity:
buffer.Append("sort=sim");
break;
case NaverSortMode.Date:
buffer.Append("sort=date");
break;
case NaverSortMode.Member:
buffer.Append("sort=member");
break;
case NaverSortMode.NewArticles:
buffer.Append("sort=newArticles");
break;
case NaverSortMode.Rank:
buffer.Append("sort=rank");
break;
}
return new Uri(String.Concat(RequestUrl, '?', buffer.ToString()));
}
public IList GetList()
{
Uri requestUri = this.CreateUri();
if (requestUri == null)
return null;
WebRequest webRequest = WebRequest.Create(requestUri);
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream webResponseStream = webResponse.GetResponseStream())
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(webResponseStream);
DataTable inferencedTable = new DataTable(this.target.ToString());
switch (this.target)
{
case NaverSearchTarget.Blog:
inferencedTable.Columns.Add("title", typeof(string));
inferencedTable.Columns.Add("link", typeof(string));
inferencedTable.Columns.Add("description", typeof(string));
inferencedTable.Columns.Add("bloggername", typeof(string));
inferencedTable.Columns.Add("bloggerlink", typeof(string));
break;
case NaverSearchTarget.Cafe:
inferencedTable.Columns.Add("title", typeof(string));
inferencedTable.Columns.Add("link", typeof(string));
inferencedTable.Columns.Add("description", typeof(string));
inferencedTable.Columns.Add("ranking", typeof(string));
inferencedTable.Columns.Add("member", typeof(string));
inferencedTable.Columns.Add("totalarticles", typeof(string));
inferencedTable.Columns.Add("newarticles", typeof(string));
break;
case NaverSearchTarget.CafeArticles:
inferencedTable.Columns.Add("title", typeof(string));
inferencedTable.Columns.Add("link", typeof(string));
inferencedTable.Columns.Add("description", typeof(string));
inferencedTable.Columns.Add("cafename", typeof(string));
inferencedTable.Columns.Add("cafeurl", typeof(string));
break;
case NaverSearchTarget.News:
inferencedTable.Columns.Add("title", typeof(string));
inferencedTable.Columns.Add("link", typeof(string));
inferencedTable.Columns.Add("description", typeof(string));
inferencedTable.Columns.Add("originallink", typeof(string));
inferencedTable.Columns.Add("pubDate", typeof(string));
break;
default:
case NaverSearchTarget.WebDocuments:
inferencedTable.Columns.Add("title", typeof(string));
inferencedTable.Columns.Add("link", typeof(string));
inferencedTable.Columns.Add("description", typeof(string));
break;
}
foreach (XmlNode eachNode in xmlDocument.SelectNodes("/rss/channel/item"))
{
XmlElement eachElement = eachNode as XmlElement;
if (eachElement == null)
continue;
int i = 0;
object[] values = new object[inferencedTable.Columns.Count];
foreach (DataColumn eachColumn in inferencedTable.Columns)
values[i++] = eachElement.SelectSingleNode(eachColumn.ColumnName).InnerXml;
inferencedTable.Rows.Add(values);
}
return inferencedTable.DefaultView;
}
}
}
public bool ContainsListCollection
{
get { return true; }
}
}
[Serializable]
public enum NaverSearchTarget : int
{
Blog,
Cafe,
CafeArticles,
WebDocuments,
News
}
[Serializable]
public enum NaverSortMode : int
{
Similarity,
Date,
Member,
NewArticles,
Rank
}
}
위의 소스 코드를 프로젝트에 추가하여 Windows Forms – 또는 – ASP.NET 프로젝트에 연결하거나, 독립적으로 객체를 만들어서 사용하는 것이 가능합니다. 다음은 Windows Forms 디자인 타임에서의 사용 예시입니다.
컴포넌트에서 API Key를 Key 프로퍼티에 설정하고, 검색어를 Query 프로퍼티에 설정하여 검색 결과를 수신할 수 있습니다. 데이터 그리드를 이용하여 수신한 데이터를 곧바로 보여줄 수도 있습니다.
'Software Development > .NET Framework' 카테고리의 다른 글
| C# Image Viewer Control 샘플 (2) | 2010/01/19 |
|---|---|
| AppDomain 프로그래밍에 대한 이야기 (2) | 2010/01/18 |
| 네이버 오픈 API X Windows Forms Binding (2) | 2009/12/20 |
| 메서드에 PreCondition/PostCondition 구현하기 (0) | 2009/10/20 |
| 새로운 MSDN Library의 URL 시스템 200% 활용하기 [Update] (1) | 2009/09/28 |
| ECMA C# / ECMA CLI에 대한 Microsoft Community Promise 시행 (0) | 2009/07/15 |