如何解决如何处理控制器中的扩展方法?
我真的没有得到这个问题的正确标题。如有误导请更正。
我有一个 WebApi 控制器,其中有多个验证检查。控制器示例代码
public async Task<IActionResult> UploadFile(IFormFile file)
{
try
{
return file.IsValid();
//some more Functionality
}
}
public static IActionResult PrepareResult(this ControllerBase controller,IFormFile file)
{
if (file== null)
{
return controller.Badrequest("No data sent");
}
return controller.Ok();
}
问题:- 在当前场景中,如果文件为 Null,那么扩展方法将返回 Badrequest()
并且同样将返回给客户端。但是如果文件不为空,那么它将返回 Ok()
并且同样将返回给 Clint,因为我有更多的代码要执行(ie//一些更多的功能)。
我不想返回 controller.Ok()
,以便在积极的情况下我可以继续使用剩余的代码。
注意:- 我不想分配给任何变量并检查 If 条件。为了避免 if 条件只有我使用扩展方法。
解决方法
不确定为什么您不想分配变量并避免 if 条件,因为这是最有效的方法。您可以使用异常处理,但这会带来性能成本。
public static void EnsureFileIsValid(this IFormFile file)
{
if(file == null) { throw new InvalidOperationException("No data sent"); }
}
public async Task<IActionResult> UploadFile(IFormFile file)
{
try
{
file.EnsureFileIsValid();
return Ok();
}
catch(InvalidOperationException ex)
{
return BadRequest(ex.Message);
}
}
,
您可以将操作传递给您的方法,例如:
public static IActionResult PrepareResult(this ControllerBase controller,IFormFile file,Action<IFormFile> work)
{
if (file == null)
{
return controller.Badrequest("No data sent");
}
work(file);
return controller.Ok();
}
在你的行动中,用途是:
public class FilesController : ControllerBase
{
[HttpPost]
public IActionResult UploadFile([FromServices]IFileService fileService,IFormFile file)
{
return Ok(PrepareResult(file,fileService.Upload));
}
}
但也许你可以考虑使用验证。
在验证步骤中,您使用 RequiredAttribute 强制参数不为空。
ApiControllerAttribute 在调用操作之前强制执行验证。如果验证失败,则 ASP.NET Core 直接返回 BadRequest 并且不调用操作。
在本例中,如果参数文件为空,则不会调用该操作并返回 BadRequest :
[ApiController]
public class FilesController : ControllerBase
{
[HttpPost]
public IActionResult UploadFile([Required]IFormFile file)
{
//Do something
return Ok();
}
[HttpPut]
public IActionResult UploadFileBis([Required] IFormFile file)
{
//Do something
return Ok();
}
}
PS : 您可以在程序集级别使用 [ApiControllerAttribute],它将对程序集中的所有控制器启用:
[assembly: ApiController]
,
如果你想在同一个下层类中验证条件并定义错误响应,这里有一个解决方案。
首先,让我们创建一个自定义异常来保存要返回的 http 状态代码和消息:
// serialization implementation redacted
public class InfrastructureException : Exception
{
public HttpStatusCode HttpStatusCode { get; }
public InfrastructureException(HttpStatusCode code,string message) : base(message)
{
HttpStatusCode = code;
}
}
我们需要一个类来处理响应序列化:
public class ExceptionResponse
{
public int StatusCode { get; set; }
public string Message { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
然后创建一个处理异常的中间件:
public class InfrastructureExceptionMiddleware
{
private readonly RequestDelegate next;
public InfrastructureExceptionMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task InvokeAsync(HttpContext httpContext,IHostEnvironment hostEnvironment)
{
try
{
await this.next(httpContext);
}
catch (Exception ex)
{
await HandleExceptionAsync(httpContext,ex);
}
}
private Task HandleExceptionAsync(HttpContext context,Exception exception)
{
context.Response.ContentType = "application/json";
ExceptionResponse response = exception is InfrastructureException infrastructureException
? new ExceptionResponse()
{
StatusCode = (int)infrastructureException.HttpStatusCode,Message = infrastructureException.Message
}
: new ExceptionResponse()
{
StatusCode = (int)HttpStatusCode.InternalServerError,Message = ReasonPhrases.GetReasonPhrase(context.Response.StatusCode)
};
return context.Response.WriteAsync(response.ToString());
}
}
现在,我们需要注册我们的中间件:
public class Startup
{
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
// redacted
app.UseMiddleware<InfrastructureExceptionMiddleware>();
// redacted
}
}
在控制器中,我们将验证委托给扩展方法:
public async Task<IActionResult> UploadFile(IFormFile file)
{
file.IsValid();
// now you can consider file is valid
}
最后,在扩展方法中,我们抛出异常:
public static void IsValid(this IFormFile file)
{
if(file == null)
{
throw new InfrastructureException(HttpStatusCode.BadRequest,"No data sent");
}
if(...) // condition for Http NotFound
{
throw new InfrastructureException(HttpStatusCode.NotFound,"Data not found");
}
// other validation conditions
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。