在 WebAPI 中为 int 时覆盖消息“值 {0} 对 {1} 无效”

Override Message “the value {0} is invalid for {1}” in case of int in WebAPI

我有一个变量名CountryId(整数类型)。 如果用户向 CountryId 提供 string 或任何随机输入,ASP.Net 中的内置 DefaultBindingModel 会抛出错误:

The value '<script>gghghg</script>' is not valid for CountryId.

如果 ModelState 失败,我想覆盖此消息并提供我自己的文本。我想要一个通用的解决方案。

我已经搜索并尝试了很多解决方案,但它们只适用于 MVC 应用程序,而不适用于 webAPI

public class IntegerModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult == null)
        {
            return base.BindModel(controllerContext, bindingContext);
        }
         int i;

        return !int.TryParse(valueProviderResult.AttemptedValue.ToString(), out i) ? new ValidationResult("Failed") : ValidationResult.Success;

    }
}

在我的 WebAPI.config 中:

ModelBinders.Binders.Add(typeof(int), new IntegerModelBinder());

预计:

The value is not valid for CountryId.

结果:

The value '<script>gghghg</script>' is not valid for CountryId.

我认为这个 link 会对您有所帮助,选项 #3:使用自定义模型活页夹可能是关键的解决方案。

public class LocationModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, 
      ModelBindingContext bindingContext)
    {
        string key = bindingContext.ModelName;
        ValueProviderResult val = bindingContext.ValueProvider.GetValue(key);
        if (val != null)
        {
            string s = val.AttemptedValue as string;
            if (s != null)
            {
                return Location.TryParse(s);
            }
        }
        return null;
    }
}

现在我们需要连接模型绑定器。

   public object  MyAction2(
        [ModelBinder(typeof(LocationModelBinder))]
        Location loc) // Use model binding to convert
    {
        // use loc...
    }

https://blogs.msdn.microsoft.com/jmstall/2012/04/20/how-to-bind-to-custom-objects-in-action-signatures-in-mvcwebapi/

网络API

对于 Web API,您可以替换 TypeConversionErrorMessageProvider 以提供自定义消息。

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        ModelBinderConfig.TypeConversionErrorMessageProvider = CustomTypeConversionErrorMessageProvider;

        // rest of init code
    }

    private string CustomTypeConversionErrorMessageProvider(HttpActionContext actionContext, System.Web.Http.Metadata.ModelMetadata modelMetadata, object incomingValue)
    {
        return $"The value is not valid for {modelMetadata.PropertyName}";
    }
}

注意CustomTypeConversionErrorMessageProvidermodelMetadata参数的完整限定;如果你不这样做,那么 System.Web.MvcModelMetadata class 被引用(由于 Global.asax.cs 中的默认 usings),而不是System.Web.Http.Metadata 中的一个,你得到一个错误:-

Error   CS0123  No overload for 'CustomTypeConversionErrorMessageProvider' matches delegate 'ModelBinderErrorMessageProvider'

MVC

对于 MVC,您可以使用 MVC 的本地化功能来替换那些验证消息。

基本上,您创建自己的资源文件,使用 DefaultModelBinder.ResourceClassKey 将 MVC 指向该资源文件,然后在该资源文件中,为 PropertyValueInvalid 键指定您自己的文本。

有关于如何执行此操作的指南here

谢谢大家!但我得到了解决方案。 要在 WebAPI 中为 Int Validation 覆盖此消息,您只需在 Application_Start 方法中添加以下代码段 Global.asax.cs

ModelBinderConfig.TypeConversionErrorMessageProvider = (context, metadata, value) => {

            if (!typeof(int?).IsAssignableFrom(value.GetType()))
            {
                return "The Value is not valid for " + metadata.PropertyName;
            }
            return null;
        };