I've created some implementations of IValueProvider
for my Web API project and I'm confused about the purpose of the ContainsPrefix
method on the interface.
The ContainsPrefix
method has this summary comment:
Determines whether the collection contains the specified prefix.
However the summary of the method is abstract and doesn't explain what prefix
will be provided to the method or what function the method serves. Is prefix
going to be the action parameter name? The action name? The controller name? The first three letters of either of these? Does this method exist to automatically figure out which action parameter the IValueProvider
should provide a value for?
I never see the ContainsPrefix
method get called by the Web API framework in my IValueProvider
implementations although I do see references in Web API's CollectionModelBinder
, MutableObjectModelBinder
, SimpleModelBinderProvider
, and CompositeValueProvider
. For instance, the following implementation has caused me no issues in my testing:
MyValueProvider:
public class MyValueProvider : IValueProvider
{
public bool ContainsPrefix(string prefix)
{
throw new NotYetImplementedException();
}
public ValueProviderResult GetValue(string key)
{
return new ValueProviderResult("hello", "hello", CultureInfo.InvariantCulture);
}
}
TestController:
public class TestController : ApiController
{
public string Get([ModelBinder]string input)
{
return input;
}
}
GET
requests to my TestController
will return hello, so I know GetValue
is being called from MyValueProvider
, but no exception is thrown so I know that ContainsPrefix
isn't called.
ContainsPrefix
to be called by the Web API framework?prefix
will be provided to this method?It's strange that you were able to create value provider without knowing what this (quite important) method does. First what value providers do? In short they provide values for parameters you specify in your actions. For example:
public ActionResult Index(string test) {
}
Here we have action with parameter named "test". Where to get value for it? From value providers. There are several built-in providers, like query string or form data providers. Those providers are invoked one by one, until some of the providers will be able to provide a value. For example, if there is query string parameter "test" - query string value provider will notice that and return a value, so other providers will not be invoked. Next, if post data contains parameter "test" - it will be used, and so on.
So this parameter name ("test" in this case), is what ContainsPrefix
is called with. Take for example query string value provider. If query string contains no "test" - ContainsPrefix for this provider will return "false" and next value provider will be invoked. If it returns true - GetValue
should return value and no other providers will be invoked.
If you want to provide a value for parameter from say cookie, in your ContainsPrefix
method you will check if there is a cookie with given name. Note that it will be called only if all default value providers will fail to provide a value.
So, TLDR: prefix represents parameter name to provide value for.
Here is parts of Pride Parrot How to create a custom session value provider article
The
ContainsPrefix
method is called by the model binder to determine whether the value provider can resolve the data for a given prefix.
If you have SessionValueProvider
public class SessionValueProvider: IValueProvider
{
public bool ContainsPrefix(string prefix)
{
return HttpContext.Current.Session[prefix] != null;
}
public ValueProviderResult GetValue(string key)
{
if(HttpContext.Current.Session[key] == null)
return null;
return new ValueProviderResult(HttpContext.Current.Session[key],
HttpContext.Current.Session[key].ToString(), CultureInfo.CurrentCulture);
}
}
public class UserModel
{
public string AccountNo { get; set; }
...
}
public ViewResult SomeAction(UserModel userModel, ...)
{
...
}
At the time of model binding the DefaultModelBinder checks with the value providers could they return value for the parameter AccountNo by calling the ContainsPrefix method. If none of the value providers registered eariler could return the value our SessionValueProvider checks with session whether such a parameter is stored and if yes it return the value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With