How to match 1 or 0 in the ASP.Net MVC route segment in the input parameter of the Boolean action method

We have several PHP and Javascript applications that invoke some ASP.NET MVC endpoints. Say we have this endpoint:

public ActionResult DoSomething(bool flag) { } 

I want it to match the value for the flag, whether I pass the integer 1 or 0 or pass the string "true" or "false". What part of the framework needs to be implemented to fit this?

+6
source share
3 answers

The best way to do this is to use a custom value provider. While you can do this using a fully customizable middleware, this is overkill based on your requirements and it is much easier to implement your own cost provider.

For some recommendations on when you use a custom mediator and when to use a custom value provider, see here and here .

You can simply create a custom value provider to handle the route values ​​with the flag key and process the int for the bool conversion in the value provider. The code for this looks something like this:

 public class IntToBoolValueProvider : IValueProvider { public IntToBoolValueProvider(ControllerContext context) { if (context == null) throw new ArgumentNullException("context"); this._context = context; } public bool ContainsPrefix(string prefix) { return prefix.ToLower().IndexOf("flag") > -1; } public ValueProviderResult GetValue(string key) { if (ContainsPrefix(key)) { int value = 0; int.TryParse(_context.RouteData.Values[key].ToString(), out value); bool result = value > 0; return new ValueProviderResult(result, result.ToString(), CultureInfo.InvariantCulture); } else { return null; } } ControllerContext _context; } public class IntToBoolValueProviderFactory : ValueProviderFactory { public override IValueProvider GetValueProvider(ControllerContext controllerContext) { return new IntToBoolValueProvider(controllerContext); } } 

In the value provider, you implement the ContainsPrefix method to return true for the route keys of interest to you, in this case the key flag. In the GetValue flag, you convert the record value of the flag route data to int, and then to boolean, depending on whether int is greater than zero. For all other route data keys that are not β€œflags,” you simply return null, which tells the MVC infrastructure to ignore this ValueProvider and move on to other value providers.

To link this, you need to implement a subclass of ValueProviderFactory, which creates a custom provider, IntToBoolValueProvider. In addition, you need to register this factory using the MVC environment. You do this in global.asax using the static ValueProviderFactories class:

 protected void Application_Start() { ValueProviderFactories.Factories.Insert(0, new IntToBoolValueProviderFactory()); } 

If you have a route configured as follows:

 routes.MapRoute("", "{controller}/foo/{flag}", new { action = "Foo" }); 

this route will direct requests to

 http://localhost:60286/Home/Foo/{flag} 

to the method of action

  public ActionResult Foo(bool flag) { //Implement action method return View("Index"); } 

When the {flag} segment is greater than 0, the input parameter of the bool flag will be true, and when it is zero, the flag parameter will be false.

More information on MVC custom value providers can be found here .

+7
source

What part of the environment do I need to implement to fit this?

Custom model binding .

0
source

Can you use a custom mediator as shown in this SO question ASP.NET MVC controller actions with custom settings?

Now, if you want to do this globally, so you did not need to set an attribute for each bool, which could get 0/1 instead of true / false, then you can expand the standard connecting device to understand 0 or 1 as false or true, redefining default binder as shown in this SO question Change the default model binding in asp.net MVC

Some combination of the two should provide you with what you want.

0
source

All Articles