반응형
.net 6 으로 API 프로젝트 작업을 진행하면서 Back End 작업중 POST 메서드에 대한 처리가 필요했다.
요구사항
1. POST 메서드로 기본적으로 csv, json 파일이 올수 있다.
2. 또는 파일의 내용을 body 에 직접 담아서 보낼수도 있다.
3. 응답 코드는 201로 응답한다.
2가지 방법으로 요청이 오기 때문에 Route를 2개로 따로 받아 처리하기로 하였다. (라우터 하나에 두가지 모두 받는 방법이 있는지는 잘 모르겠다.)
File 로 받기
Post 메소드의 파라미터를 IFormFile 로 한다.
[HttpPost]
public IActionResult Post(IFormFile file)
{
// 파일을 읽어서(csv, json 에따라서 파싱)
var fileContent = this.ReadFile(file);
//add service 작업
// 파일내용을 등록
// 응답코드 201 리턴
return CreatedAtAction(nameof(GetList), result);
}
스웨거로 확인한 결과 파일 csv 나 json 파일 입력에 대한 처리 후 정상적으로 201 호출을 응답한다.
Body 로 받기
json 으로만 받게 되면 입력 모델 class 를 만들어 처리하면 편하지만, mvc 나 core 버전이 바뀔때마다 body데이터를 받는게 조금씩 달라지는 경우가 있다.
Request.Body 데이터를 두가지 형식(cvs, json 문자열)으로 body 로 전달되어 string으로 데이터를 받아서 처리를 하게 되었다. NET 6 에서 [FromBody] string body 로 받으니 null 로 되어서 Formatter 추가 작업이 필요한것을 알게 되었음.
// Program.cs
builder.Services.AddControllers(mvcOptions =>
{
mvcOptions.InputFormatters.Add(new TextSingleValueFormatter());
});
// TextSingleValueFormatter.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Formatters;
namespace Employee.Test
{
public class TextSingleValueFormatter : InputFormatter
{
private const string TextPlain = "text/plain";
public TextSingleValueFormatter()
{
SupportedMediaTypes.Add(TextPlain);
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
{
try
{
using (var reader = new StreamReader(context.HttpContext.Request.Body))
{
string textSingleValue = await reader.ReadToEndAsync();
//Convert from string to target model type (this is the parameter type in the action method)
object model = Convert.ChangeType(textSingleValue, context.ModelType);
return InputFormatterResult.Success(model);
}
}
catch (Exception ex)
{
context.ModelState.TryAddModelError("BodyTextValue", $"{ex.Message} ModelType={context.ModelType}");
return InputFormatterResult.Failure();
}
}
protected override bool CanReadType(Type type)
{
//Put whatever types you want to handle.
return type == typeof(string) ||
type == typeof(int) ||
type == typeof(DateTime);
}
public override bool CanRead(InputFormatterContext context)
{
return context.HttpContext.Request.ContentType == TextPlain;
}
}
}
* TextSingleValueFormatter.cs 검색하다 발견한 소스인데 출처를 잊어버림
formatter 처리 후 정상적으로 body 데이터 수신
[HttpPost]
[Route("cvs")]
[Consumes("text/plain")]
public IActionResult Post([FromBody] string cvs)
{
// 데이터 파싱
// service 등록 처리
return Ok();
}
반응형