После борьбы с этой проблемой в течение почти 2 дней я решил прийти сюда и задать этот вопрос - я сделаю все возможное, чтобы быть максимально ясным.
Прежде всего, то, что я пытаюсь сделать, довольно просто: реализовать собственный IValueProvider, который расшифровывает параметры действия внутри контроллера ASP.NET MVC — эта часть выполнена и работает отлично; моя проблема начинается в тот момент, когда у меня есть список среди параметров действия, потому что я не могу точно указать значения этого списка из контекста запроса.
Давайте сделаем это шаг за шагом.
Во-первых, у меня есть атрибут, который украшает нужные действия:
public class EncryptedQueryStringValuesAttribute : FilterAttribute, IAuthorizationFilter
{
/// <summary>
/// Called when authorization is required.
/// </summary>
/// <param name="filterContext">The filter context.</param>
public void OnAuthorization(AuthorizationContext filterContext)
{
filterContext.Controller.ValueProvider = new EncryptedQueryStringValuesProvider(
filterContext.RequestContext, filterContext.ActionDescriptor);
}
}
Затем у меня есть конструктор поставщика значений, в котором я инициализирую то, что мне нужно:
public EncryptedQueryStringValuesProvider(RequestContext requestContext, ActionDescriptor actionDescriptor)
{
this.requestContext = requestContext;
this.actionDescriptor = actionDescriptor;
this.prefixContainer =
new Lazy<PrefixContainer>(
() => new PrefixContainer(this.requestContext.HttpContext.Request.Params.AllKeys), true);
}
В качестве примечания, prefixContainer действительно работает как шарм - если я проверяю, есть ли префикс в контейнере, он работает отлично независимо от типа префикса (это означает, что не имеет значения, является ли параметр коллекцией или простой параметр).
Проверка наличия параметра внутри провайдера значений выполняется так:
public bool ContainsPrefix(string prefix)
{
return this.prefixContainer.Value.ContainsPrefix(prefix);
}
Как я уже сказал, это дает мне правильные значения.
Теперь самое неприятное — метод GetValue
:
public ValueProviderResult GetValue(string key)
{
string[] rawValue = this.requestContext.HttpContext.Request.Params.GetValues(key);
string attemptedValue = this.requestContext.HttpContext.Request.Params[key];
return new ValueProviderResult(rawValue, attemptedValue, CultureInfo.CurrentCulture);
}
rawValue
, извлеченный прямо сейчас, имеет значение null и логично быть нулевым, потому что в моем запросе нет ключа с таким именем - все, что у меня есть, это просто коллекция, подобная этой:
[25]: "SupplierInvoices[x].PaymentToInvoiceExchangeRate"
[26]: "SupplierInvoices[x].AmountToPayOnGivenInvoice"
[27]: "SupplierInvoices[x].OpenInvoiceId"
[28]: "SupplierInvoices[x].OpenInvoiceTimestamp"
С другой стороны, я прекрасно понимаю, что я должен использовать конструкцию this.prefixContainer.Value.GetKeysFromPrefix(prefix);
, чтобы получить все ключи, которые есть в моем запросе, и на его основе как-то соединить эти ключи и отдать их обратно в ValueProviderResult, НО НЕ ИМЕЮ ИДЕИ КАК! :-)
Пожалуйста, кто-нибудь может объяснить, как эти значения могут быть объединены, чтобы быть переданными обратно в ValueProviderResult для правильной интерпретации?
СПАСИБО!