Asp.net Core MVC本地化结合String.Format报错,求解决方案
解决ASP.NET Core MVC本地化中带变量文本的FormatException问题
我来帮你搞定这个本地化场景的格式化错误——你遇到的FormatException是因为对IViewLocalizer的用法理解有点偏差,下面直接给正确的实现方案,再解释错误原因:
正确的实现方式
方式1:直接用IViewLocalizer的参数化索引器(推荐)
IViewLocalizer本身就支持传递格式化参数,完全不需要手动调用String.Format,代码更简洁也更符合框架设计:
@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @{ var item = "car"; } <h1>@Localizer["Max's {0} is blue", item]</h1>
对应的法语资源文件(比如Views/[你的视图名].fr.resx)里的条目保持你原来的配置就行:
Max's {0} is blue => {0} de Max est bleu
方式2:调用LocalizedString的Format方法
如果需要更灵活的参数处理,也可以显式调用返回结果的Format方法:
@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @{ var item = "car"; } <h1>@Localizer["Max's {0} is blue"].Format(item)</h1>
为什么原来的写法会报错?
你之前写的@String.Format(Localizer["Max's {0} is blue"],@item)之所以抛出异常,核心原因是:Localizer["键名"]返回的是**LocalizedString对象**,不是直接的字符串。当你把这个对象传给String.Format时,方法会把整个LocalizedString当作第一个格式化参数,而你的格式化字符串里需要{0}对应的变量,但你并没有把item作为格式化字符串的参数传递——相当于你只给了String.Format一个参数(LocalizedString),但格式化字符串要求至少两个参数,所以就出现了索引越界的错误。
哪怕你改成String.Format(Localizer["Max's {0} is blue"].Value, item)能运行,也不推荐这么做,因为框架已经帮你封装好了更优雅的参数化本地化方式。
额外提示
- 确保你的资源文件路径和命名符合ASP.NET Core本地化的规则,比如视图对应的资源文件要放在
Resources/Views/[控制器名]/[视图名].resx或者Views/[控制器名]/[视图名].resx位置。 - 如果遇到复数、性别区分等复杂本地化场景,可以进一步研究
IStringLocalizer的复数重载方法,或者结合数据注解的本地化特性。
内容的提问来源于stack exchange,提问作者Alexis
相关产品推荐
相关产品推荐

