Получение значения Request.Headers

Очень просто, я уверен, но доводит меня до белого каления! Есть компонент, который я использую в своем веб-приложении, который идентифицирует себя во время веб-запроса, добавляя заголовок "XYZComponent=true" - проблема, с которой я столкнулся, заключается в том, как вы проверяете это в своем представлении?

Следующее не будет работать:

if (Request.Headers["XYZComponent"].Count() > 0)

Ни это:

if (Request.Headers.AllKeys.Where(k => k == "XYZComponent").Count() > 0)

Оба генерируют исключения, если переменная заголовка не была установлена. Любая помощь будет принята с благодарностью.


person Jimbo    schedule 20.08.2010    source источник
comment
Я не знаю, оборачивает ли MVC эту функциональность, но в самом HTTP заголовки имеют форму XYZComponent: true. Я просто удивляюсь, если вам удалось установить заголовок, например XYZComponent=true: (т.е. вся строка, которую вы цитируете, является именем и, следовательно, тем, что вам нужно проверить. Должно быть достаточно легко проверить, поскольку вы уже знаете, как выполнять итерацию через ключи...   -  person Chris    schedule 20.08.2010


Ответы (6)


if (Request.Headers["XYZComponent"].Count() > 0)

... будет пытаться подсчитать количество символов в возвращаемой строке, но если заголовок не существует, он вернет NULL, поэтому он генерирует исключение. Ваш второй пример эффективно делает то же самое, он будет искать в коллекции заголовков и возвращать NULL, если он не существует, и затем вы пытаетесь подсчитать количество символов:

Используйте это вместо этого:

if(Request.Headers["XYZComponent"] != null)

Или, если вы хотите обрабатывать пустые или пустые строки как не установленные, используйте:

if((Request.Headers["XYZComponent"] ?? "").Trim().Length > 0)

Оператор Null Coalesce ?? вернет пустую строку, если заголовок имеет значение null, что остановит создание исключения NullReferenceException.

Вариант вашей второй попытки также будет работать:

if (Request.Headers.AllKeys.Any(k => string.Equals(k, "XYZComponent")))

Изменить. Извините, я не понял, что вы явно проверяли значение true:

bool isSet = Boolean.TryParse(Request.Headers["XYZComponent"], out isSet) && isSet;

Возвращает false, если значение заголовка равно false, или если заголовок не был установлен, или если заголовок имеет любое другое значение, кроме true или false. Вернет true, если значение заголовка является строкой «true»

person Sunday Ironfoot    schedule 20.08.2010

Заголовок существует:

if (Request.Headers["XYZComponent"] != null)

или еще лучше:

string xyzHeader = Request.Headers["XYZComponent"];
bool isXYZ;

if (bool.TryParse(xyzHeader, out isXYZ) && isXYZ)

который проверит, установлено ли оно в true. Это должно быть надежным, потому что оно не заботится о начальных/конечных пробелах и нечувствительно к регистру (bool.TryParse работает с null)

Дополнение: вы можете сделать это более простым с помощью этого метода расширения, который возвращает логическое значение, допускающее значение NULL. Он должен работать как с недопустимым вводом, так и с нулевым значением.

public static bool? ToBoolean(this string s)
{
    bool result;

    if (bool.TryParse(s, out result))
        return result;
    else
        return null;
}

Использование (поскольку это метод расширения, а не метод экземпляра, это не вызовет исключение для null — хотя это может сбивать с толку):

if (Request.Headers["XYZComponent"].ToBoolean() == true)
person Lasse Espeholt    schedule 20.08.2010

Во-первых, вы не делаете этого в своем представлении. Вы делаете это в контроллере и возвращаете модель представления в представление, чтобы представление не заботилось о пользовательских заголовках HTTP, а просто отображало данные в модели представления:

public ActionResult Index()
{
    var xyzComponent = Request.Headers["xyzComponent"];
    var model = new MyModel 
    {
        IsCustomHeaderSet = (xyzComponent != null)
    }
    return View(model);
}
person Darin Dimitrov    schedule 20.08.2010

Следующий код должен позволить вам проверить наличие нужного заголовка в Request.Headers:

if (Request.Headers.AllKeys.Contains("XYZComponent"))
{
    // Can now check if the value is true:
    var value = Convert.ToBoolean(Request.Headers["XYZComponent"]);
}
person Rob    schedule 20.08.2010

В ядре dotnet Request.Headers["X-MyCustomHeader"] возвращает StringValues, которое не будет нулевым. Вы можете проверить количество, чтобы убедиться, что он нашел ваш заголовок следующим образом:

var myHeaderValue = Request.Headers["X-MyCustomHeader"];
if(myHeaderValue.Count == 0) return Unauthorized();
string myHeader = myHeaderValue.ToString(); //For illustration purposes.
person Tony    schedule 30.01.2020

person    schedule
comment
Это сравнение нечувствительно к регистру, так как это может быть XYZComponent: True или XYZComponent: TRUE. Попробуйте (Request.Headers[XYZComponent] ?? ).Equals(true, StringComparison.InvariantCultureIgnoreCase) - person Sunday Ironfoot; 20.08.2010
comment
@Sunday: поскольку протокол HTTP всегда использует английский язык, вы должны использовать StringComparison.OrdinalIgnoreCase, который является необработанным, байт за байтом, сравнение. Подробнее см. в ветке lists.ximian.com/pipermail/mono. -list/2010-July/045508.html - person abatishchev; 20.08.2010