asp.net 如何在.net中的Post端点中接受File和JSON数据

r1zk6ea1  于 4个月前  发布在  .NET
关注(0)|答案(1)|浏览(49)

我正在使用Aradalis Endpoints包。对于Post端点,我想接受一个文件和对象作为JSON,并将其转换为JSON。
下面是我的端点代码

namespace App.API.Endpoints.ExecuteQueryTasks
{
    public sealed class CreateExecutionResultEndpoint : EndpointBaseAsync
        .WithRequest<CreateQueryResultRequest>
        .WithActionResult<ExecutionResult>
    {
        public const string RouteName = "ExecuteQueryTasks.StoreResult";

        private readonly ISender _sender;
        private readonly ILogger<CreateExecutionResultEndpoint> _logger;

        public CreateExecutionResultEndpoint(ISender sender, ILogger<CreateExecutionResultEndpoint> logger)
        {
            _sender = sender ?? throw new ArgumentNullException(nameof(sender));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        [HttpPost("/tasks/result")]
        public override async Task<ActionResult<ExecutionResult>> HandleAsync([FromForm] CreateQueryResultRequest request, CancellationToken cancellationToken = default)
        {
            if (!ModelState.IsValid)
            {
                foreach (var state in ModelState)
                {
                    foreach (var error in state.Value.Errors)
                    {
                        _logger.LogError("Validation error: {ErrorMessage}", error.ErrorMessage);
                    }
                }
                return BadRequest(ModelState);
            }

            try
            {
                _logger.LogInformation("Handling CreateExecutionResult request");

                var resultData = JsonConvert.DeserializeObject<ExecutionResult>(request.Result);
                ...
                return Created(getByIdUrl, result.Value);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "An error occurred while handling CreateExecutionResult request");

                return StatusCode(500, "An unexpected error occurred");
            }
        }
    }
}

public class CreateQueryResultRequest
{
    public string Result { get; set; }

    public IFormFile? File { get; set; }
}

字符串
这工作,但当我尝试接受Result作为类型ExecutionResult,并给予它一个属性[FromBody]File的属性[FromForm]。然后我给我的CreateExecutionRequest[FromBody]属性。这给我415不支持的类型响应时,发送数据到后端点。
以下是我的发送代码:

using var httpClient = _httpClientFactory.CreateClient("AppClient");
            try
            {
                using var multipartContent = new MultipartFormDataContent();

                 if (data is not null) 
                {
                    var memoryStream = new MemoryStream();
                    await using var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8);
                    await using JsonTextWriter jsonWriter = new JsonTextWriter(streamWriter);

                    JsonSerializer serializer = new JsonSerializer();
                    serializer.Serialize(jsonWriter, data);
                    await jsonWriter.FlushAsync();

                    memoryStream.Position = 0;

                    var streamContent = new StreamContent(memoryStream);

                    streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                    multipartContent.Add(streamContent, "File", "data.json");
                }
                

                var metadataJson = JsonConvert.SerializeObject(result);
                multipartContent.Add(new StringContent(metadataJson), "Result");

                HttpResponseMessage response = await httpClient.PostAsync("/tasks/result", multipartContent);

                var res = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    return Result.Error(new Error("error", "Error occured while sending data to QueryHub"));
                }

                return Result.Success();
            }
            catch (Exception ex)
            {
                return Result.Error(new Error("error", ex.Message));
            }


这是我试图将我的结果具体化到的类。

public sealed class ExecutionResult
    {
        public ExecutionResult();

        public Guid ResultId { get; set; }
        public Guid TaskId { get; set; }
        public TimeSpan TimeElapsed { get; set; }
        public ExecutionStatusEnum Status { get; set; }
        public IEnumerable<Error> Errors { get; set; }
        public string FileUrl { get; set; }
    }


这里ExecutionStatusEnumArdalis SmartEnum

smdncfj3

smdncfj31#

在一个操作中不能同时具有FromFormFromBody属性。
参考官方文档https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-8.0,[FromForm]从发布的表单字段中获取值,[FromBody]从请求体中获取值。在一个http请求中,它不能一次将数据绑定到两个来源的参数。这就是为什么你得到415。关于这个ASP.NET Core FromForm And FromBody Same Action也有一些讨论。
您可以使用multipart/form-data[FromForm]发送表单数据中的文件和字符串。

相关问题