访问.net核心webapi中的QueryString,Route参数值

时间:2018-05-10 18:51:26

标签: c# asp.net-core-2.0 asp.net-core-webapi

我有一个独特的情况,我需要从[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}}类。

感谢任何帮助......

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。请记住 - 如果您在业务类中使用访问者,则可能会将基础结构泄露到业务层。