Доступ к значениям QueryString, Route Parameter в .net core webapi - PullRequest
0 голосов
/ 10 мая 2018

У меня уникальная ситуация, когда мне нужно получить DepartmentId из [FromRoute] или [FromQuery] или [FromBody]. Это странно, так как я не могу разорвать свои публичные контракты API и не могу ничего с этим поделать. Также я не могу изменить бизнес-контракты, которые вызываются из контроллера, так что я не могу передать DepartmentId по конвейеру.

Я вижу, что могу ввести IHttpContextAccessor и получить IHttpContextAccessor.HttpContext. Я смог получить DepartmentId для [FromQuery], как показано ниже:

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);
} 

Я не знаю, как мне получить DepartmentId от сложного объекта [FromBody]. Но я знаю, что все объекты запроса, используемые в [HttpPost], наследуются от класса Department, который имеет DepartmentId.

Любая помощь приветствуется ....

1 Ответ

0 голосов
/ 12 мая 2018

Используя промежуточное ПО, я бы сделал что-то вроде этого:

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 таким же образом, как получить DepartmentId от Body.Имейте в виду - вы можете передавать свою инфраструктуру бизнес-уровню - если вы используете средство доступа в своих бизнес-классах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...