ASP.NET Web API 셀프 호스트 구현 및 파일 전송 기능 구축

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&para2=value2 형태로 작성합니다.

파일 다운로드 구현 파일 업로드 로직을 반대로 구현하면 파일 다운로드 기능을 쉽게 구축할 수 있습니다. 서버의 특정 경로에 있는 파일을 읽어 HttpResponseMessage의 콘텐츠로 반환하면 됩니다.

8월 13일 22:42에 게시됨