【问题标题】:Override Message “the value {0} is invalid for {1}” in case of int in WebAPI在 WebAPI 中为 int 的情况下覆盖消息“值 {0} 对于 {1} 无效”
【发布时间】:2019-12-26 17:03:33
【问题描述】:

我有一个变量名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());

预期:

该值对 CountryId 无效。

结果:

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

【问题讨论】:

  • 在这种情况下不要使用DefaultBindinModel,也请在问题中输入一些代码
  • @PrasadTelkikar 我知道消息更清楚,但要求是 EndUser 应该不能看到输入值。
  • @CodeNameJack 我尝试制作自己的 BinderModel,但它不起作用。我正在制作资源文件并添加了一个字段“PropertyValueInvalid The value '{0}' is not valid for {1}.”。但没有运气。

标签: c# asp.net-web-api model-binding


【解决方案1】:

网络 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 类(由于 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

【讨论】:

  • 谢谢。我已经尝试过了,但这仅适用于 MVC,不适用于 WebAPI。
  • @AnuragMaheshwari,别介意......我刚刚在你找到它的地方看到了你的答案:)
  • 嗨@Aleks,谢谢你的答案,但我尝试使用你的解决方案,但我遇到了一个错误“'CustomTypeConversionErrorMessageProvider'没有重载匹配委托'ModelBinderErrorMessageProvider'”。请为我提供解决方案。
  • 我在这里找到了答案:stackoverflow.com/a/26782311/11727639
  • 嗨@AnuragMaheshwari,这很奇怪。您在回答中使用的方法是否有效? (这或多或少是一回事)。您使用的是哪个版本的 Microsoft.AspNet.WebApi.Core?
【解决方案2】:

我认为此链接会对您有所帮助,选项 #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/

【讨论】:

    【解决方案3】:

    谢谢大家!但我得到了解决方案。 要在 WebAPI 中为 Int Validation 覆盖此消息,您只需在 Global.asax.cs

    Application_Start 方法中添加以下 sn-p
    ModelBinderConfig.TypeConversionErrorMessageProvider = (context, metadata, value) => {
    
                if (!typeof(int?).IsAssignableFrom(value.GetType()))
                {
                    return "The Value is not valid for " + metadata.PropertyName;
                }
                return null;
            };
    

    【讨论】:

      猜你喜欢
      • 2012-06-01
      • 2012-09-28
      • 2014-02-25
      • 1970-01-01
      • 2014-09-29
      • 1970-01-01
      • 2013-05-18
      • 2011-02-03
      • 1970-01-01
      相关资源
      最近更新 更多