본문 바로가기
Dotnet/.NET , ASP.NET CORE

C#에서의 http 요청/응답/사용

by 잘먹는 개발자 에단 2024. 11. 19.

Http Get 요청

public async Task<string> SendHttpGet(string url){
	try{
    	using(HttpClient client = new HttpClient()){
        	HttpResponseMessage response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode();
            
            string responseBody = await response.Content.ReadAsStringAsync();
            return responseBody;
        }
    }catch(Exception e){
    	Console.WriteLine(e.Message);
        return string.Empty;
    }
}

 

참고로 async로 비동기로 값을 받아올 때에는 Task<결과물 형>을 명시해줘야 한다. 

이것은 비동기의 결과가 <결과물 형> 임을 알려준다.

 

 

 

 

Http Post 요청

public asnyc Task<string> SendHttpPonst(string url, string body){
	try{
    	using(HttpClient client = new HttpClient()){
        	HttpResponseMessage response = await client.PostAsync(url, new StringContent(body, Encoding.UTF8, "application/json"));
            response.EnsureSuccessStatusCode();
            
            string responseBody = await response.Content.ReadAsStringAsync();
            
            return responseBody;
        }
    }catch(Exception e){
    	Console.WriteLine(e.message);
        return string.Empty;
    }
}

 

HttpResponseMessage.EnsureSuccessStatusCode

이 메서드는 http 응답의 상태코드를 확인하고, 상태코드가 성공적인 응답을 나타내지 않을 경우, 예외를 던진다.

이 메서드는 HttpClient로부터 받은 HttpResponseMessage 객체의 상태코드를 확인한다.

만약에 성공적인 응답인 200-299 범위라면 아무런 동작을 하지 않고, 다음 코드를 실행한다.

하지만 아니라면, 예외를 던진다. 이 예외를 잡아서 처리를 해주면 된다. 

 

HttpResponseMessage.Content

이것은 자바스크립트의 response.data와 유사한 개념이다.

response.Content는 HttpClient를 통해 수신한 http 응답의 내용을 나타낸다. 이 속성은 HttpContent 형식을 반환하며, 실제 응답 데이터에 액세스하기 위해서 ReadAsStringAsync() 메서드를 사용하여 문자열로 변환할 수 있다. 

상태 코드의 경우는 HttpResponseMessage .StatusCode이다.

 

 

 

자바스크립트와 C#이 크게 다른 것은 JSON 객체를 주고 받을 때, C#은 역직렬화, 직렬화 과정을 거쳐야한다는 것이다.

때문에 응답을 받아올 때 DTO를 일일히 작성해줘야 하는 불편함이 있다. 

더욱이 POST 요청을 보낼 때, BODY에 JSON 객체를 보내야 한다면 이것 역시 텍스트로 직렬화 해서 보내야 한다.

 

때문에 

string post_param = '{' + $"\"id\":\"{IdTextBox.Text}\"," + $"\"pw\":\"{PwTextBox.Text}\"" + '}';

 

이러한 불편함이 있다. 

 

 

예시로 POST 요청을 비동기로 보내고, 이를 DTO를 활용해서 처리하는 예제를 보겠다.

 

async private void LoginButton_Click(object sender, EventArgs e){
	string url = "https://example.co.kr/example.php?action=login";
    string post_param = '{' + $"\"id\":\"{IdTextBox.Text}\"," + $"\"pw\":\"{PwTextBox.Text}\"" + '}';
	
    CustomHttp httpInstance = new CustomHttp();
    string response = await httpInstance.SendHttpPost(url, post_param);
    
    DTOs.LoginPostDTO loginedUser = JsonSerializer.Deserialize<DTOs.LoginPostDTO>(response);
}

 

* JsonSerializer.Deserialize<Type>(JsonString) 메서드

이 메서드는 json 문자열을 지정된 형식의 객체로 역직렬화하는 역할을 합니다.

이 메서드는 닷넷에서 json데이터를 처리하는데 사용되는 기능 중 하나입니다.

 

이 메서드는 JSON 문자열을 역직렬화하여 지정된 형식의 객체로 변환합니다.

이를 통해서 직렬화된 JSON 데이터를 닷넷 객체로 사용할 수 있습니다.

역직렬화된 객체는 Type(보통 DTO)로 지정된 형식의 인스턴스로 반환됩니다.

 

 

그런데 위의 코드를 보면 상당히 불편한 점이 하나 있다. 

바로 이 부분

string post_param = '{' + $"\"id\":\"{IdTextBox.Text}\"," + $"\"pw\":\"{PwTextBox.Text}\"" + '}';

 

이 부분은 C#의 익명형식을 사용하면 가능하다. 

익명형식은 이름이 없는 클래스라고 생각하면 되고, 간단한 데이터 구조를 표현하기 위해서 사용된다.

 

익명형식 그러니까 이 이름이 없는 클래스의 인스턴스를 만든다음에 System.Text.Json 네임스페이스의 JsonSerializer.Serialize() 메서드를 사용해서 C# 객체를 JSON 문자열로 변환한다.

 

이 경우에, 익명형식 객체가 JSON 형식으로 직렬화 되어 post_param에 저장된다. 

var loginData = new {
	id = IdTextBox.Text, pw = PwTextBox.Text
};

string post_param = JsonSerializer.Serialize(loginData);

 

 

그렇다면 궁금한 것이 한가지 생긴다. 

DTO 쓰지 않고, 거기에도 익명형식을 쓰면 간단해지지 않나요?

 

익명형식을 써보려고 하긴 했는데, 강타입 언어인 C#에서 그런 식으로 머리를 굴리면 

더 힘들어진다...