URI (별칭식 경로 : Uniform Resource Identifier 통합 자원 식별자)
URI는 특정 리소스를 식별하는 경로를 의미한다. 웹 기술에서 사용하는 논리적 또는 물리적 리소스를 식별하는 고유한 문자열 시퀀스다.
URL (절대 경로 : Uniform Resource Locator 또는 통칭 web address)
URL은 흔히 웹 주소라고도 하며, 컴퓨터 네트워크 상에서 리소스가 어디 있는지 알려주기 위한 규약이다. URI의 서브셋이다.
POST 방식은 기본 (URL)에 요청할 때 BODY 부분에 데이터를 넘겨주는 방식입니다.
Spring 공부를 하면 해당 API 들을 직접 호출 및 테스트 해볼 수 있게 만들면 좋겠네요.
POST 방식은 코드만 올리겠습니다.
1개 보내는 방식, multipart 로 2개 이상의 다른 데이터 보내는 방식입니다.
using System;
using System.IO; //Stream
using System.Net; //HttpWebRequest, WebRequest 등 사용
using System.Windows.Forms;
using System.Net.Security; //SSL (Secure Sockets Layer) 관련
using System.Security.Cryptography.X509Certificates; //암호화 된 인증서 관련
using System.Text;
namespace WindowsFormsApp_POST_HttpRequest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PostRequest();
}
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
//인증서에 대한 결과를 보려면 여기서 브레이크 걸고 certificate, chain 등을 살펴보면 됩니다.
//권장하지 않는 방법이지만 인증 기관에 대해 true로 설정해둡니다.
return true;
}
private void PostRequest()
{
//****************************** 이 부분은 첫 사용하기 전에만 넣어주면 됩니다. ***********************************
//웹 통신 시 System.Net.WebException : 기본 연결이 닫혔습니다. 관련 에러 방지용 프로토콜 정의입니다.
//Secure Sockets Layer, Transport Layer Secure
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12 |
SecurityProtocolType.Ssl3;
//https (hyper text transfer protocol Secure : 전송 규약 보안) 보안이 올바른지 확인하는 구문입니다.
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
//****************************************************************************************************************
//[ContentType] : Body에서 전송되는 콘텐츠의 유형을 서버에 알려줍니다.
// MIME (Multipurpose Internet Mail Extensions) 표준을 따릅니다.
//
//ex)
//1. multipart/form-data 2개 이상으로 한 번에 보낼 때 boundary와 함께 사용
//2. application/json 제이슨 형태
//3. application/x-www-urlencoded 기본 타입
//4. image/tiff 이미지, 확장자
// 등 등
//한 개의 데이터를 POST 방식으로 보내기
PostRequestOne();
//2개 이상의 데이터를 POST 방식으로 보내기
//multipart/form-data 방식으로 사용되며 줄 구분을 위한 boundary가 필요
PostRequestAll();
}
private void PostRequestOne ()
{
string uri = textBox_uri.Text;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); //요청 준비
HttpWebResponse response = null;
try
{
request.Method = "POST"; //기본 값은 GET 입니다.
request.ContentType = "application/x-www-form-urlencoded"; //url encoded 방식 변수=값&변수1=값..
string userName = "name";
string password = "1234"; //서버와 협의하여 해쉬 등으로 암호화
string data = string.Format("userName={0}&password={1}", userName, password);
//request body에 데이터 채우기
byte[] buffer = Encoding.UTF8.GetBytes(data);
Stream requestStream = request.GetRequestStream(); //request에 보낼 데이터 입력용
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Close();
//응답 결과 받기
response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader responseStreamReader = new StreamReader(responseStream);
//응답 값 받아서 리턴하거나 사용하면 됩니다.
string result = responseStreamReader.ReadToEnd();
responseStreamReader.Close();
responseStream.Close();
response.Close();
}
catch (Exception ex)
{
//로그 남기면 좋을 듯
MessageBox.Show("Request Error" + Environment.NewLine + ex.ToString());
}
finally
{
if (response != null)
{
response.Close();
}
}
}
private void PostRequestAll ()
{
string uri = textBox_uri.Text;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); //요청 준비
HttpWebResponse response = null;
try
{
request.Method = "POST"; //기본값은 GET
//그 밖에도 timeout, credential 등 다양한 옵션을 줄 수 있습니다.
//https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
//2개 이상 multipart로 보내는 방법
//보낼 값) field1 = value, 파일 = byte file
//경계를 통해 데이터 타입 명시 및 다음과 같은 형태로 만들어서 보내면 됩니다.
/*
Content-Type: multipart/form-data; boundary=isBoundary
--isBoundary
Content-Disposition: form-data; name="field1"
value
--isBoundary
Content-Disposition: form-data; name="파일"; filename="myImage.tiff" (filename은 부가적인 부분으로 없어도 된다고 봤네요.)
Content-Type: image/tiff (타입에 대한 명시 필요)
byte file
--isBoundary-- (경계의 끝은 -- 붙여주기)
*/
string endLine = "\r\n"; //웹에서 개행을 나타내는 문자열입니다.
string boundary = "isBoundary"; //구분자입니다. --isBoundary ~ --isBoundary-- 로 끝나게 됩니다.
request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
byte[] boundaryBytes = Encoding.ASCII.GetBytes(endLine + "--" + boundary + endLine);
Stream requestStream = request.GetRequestStream();
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
//
//--isBoundary
//
string field1 = "field1";
string value = "value";
string data = string.Format("Content-Disposition: form-data; name=\"{0}\"{1}{2}{3}", field1, endLine, endLine, value);
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
requestStream.Write(dataBytes, 0, dataBytes.Length);
//[진행 현황]
//
//--isBoundary
//Content-Disposition; form-data; name="field1"
//
//value
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
//[진행 현황]
//
//--isBoundary
//Content-Disposition; form-data; name="field1"
//
//value
//--isBoundary
//
string name = "파일";
string filename = "myImage.tiff";
string data2 = string.Format("Content-Disposition: form-data; name=\"{0}\" filename=\"{1}\"{2}Content-Type: image/tiff{3}{4}",
name, filename, endLine, endLine, endLine);
byte[] data2Bytes = Encoding.UTF8.GetBytes(data2);
requestStream.Write(data2Bytes, 0, data2Bytes.Length);
//[진행 현황]
//
//--isBoundary
//Content-Disposition; form-data; name="field1"
//
//value
//--isBoundary
//Content-Disposition: form-data; name="파일" filename="myImage.tiff"
//Content-Type: image/tiff
//
//
//예시 경로 파일 바이트로 읽어서 보내기
string imagePath = @"c:\temp\myImage.tiff";
FileStream fileStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
byte[] imageBuffer = new byte[4096];
int bytesRead = 0;
while (true)
{
bytesRead = fileStream.Read(imageBuffer, 0, imageBuffer.Length);
if (bytesRead <= 0) //이미지 바이트 다 읽은 경우
{
break;
}
requestStream.Write(imageBuffer, 0, bytesRead);
}
fileStream.Close();
byte[] endBoundaryByte = Encoding.ASCII.GetBytes(endLine + "--" + boundary + "--" + endLine);
requestStream.Write(endBoundaryByte, 0, endBoundaryByte.Length);
//[진행 현황]
//
//--isBoundary
//Content-Disposition; form-data; name="field1"
//
//value
//--isBoundary
//Content-Disposition: form-data; name="파일" filename="myImage.tiff"
//Content-Type: image/tiff
//
//byte file
//--isBoundary--
response = (HttpWebResponse)request.GetResponse(); //요청 후 결과 반환
Stream responseStream = response.GetResponseStream(); //요청에 대한 stream 가져오기
StreamReader responseStreamReader = new StreamReader(responseStream); //해당 stream 읽기 위한 streamReader
//응답값 받아서 리턴하거나 사용하면 됩니다.
string result = responseStreamReader.ReadToEnd();
responseStreamReader.Close();
responseStream.Close();
response.Close();
}
catch (Exception ex)
{
//로그 남기면 좋을 듯
MessageBox.Show("Request Error" + Environment.NewLine + ex.ToString());
}
finally
{
if (response != null)
{
response.Close();
}
}
}
}
}
'C# > Windows Form' 카테고리의 다른 글
[C# Windows Form] FormBorderStyle : None 일 때 폼 크기 변경 및 움직이기 (WndProc 사용) (0) | 2024.01.27 |
---|---|
[C# Windows Form] 로컬 프로그램 간 통신 SendMessage (0) | 2022.12.04 |
[C# Windows Form] HttpWebRequest Get 방식 통신 (0) | 2022.12.03 |
[C# Windows Form] 로그 남기는 방법 (DateTime, 컴파일 서비스 CallerMember, CallerFilePath, CallerLineNumber) (0) | 2022.11.26 |
[C# Windows Form] Alt + Tab, Ctrl + Esc 등 특수 키 막기 (키보드 후킹) (0) | 2022.11.22 |