[英]IViewLocalizer internally string.Format and no params are passed into custom IStringLocalizer
想象一下這個字符串: Welcome, {0}. Your age is {1}
Welcome, {0}. Your age is {1}
。 如果有人執行@Localizer["welcome", "Timmy"]
頁面將無法呈現,因為它需要 2 個參數而不是 1 個。
我從IStringLocalizer
繼承的自定義實現具有以下代碼:
public LocalizedString this[string name] => this[name, new object[0]];
public LocalizedString this[string name, params object[] arguments]
{
get
{
var translation = _translations[name];
if(arguments.Any())
{
var formatted = string.Format(translation, arguments);
return new LocalizedString(name, formatted, false);
}
return new LocalizedString(name, translation, false);
}
}
這很完美,除了一件事: arguments
總是空的。 沒有參數,即使我知道該方法會被命中(斷點會被命中)。
因此,我無法對抗內部調用的string.Format
,如果參數少於預期(在這種情況下只有 1 個參數),則會引發異常。
我想擴展我的代碼以在我的代碼中try/catch
string.Format
,這樣我就可以記錄潛在的失敗,然后回## MISING ARGUMENT ##
顯示密鑰,或者簡單地用## MISING ARGUMENT ##
或類似的東西替換缺少的參數那。
我應該如何對抗這種情況? 奇怪的是,該方法被擊中了,但沒有參數。
您的代碼被命中但沒有參數的原因是來自此類的索引:Microsoft.AspNetCore.Mvc.Localization::HtmlLocalizer
public virtual LocalizedHtmlString this[string name, params object[] arguments]
{
get
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
return ToHtmlString(_localizer[name], arguments);
}
}
如您所見,它不會調用 _localizer[name, arguments] 而是 _localizer[name]。
邏輯似乎是 ToHtmlString 創建並返回 LocalizedHtmlString 的實例,Value 有以下描述
/// <summary>
/// The original resource string, prior to formatting with any constructor arguments.
/// </summary>
public string Value { get; }
看起來您不應該對其進行格式化,而是讓 LocalizedHtmlString.WriteTo 方法進行格式化。
我也有自己的IStringLocalizer<TResourceSource>
和IHtmlLocalizer<TResourceSource>
。 我不確定你的行為是什么,但對我來說,當頁面呈現並且LocalizedHtmlString.WriteTo
因參數計數不匹配而失敗時,它立即停止並且顯示部分呈現的任何內容並且沒有發生錯誤(從用戶的角度來看) . 但是,輸出窗口中有一些東西,這就是我確認LocalizedHtmlString.WriteTo
問題的方式。
為了解決,我基本上采用給定的資源字符串並找到最高的參數替換。 然后,如果傳入的參數不包含足夠的參數,我會附加足夠的參數和一個虛擬字符串,OP 建議指示缺少參數,以便頁面呈現但在字符串中顯示“缺少”。
public virtual LocalizedHtmlString this[ string name ] => GetLocalizedString( name, new object[] { }, GetValue, IsResourceFound, GetLocalizedHtmlItem );
public virtual LocalizedHtmlString this[ string name, params object[] arguments ]
{
var ls = _localizer[name, arguments];
if ( !ls.IsResourceNotFound( ls ) )
{
var matches = parameterCount.Matches( ls.Value );
var expectedParameters = matches.Count > 0
? matches.Cast<Match>()
.Max( m => int.Parse( m.Groups[ "number" ].Value ) + 1 )
: 0;
if ( arguments.Length < expectedParameters )
{
var protectedArgs =
arguments.Concat(
Enumerable
.Range( arguments.Length, expectedParameters - arguments.Length )
.Select( p => $"{{MISSING PARAM #{p}}}" )
).ToArray();
return _localizer[name, protectedArgs];
}
}
return ls;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.