ASP.NET Web API Self Host 패키지 설치
프로젝트 개발 환경에서 NuGet 패키지 관리자를 통해 ASP.NET Web API Self Host 패키지를 다운로드하고 설치합니다. 이 패키지는 별도의 IIS 서버 없이 독립적으로 실행 가능한 Web API 서비스를 구축할 수 있게 해줍니다.
API 컨트롤러 구현
Web API의 핵심이 되는 컨트롤러 클래스를 생성합니다. 이 클래스는 ApiController 클래스를 상속하며, 클라이언트의 요청을 처리하는 다양한 액션 메서드를 포함하게 됩니다.
1 public class FileApiController : ApiController
연결 테스트용 Ping 메서드
클라이언트와 서버 간 연결이 정상적으로 이루어졌는지 확인하기 위한 간단한 Ping 엔드포인트를 구현합니다. 이 메서드는 URI 파라미터로 전달받은 이름을 출력하고, 정상 응답을 반환합니다.
1 /// <summary>
2 /// 서버 연결 테스트
3 /// </summary>
4 /// <param name="userName">테스트 사용자명</param>
5 /// <returns></returns>
6 [HttpPost]
7 public HttpResponseMessage CheckConnection([FromUri] string userName)
8 {
9 Console.WriteLine("수신 데이터: " + userName);
10 return Request.CreateResponse(HttpStatusCode.OK, "SUCCESS");
11 }
파일 업로드 처리 메서드
클라이언트로부터 파일을 수신하여 지정된 경로에 저장하는 기능을 구현합니다. 비동기 처리 방식을 활용하여 대용량 파일도 효율적으로 전송할 수 있으며, 수신된 파일은 원래 이름으로 저장됩니다.
1 /// <summary>
2 /// 파일 업로드 처리
3 /// </summary>
4 /// <param name="savePath">파일 저장 경로</param>
5 /// <returns></returns>
6 [HttpPost]
7 public async Task<HttpResponseMessage> UploadFile([FromUri] string savePath)
8 {
9 try
10 {
11 if (!Directory.Exists(savePath))
12 Directory.CreateDirectory(savePath);
13
14 var streamProvider = new MultipartFormDataStreamProvider(savePath);
15 await Request.Content.ReadAsMultipartAsync(streamProvider);
16
17 foreach (var fileData in streamProvider.FileData)
18 {
19 var contentHeader = fileData.Headers.ContentDisposition;
20 var fileName = contentHeader.FileNameStar ?? contentHeader.FileName;
21 var tempPath = fileData.LocalFileName;
22 var destPath = Path.Combine(savePath, fileName);
23
24 File.Move(tempPath, destPath);
25 Console.WriteLine("파일 수신 완료: " + destPath);
26
27 // 수신된 파일 내용 확인 (로그 출력)
28 using (var fileStream = new FileStream(destPath, FileMode.Open, FileAccess.Read))
29 {
30 using (var reader = new StreamReader(fileStream))
31 {
32 string line;
33 while ((line = reader.ReadLine()) != null)
34 {
35 Console.WriteLine(line);
36 }
37 }
38 }
39 }
40 return Request.CreateResponse(HttpStatusCode.OK, "UPLOAD_COMPLETE");
41 }
42 catch (Exception ex)
43 {
44 return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
45 }
46 }
Web API 서버 기동 클래스
API 서버를 시작하고 관리하기 위한 클래스를 구현합니다. HttpSelfHostServer를 활용하여 지정된 주소에서 리스닝을 시작하며, 라우팅 테이블을 구성하여 URL 패턴에 맞는 컨트롤러 및 액션으로 요청을 라우팅합니다.
1 public class ApiHostManager
2 {
3 private static HttpSelfHostServer _server = null;
4
5 public static void Initialize()
6 {
7 try
8 {
9 var baseAddress = new Uri("http://localhost:8080/");
10 var config = new HttpSelfHostConfiguration(baseAddress);
11
12 config.Routes.MapHttpRoute(
13 name: "DefaultApi",
14 routeTemplate: "api/{controller}/{action}/{id}",
15 defaults: new { id = RouteParameter.Optional });
16
17 // 대용량 파일 전송을 위한 버퍼 크기 확장
18 config.MaxReceivedMessageSize = int.MaxValue;
19
20 _server = new HttpSelfHostServer(config);
21 _server.OpenAsync().Wait();
22
23 Console.WriteLine("Web API 서비스 시작됨: " + baseAddress);
24 }
25 catch (Exception e)
26 {
27 Console.WriteLine("서버 시작 실패: " + e.Message);
28 }
29 }
30 }
클라이언트 구현
HttpClient 초기화
서버와 통신하기 위한 HttpClient 인스턴스를 생성합니다. 이 클라이언트는 애플리케이션 전역에서 재사용됩니다.
1 static HttpClient _httpClient = new HttpClient();
연결 테스트 요청
서버의 Ping 엔드포인트를 호출하여 연결 상태를 확인합니다.
1 private static async Task<string> VerifyConnection()
2 {
3 var requestUrl = "http://localhost:8080/api/FileApi/CheckConnection?userName=Admin";
4 var emptyContent = new StringContent(string.Empty);
5
6 var response = await _httpClient.PostAsync(requestUrl, emptyContent);
7 var result = await response.Content.ReadAsStringAsync();
8
9 return result;
10 }
파일 업로드 요청
로컬에 존재하는 파일을 서버로 전송합니다. MultipartFormDataContent를 활용하여 파일 데이터와 메타정보를 함께 전달하며, 스트림 형태로 파일 내용을 읽어 전송합니다.
1 private static async Task<string> SendFileToServer()
2 {
3 var sourceFile = @"C:\Data\sample.txt";
4 var targetPath = @"C:\Upload\";
5
6 Console.WriteLine("업로드 파일: " + sourceFile);
7
8 var requestUrl = "http://localhost:8080/api/FileApi/UploadFile?savePath=" + Uri.EscapeDataString(targetPath);
9
10 var formData = new MultipartFormDataContent();
11 var fileStream = new StreamContent(File.OpenRead(sourceFile));
12 fileStream.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
13 formData.Add(fileStream, "uploadFile", "sample.txt");
14
15 var response = await _httpClient.PostAsync(requestUrl, formData);
16 var result = await response.Content.ReadAsStringAsync();
17
18 return result;
19 }
핵심 포인트 정리
다중 파라미터 전달 여러 개의 파라미터를 전달할 때는 앰퍼샌드(&) 기호로 구분하여 쿼리 문자열을 구성합니다. 예를 들어, para1=value1¶2=value2 형태로 작성합니다.
파일 다운로드 구현 파일 업로드 로직을 반대로 구현하면 파일 다운로드 기능을 쉽게 구축할 수 있습니다. 서버의 특정 경로에 있는 파일을 읽어 HttpResponseMessage의 콘텐츠로 반환하면 됩니다.