我们有一些PHP和Javascript应用程序可以调用一些ASP。NET MVC端点。假设我们有一个端点:
public ActionResult DoSomething(bool flag)
{
}
我希望它与flag的值匹配,无论我是传递1或0的整数,还是传递"true"或"false"的字符串。为了与之匹配,我需要实现框架的哪一部分?
实现这一点的最佳方法是使用自定义值提供程序。虽然您可以使用一个完整的自定义模型绑定器来实现这一点,但根据您的需求,这是过度的,而且简单地实现一个自定义值提供程序要容易得多。
有关何时使用自定义模型绑定器以及何时使用自定义值提供程序的一些指导,请参阅此处和此处。
您只需创建一个自定义值提供程序来处理键为"flag"的路由值,并在值提供程序中处理int到bool的转换。这样做的代码看起来像这样:
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);
}
}
在值提供程序中,您可以实现ContainsPrefix方法,为您感兴趣的路由值键返回true,在本例中为键"flag"。在GetValue标志中,将"flag"路由数据项的值转换为int,然后转换为布尔值,具体取决于int是否大于零。对于所有其他不是"flag"的路由数据键,只需返回null,这告诉MVC框架忽略此ValueProvider并转移到其他值提供程序。
要实现这一点,您需要实现ValueProviderFactory的一个子类,该子类创建自定义IntToBoolValueProvider提供程序。此外,您需要使用MVC框架注册此工厂。您可以在global.asax中使用静态ValueProviderFactories类来完成此操作:
protected void Application_Start()
{
ValueProviderFactories.Factories.Insert(0, new IntToBoolValueProviderFactory());
}
如果你有一个路线设置如下:
routes.MapRoute("", "{controller}/foo/{flag}", new { action = "Foo" });
这条路线将把请求导向
http://localhost:60286/Home/Foo/{flag}
行动方法
public ActionResult Foo(bool flag)
{
//Implement action method
return View("Index");
}
当{flag}段大于0时,bool flag输入参数将为true,当为零时,flag参数将为false。
有关MVC自定义值提供程序的更多信息,请访问此处。
为了与之匹配,我需要实现框架的哪一部分?
自定义模型活页夹。
您可以使用自定义模型绑定器,如本SO问题ASP中所述。NET MVC控制器操作与自定义参数转换?
现在,如果你想全局地这样做,这样你就不必在每个可能得到0/1而不是true/false的bool上设置一个属性,那么你可以通过覆盖默认模型绑定器来扩展默认模型绑定程序,将0或1理解为false或true,如本so问题中所述
这两者的结合应该会让你得到你想要的。
这是一个变通方法,但如果您不想修改或创建模型绑定器,它是最终实例中的示例。
public ActionResult DoSomething(string flag)
{
if(flag.Equals("true") || flag.Equals(1)) {
//condition true, any else false
}
}