c# -ModelState.IsValid 仅在资源语言更改时返回 false?

Posted

技术标签:

【中文标题】c# -ModelState.IsValid 仅在资源语言更改时返回 false?【英文标题】:c# -ModelState.IsValid returns false only when resource language changed? 【发布时间】:2017-08-12 23:33:47 【问题描述】:

我的剃刀视图上有一个字段如下

 @html.TextBoxFor(model => model.Duration, new  @class = "form-control txtSite input-large rounded-custom", name = "Duration", @type = "number", min = "0", id = "durationId", required = "true", Tabindex = "1", value = "0" )
 @Html.ValidationMessageFor(model => model.Duration, "", new  style = "color: red" )

我在 MVC 中使用实体模型结构。字段持续时间在数据库表“活动”中定义(我在剃须刀上使用的模型相同)作为浮点数。但实体元数据显示为 Double 如下。

  public Nullable<double> Duration  get; set; 

我使用部分类作为 Activity.cs 进行所需的验证,如下所示

 [MetadataTypeAttribute(typeof(Activity.Metadata))]
public partial class Activity
 
  internal sealed class Metadata
   
     [Required(ErrorMessageResourceType = typeof(Resources.Common), ErrorMessageResourceName = "PleaseEnterDuration")]
      public Nullable<double> Duration  get; set; 
   

在Controller上我的代码是这样的

[HttpPost]
public ActionResult AddActivity(Activity model)

    if (ModelState.IsValid)
        
          //Some Code
        

奇怪的是,当我显示标签的资源语言是英语时,我的代码适用于浮点值,而当我将其更改为另一种语言(法语)时它不起作用。这里 ModelState.IsValid 返回 false。而且我收到错误

"The value 3.5(any float value) is invalid for Duration." 

如何为另一种资源语言修复它?任何帮助将不胜感激

【问题讨论】:

参考此博客geekswithblogs.net/shaunxu/archive/2010/05/06/… 法国人不要使用逗号作为点 (3,5) 而不是句点 (3.5)。 @Dave Becker - 是的,你说得对,但在数据库方面,我把它当作浮点数。我是否将其更改为字符串? @KulOmkar 您可能需要在服务器端进行格式化(法语),因此值3.5 输出为3,5,请参阅此帖子:***.com/questions/1559185/… 【参考方案1】:

您收到该错误是因为您网站的文化设置为不使用点 . 作为小数分隔符的语言(法语)。但是,Duration 的条目中有一个点,因此您的模型的状态评估为无效。

换句话说,您的网站(服务器端)是法国文化,但您使用的浏览器或任何客户端不是法语。


修复

您需要同步客户端和服务器的语言在每个请求上:确保设置文化的代码在每个请求中执行,而不仅仅是在应用程序启动时执行。用户可以在请求之间切换语言。将CurrentCulture 设置为适当的语言将使用该语言的数字格式、日期时间格式等。

此外,建议但不是必须解决您的问题,您还应该设置CurrentUICulture,它将从您的语言资源文件中获取标签、消息等(如果您有任何资源文件)。

按照上面@orhun.begendi的回答设置以上2项。

【讨论】:

是的,我有 Common.resx 和 Common.fr.resx 等资源文件,我正在使用它们,它们分别适用于 Engliah 和法语版本【参考方案2】:

您可以像这样轻松覆盖 global.asax.cs 文件

protected void Application_AcquireRequestState(object sender, EventArgs e)

     //Create culture info object 
     CultureInfo ci = new CultureInfo("en");

     if(Request.Url.Host.Equals("yourdomain.com",                                   StringComparison.InvariantCultureIgnoreCase))
     
          ci = new CultureInfo("fr"); //in your case
     

     System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
     System.Threading.Thread.CurrentThread.CurrentCulture =                                     CultureInfo.CreateSpecificCulture(ci.Name);

你也可以在 begin_request 方法中设置。

更多信息,您可以查看此链接 https://www.codeproject.com/articles/778040/beginners-tutorial-on-globalization-and-localizati

【讨论】:

我的 global.asax.cs 已经被你提到的代码覆盖了。所有其他文本、日期等都在我的系统上以本地语言运行 在法语上,有一些指向问题,你可以在请求后检查线程文化吗?你必须在那里指定,如果你得到其他文化,那就有问题了。您也可以检查更改网络浏览器的文化信息。有时像在铬上;计算机文化信息应用在网页上,为了进行正确的测试,你也必须改变它。 @OmkarKulkarni 确保为每个请求执行设置文化的代码,而不仅仅是在应用程序启动时执行。用户可以在请求之间切换语言。 @Coding Yoshi - 明白了,我设置文化的代码仅在应用程序启动时执行,因此标签来自该文化。

以上是关于c# -ModelState.IsValid 仅在资源语言更改时返回 false?的主要内容,如果未能解决你的问题,请参考以下文章

C# 仅在存在时使用数组

当结构仅在运行时已知时,将结构从 c++ 传递到 c#

仅在数据库中存储日期而不是时间部分 C#

C# PowerShell 无法仅在 Web 应用程序中连接到 AzureAD

C# 代码仅在逐步执行时给出预期结果?

如何在 C# 中使用 TaskScheduler 设置“仅在登录时运行”和“运行方式”?