我正在使用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; }
}
型
这里ExecutionStatusEnum
是Ardalis SmartEnum
1条答案
按热度按时间smdncfj31#
在一个操作中不能同时具有
FromForm
和FromBody
属性。参考官方文档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]
发送表单数据中的文件和字符串。