我有一个独特的情况,我需要从[FromRoute]
或[FromQuery]
或[FromBody]
获取DepartmentId。这很奇怪,因为我无法打破我的公共行动合同,也无法做很多事情。此外,我无法改变从控制器内部调用的业务合同,因此我无法将DepartmentId传递给管道。
我看到我可以注入IHttpContextAccessor
并获取IHttpContextAccessor.HttpContext
。我能够获得[FromQuery]
的DepartmentId,如下所示:
request.QueryString.Value.Replace("?", "")
.Split("&")
.FirstOrDefault(x => x.Contains("departmentId"))
?.Split("=")[1];
我得到[FromRoute]
参数如下;
var departmentId = 0;
var match = Regex.Match(request.Path, "Department/\\d+");
if (match.Success && match.Groups.Any())
{
int.TryParse(match.Groups[0].Value.Replace("Department/", ""), out departmentId);
}
我不知道如何从[FromBody]
复杂对象中获取DepartmentId。但我知道[HttpPost]
中使用的所有请求对象都继承自Department
的{{1}}类。
感谢任何帮助......
答案 0 :(得分:1)
使用中间件我会做这样的事情:
public class EstablishDepartmentMiddleware
{
private RequestDelegate _next;
public EstablishDepartmentMiddleware(RequestDelegate next)
{
this._next = next;
}
public async Task InvokeAsync(HttpContext context, IDepartmentContext departmentContext)
{
await TryGetDepartmentFromBody(context, departmentContext);
// TryGetFromQuery
// TryGetFromRoute
await _next(context);
}
private static async Task TryGetDepartmentFromBody(HttpContext context, IDepartmentContext departmentContext)
{
using (var sr = new StreamReader(context.Request.Body))
{
var bodyText = await sr.ReadToEndAsync();
var department = JsonConvert.DeserializeObject<Department>(bodyText);
if (department != null)
{
departmentContext.DepartmentId = department.DepartmentId;
}
}
}
}
以下是其他课程:
public interface IDepartmentContext
{
int DepartmentId { get; set; }
}
public class DepartmentContext : IDepartmentContext
{
public int DepartmentId { get; set; }
}
public class Department
{
public int DepartmentId { get; set; }
}
这是启动课程的内容:
app.UseMiddleware<EstablishDepartmentMiddleware>();
您也可以使用动作过滤器执行类似操作 - 中间件可以处理所有到达的请求。
显然你可以使用上面的代码并使用IHttpContextAccessor以同样的方式从Body获取DepartmentId。请记住 - 如果您在业务类中使用访问者,则可能会将基础结构泄露到业务层。