C#에서 HTTP POST로 JSON 데이터 보내는 방법

회사 업무 중 HTTP POST로 Request Body에 JSON을 넣어서 보내야 할 일이 있어서 간단하게 짜본 WinForm 프로그램이다.

이런 코드들을 간단하면서도 막상 필요할 때 찾아서 쓰기가 귀찮아서 찾아보기 쉽게 여기에 적어둔다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://127.0.0.1:40080/Default.aspx?cmd=2");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";

using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{"kakao_id":"1","image_url":"http://teste11111.com","public_profile":"Y"}";

streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();

var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
MessageBox.Show(result);
}
}
}
}
}

 

C#에서 엔디안 변경

C#에서 네트워크 통신을 할게 있어서 바이트오더를 빅엔디안으로 해주려다가 알게 된게 있어서 정리한다.

일단 바이트오더링을 하기 위해 리틀엔디안-빅엔디안의 변환이 필요한데 C#에는 이를 지원하는 메서드가 이미 있었다.

http://msdn.microsoft.com/en-us/library/fw3e4a0f 에 있는 HostToNetworkOrder 와 NetworkToHostOrder 라는 메서드인데 이상한건 이 메서드들이 int16, int32, int64만 지원한다는 것이다. 난 uint16, uint32를 변경해야했기에 아무리 해봐도 이 메서드를 통해서는 바이트오더를 변경할 수 없었다. 강제로 형변환도 해봤지만 데이터가 잘못 들어가기만 했다.

구글을 한참 뒤져서 스택오버플로우에서 답을 찾았다.

http://stackoverflow.com/questions/11232594/c-sharp-reversed-ushort

위 링크의 리플처럼 다음의 코드를 사용하면 된다.

var arr = new byte[1];

arr = BitConverter.GetBytes(total_length);
Array.Reverse(arr);
arr.CopyTo(buffer, offset);
offset += Marshal.SizeOf(total_length);

원리는 바이트배열을 선언하고 비트컨버터를 통해 바이트를 구한다음 Array.Reverse()를 통해 바이트를 거꾸로 하는 것이다. 한마디로 바이트오더링을 직접 구현한 것이라고 보면 될 것 같다.

여튼 이 코드를 통해 테스트해보니 정상작동함을 확인했다.

C#에서 엑셀 문서 저장하기

ClosedXML_small2C#으로 사내용으로 쓸 프로그램을 만들다가 엑셀 파일로 저장해야할 일이 생겼다.

인터넷을 찾아헤메다가 결국은 내가 사용하게 된 방법에 대해 정리한다.

찾아본 끝에 내린 결로은 OpenXML 기술을 이용하는 방식으로 택했다. .xlsx라는 가장 최신의 엑셀 포맷이고 MS오피스 뿐만 아니라 오픈오피스에서도 잘 지원한다. OpenXML이 무엇인가에 대해서는 구체적으로 나도 잘 모르겠다. 혹시 관심 있는 사람들은 위키 같은 곳을 찾아봄이 좋을듯하다. 난 엑셀 파일 읽고 쓰기가 필요한 것이지 엑셀 포맷 그 자체에는 별로 관심도 없거니와 알 필요성도 적어서(물론 알면 좋겠지만) 일단은 OpenXML에 대해 잠깐만 웹서핑을 해본 후 사용하기로 결정했다. OpenXML에 대해 더 알고 싶다면 다음의 페이지를 방문해보자.

OpenXML을 사용하기 위해서 ClosedXML 이라는 라이브러리를 이용할 것이고 http://closedxml.codeplex.com 를 참조하면 된다.

내 환경은 Visual Studio 2012 이며 C# Winform .NET 3.5 였는데 이 기능을 이용하기 위해서는 .NET 4.0 으로 프로젝트 설정을 변경해야했다. 4.0 아래 버전에서는 호환이 안되기 때문에 오류가 난다.

다운로드 받은 후 압축을 풀어보면 몇개의 DLL파일과 XML 파일 등으로 이루어져 있으며 C#을 사용했던 사람이라면 별로 어려움 없이 사용할 수 있으리라 본다.

예제코드는 http://closedxml.codeplex.com/wikipage?title=Showcase&referringTitle=Home 에 설명되어 있고 이것을 참조하면서 만들면 별 무리가 없다.

엑셀 파일을 작성하는데 필요한 기초적인 기능은 충분히 제공된다. 결과적으로는 제대로 선택한 것 같고 별 어려움 없이 엑셀 문서를 작성할 수 있었다.

하나 주의할 사항이라면,

엑셀 파일로 작성할 내용이 많아지면 속도가 꽤나 느려질 수 있다. 특히 다수의 셀에 색상을 입힌다거나 Style 속성을 바꾸는 작업 등은 속도를 굉장히 느려지게 할 수 있으니 주의해야한다. 다수의 셀에 특정 Style을 적용하고 싶다면 for 루프를 돌면서 각 셀마다 Style을 지정하지 말고

ws.Range("B" + index.ToString() + ":D" + index.ToString()).Style.Font.Bold = true;
ws.Range("B" + index.ToString() + ":D" + index.ToString()).Style.Font.FontColor = XLColor.White;
ws.Range("B" + index.ToString() + ":D" + index.ToString()).Style.Fill.BackgroundColor = XLColor.Black;

와 같은 코드를 사용해서 한번에 잡아주는 것이 속도 향상에 도움이 된다.

예제페이지처럼 RangeTable을 잡고 한번에 적용해주면 더 속도향상이 되리라 생각하지만 이렇게 하기에는 너무 귀찮아져서 일단은 난 행단위로 처리했다.

(이 ClosedXML 라이브러리를 이용했다면 프로그램 배포시 ClosedXML.DLL 파일도 같이 배포해야하니 이것 역시 주의하자.))

개발이 모두 끝나고서 알게된 것이지만 ClosedXML은 .NET 4.0용과 .NET 3.5용이 있었다. 이런 젠쟝… ( http://closedxml.codeplex.com/releases/view/96561 )

C++ 개발자를 위한 C# 에 대한 문서

visualcsharp_2

 

회사에서 게임관리툴을 만들기 위해 C#을 애용하고 있다. 이유는 무엇보다도 생산성이 높으니까. MFC 같은 것으로 해도 되지만 MFC는 번거로운 면도 많을뿐더러 MS가 C#을 밀고 있기 때문이다. (추가적으로 개인적으로는 MFC를 그리 싫어하는 편은 아니지만내 주위 동료프로그래머들은 MFC를 그리 좋아하지 않았다.)

 

그런데 C#을 하다보면 C++에서 나왔던 습관들이나 C++에서 쓰던 것들이 없어서 난처할 때가 가끔 있다. 예를 들면, memcpy()나 typedef 같은 것들 말이다. C++을 하면 유용하게 자주 썼던 memcpy()가 없으니 어찌나 당황스럽던지…

이런 것들을 일목 요연하게 정리해놓은 문서가 없나 찾다가 마이크로소프트에서 정리해놓은 문서를 찾았다.

 

제목도 C++ 개발자를 위한 C# 이라는 문서이다.

 

C#을 접하며 나처럼 당황해하는 개발자들을 위한 문서이니 참조해보면 좋을 것 같다. Visual Studio 2008용이고 무려 2007년에 작성된 문서이긴 하지만 별로 달라진게 없을 것 같으므로 참조하자.

C#에서 레지스트리 읽고 쓰는 방법

Registry 클래스를 이용한다.

일단 소스 상단에 using Microsoft.Win32를 선언해준다.

RegistryKey reg;
reg = Registry.LocalMachine.CreateSubKey("Software").CreateSubKey("RegistryKeyTest");
SetValue()를 통해 값을 설정하고 GetValue()를 통해 값을 읽어올 수 있다.

reg.SetValue("Text", "글을 입력하겠소"); // 값을 저장한다.
reg.GetValue("Text", "없음")     // text라는 이름을 가진 값을 가져온다.
// 이때 값이 없다면 "없음" 이라고 값을 얻어온다.
reg.GetValue("Text") // text라는 이름을 가진 값을 가져온다.
레지스트리에 값을 삭제할 때는 DeleteSubkey()를 쓴다.

reg.DeleteSubKey("Text", false); // 값을 삭제한다.
Registry.LocalMachine.DeleteSubKey("Software\RegistryKeyTest"); // 레지스트리키를 삭제한다.

출처 : http://happyguy81.blog.me/10148698440

 

2013년 5월 13일 추가.

이 기능을 사용하려면 프로그램을 관리자 권한으로 실행해야 정상작동한다. 관리자 권한으로 실행하지 않았을시에는 오류가 발생할 수 있다. 때문에 내 경우에는 힘들여만들어놓은 이 기능을 안 쓰고 파일을 이용하도록 변경해 나가는 중.

C#에서 Byte[]와 String간 변환하기

서버에서 받은 데이터를 byte[]에 문자열을 저장하고 Message.Show()로 보여주려고 했더니 System.Byte[]만 계속 찍혔다.

뭐가 문제인가 네이버에서 찾아봤더니 좋은 글 발견.

String을 byte[]로 변환하려면,
byte[] ba = System.Text.Encoding.Default.GetBytes(str);

byte[]를 String으로 변환하려면,
String str = System.Text.Encoding.Default.GetString(ba);

출처 : http://blog.naver.com/hursh1225?Redirect=Log&logNo=40120911491