programing

ASP.NET Core Web API에서 파일 및 기타 양식 데이터 수신(경계 기반 요청 구문 분석)

i4 2023. 6. 30. 22:06
반응형

ASP.NET Core Web API에서 파일 및 기타 양식 데이터 수신(경계 기반 요청 구문 분석)

수신해야 하는 작업 방법에 대한 매개 변수를 어떻게 구성하시겠습니까?file하나text요청의 가치?

해봤습니다.

public string Post([FromBody]string name, [FromBody]IFormFile imageFile)

그리고 우체부한테 쳐보았지만 그것은 나를 줍니다.500 Internal Server Error또한 중단점을 둔 액션 메소드 내의 첫 번째 문에 도달하지 않기 때문에 디버깅할 수 없습니다.

어떻게 경계 기반 요청을 구문 분석하고 파일 및 기타 텍스트 필드를 추출할 수 있는지 아십니까?ASP.NET Core는 처음입니다.

저는 비슷한 문제를 가지고 있었고, 사용하여 문제를 해결했습니다.[FromForm]속성 및FileUploadModelView다음과 같은 기능을 사용합니다.

[HttpPost]
[Route("upload")]
public async Task<IActionResult> Upload([FromForm] FileUploadViewModel model, [FromForm] string member_code)
{
    var file = model.File;
    
    // ...
}

이는 동일한 문제에 직면한 모든 사용자를 위한 빠른 해결책입니다.

Ajax를 사용하여 다음 양식Data를 전송합니다.

let formData: FormData;
formData = new FormData();
formData.append('imageFile', imageFile);
formData.append('name', name);

그러면 다음과 같이 컨트롤러에 수신됩니다.

public string Post(IFormCollection data, IFormFile imageFile)

그러면 일반적으로 하는 것처럼 데이터에 액세스할 수 있습니다.

var name = data["name"];

HomeController.cs 에서

using Microsoft.AspNetCore.Hosting;
.......
private IHostingEnvironment _environment;

public HomeController(IHostingEnvironment environment)
{
    _environment = environment;
}

[HttpPost]
[ValidateAntiForgeryToken]        
public IActionResult Index(IFormCollection formdata)
{
 var files = HttpContext.Request.Form.Files;
 foreach (var file in files)
 {
     var uploads = Path.Combine(_environment.WebRootPath, "Images");
     if (file.Length > 0)
     {
        string FileName = Guid.NewGuid(); // Give file name
        using (var fileStream = new FileStream(Path.Combine(uploads, FileName), FileMode.Create))
        {
            file.CopyToAsync(fileStream);
        }       
     }
  }
}

보기 - Index.cshtml

<form method="post" enctype="multipart/form-data" >
 .....
</form>

이 코드를 사용해 보십시오.

감사합니다!!

파일과 텍스트 값으로 구성된 Mailgun의 응답을 구문 분석하기 위해 다음 코드를 사용합니다.

"대시화"는 "메시지"와 같은 속성 이름입니다.헤더"는 "메시지 헤더"로 바뀝니다. 사용 사례에 맞는 논리를 사용해야 합니다.

컨트롤러:

using System;
using Microsoft.AspNetCore.Mvc;
using NuGet.Protocol.Core.v3;

namespace Potato
{
    [Route("api/[controller]")]
    public class MailgunController : Controller
    {
        [HttpPost]
        public IActionResult Post()
        {
            MailgunEmail email = new MailgunEmail(Request);

            return Ok(email.ToJson());
        }
    }
}

모델:

using System;
using System.Reflection;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;

namespace Potato
{
    public class MailgunEmail
    {
        public IEnumerable<IFormFile> Attachments { get; set; }

        public string Recipient { get; set; }
        public string Sender { get; set; }
        public string From { get; set; }
        public string Subject { get; set; }
        public string BodyPlain { get; set; }
        public string StrippedText { get; set; }
        public string StrippedSignature { get; set; }
        public string BodyHtml { get; set; }
        public string StrippedHtml { get; set; }
        public int? AttachmentCount { get; set; }
        public int Timestamp { get; set; }
        public string Token { get; set; }
        public string Signature { get; set; }
        public string MessageHeaders { get; set; }
        public string ContentIdMap { get; set; }

        public MailgunEmail(HttpRequest request)
        {
            var form = request.Form;

            Attachments = new List<IFormFile>(form.Files);

            foreach (var prop in typeof(MailgunEmail).GetProperties()) {
                string propName = Dashify(prop.Name);
                var curVal = form[propName];
                if (curVal.Count > 0) {
                    prop.SetValue(this, To(curVal[0], prop.PropertyType), null);
                }
            }
        }

        private object To(IConvertible obj, Type t)
        {
            Type u = Nullable.GetUnderlyingType(t);

            if (u != null) {
                return (obj == null) ? GetDefaultValue(t) : Convert.ChangeType(obj, u);
            } else {
                return Convert.ChangeType(obj, t);
            }
        }

        private object GetDefaultValue(Type t)
        {
            if (t.GetTypeInfo().IsValueType) {
                return Activator.CreateInstance(t);
            }
            return null;
        }

        private string Dashify(string source)
        {
            string result = "";
            var chars = source.ToCharArray();
            for (int i = 0; i < chars.Length; ++i) {
                var c = chars[i];
                if (i > 0 && char.IsUpper(c)) {
                    result += '-';
                }
                result += char.ToLower(c);
            }
            return result;
        }
    }
}

페이지는 저에게 많은 도움이 되었습니다. https://learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads

그래서 이제 내 코드에는 다음과 같은 컨트롤러 방법이 있습니다.

 public async Task<IActionResult> UploadFiles(UploadedFile ups)

그리고 모델을 위한 클래스.

public class UploadedFile
    {
        public string UploadName { get; set; }
        public List<IFormFile> Files { get; set; }
    }

그리고 같은 형태.

<form method="post" enctype="multipart/form-data" asp-controller="Files" asp-action="UploadFiles">

나는 텍스트 값보다 복잡한 객체를 보내고 싶었습니다.그리고 아래와 같이 할 수 있습니다.

양식 데이터 전송 중:

let data = new FormData();
data.append("file", file, file.name);
data.append("someData", JSON.stringify(someData));

컨트롤러의 양식 데이터 사용:

public async Task<IActionResult> OnPostUploadAsync( IFormCollection data )
{
  var files = data.Files;
  if (data.TryGetValue("someData", out var someData))
  {
    //use files & some data (json string)
  }
}

멀티파트를 통해 샘플 코드로 여러 이미지를 얻을 수 있습니다.

시작 클래스에서 서비스 메서드를 구성하려면 먼저 IHTTPContextAccessor를 주입합니다.그런 다음 컨트롤러에서 생성자 주입을 사용하여 호출:

        private readonly IHttpContextAccessor _httpContextAccessor;

          public FileController(IHttpContextAccessor httpContextAccessor)
                {
                    _httpContextAccessor = httpContextAccessor;           
                }

액션 메서드에 응답이 있을 수 있음 또는 없을 수 있습니다.

        public async Task<object> UploadImage()
            {
                var fileBytes = new List<byte[]>();
                var files = 
                   _httpContextAccessor.HttpContext.Request.Form.Files;

            foreach (var file in files)
            {
                if (file.Length > 0)
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        await file.CopyToAsync(memoryStream);
                        fileBytes.Add(memoryStream.ToArray());
                    }
                }
            }
   // TODO: Write Code For Save Or Send Result To Another Services For Save
            }
  1. 일반적인 컨트롤러(.NET 5\6)의 코드는 다음과 같습니다.
[ApiController]
[Route("[controller]")]
public class UploadController : Controller
{
    [HttpPost]
    [Route("CreateUser")]
    public async Task<IActionResult> CreateUser([FromForm]ApplicationUserCreationDto userCreationDto)
    {
        return Json(new
        {
            user = userCreationDto.UserName,
            fileName = userCreationDto.Photo.FileName
        });
    }
}

public class ApplicationUserCreationDto
{
    [Required]
    public string UserName { get; set; }

    public IFormFile Photo { get; set; }
}
  1. 최소 API 사용

당신은 파일과 텍스트를 적절한 JSON 형식으로 전송하고 있는 것 같습니다.

파일 및 텍스트를 유형 문자열의 속성으로 포함하는 새 클래스를 만들어야 합니다.[FromBody] 특성을 사용하여 메서드 인수에 새 클래스를 추가하면 필요에 따라 이미지 문자열을 구문 분석할 수 있습니다.

다른 방법은 다음을 통해 전체 요청 콘텐츠에 액세스하는 것입니다.

await Request.Content.ReadAsStringAsync();

그러면 전체 내용을 구문 분석해야 합니다.

언급URL : https://stackoverflow.com/questions/40629947/receive-file-and-other-form-data-together-in-asp-net-core-web-api-boundary-base

반응형