我需要一个将string
解析为int
的解决方案,以便与Blazor的InputSelect
一起使用。
我发现这个解决方案效果很好。
现在使用我的型号
public class Book
{
[Required]
public int Id { get; set; }
[Required]
public int CategoryId { get; set; }
public Category Category { get; set; }
...
[Required]
public EnumLanguages Language { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
}
我可以在我的Razor页面中使用它,如下所示:
<InputSelectNumber id="category" @bind-Value="@Book.CategoryId">
@foreach (var category in Categories)
{
<option value="@category.Id">@category.Name</option>
}
</InputSelectCustom>
有了它,我可以直接在InputSelectNumber
标签上使用我的CategoryId
(即int
(。到目前为止还不错。
现在我需要对枚举做同样的操作,比如EnumLanguages
public enum EnumLanguages
{
English,
French
}
我更新了InputSelectNumber
类,如下所示:
public class InputSelectNumber<T> : InputSelect<T>
{
protected override bool TryParseValueFromString(string value, out T result, out string validationErrorMessage)
{
if (typeof(T) == typeof(int))
{
if (int.TryParse(value, out var resultInt))
{
result = (T)(object)resultInt;
validationErrorMessage = null;
return true;
}
else
{
result = default;
validationErrorMessage = "The chosen value is not valid.";
return false;
}
}
else
if (typeof(T) == typeof(EnumLanguages))
{
if (Enum.TryParse<EnumLanguages>(value, out var resultEnum))
{
result = (T)(object)resultEnum;
validationErrorMessage = null;
return true;
}
else
{
result = default;
validationErrorMessage = "The chosen value is not valid.";
return false;
}
}
else
{
return base.TryParseValueFromString(value, out result, out validationErrorMessage);
}
}
}
并使用它:
<InputSelectNumber @bind-Value="Book.Language">
<option value="English">English</option>
<option value="French">French</option>
</InputSelectCustom>
正如您所看到的,我添加了第二个代码块,在其中我对代码中的EnumLanguages
进行了硬编码。但我更喜欢使用枚举的通用代码,但我不知道这是否可行。请不要说我不能更改该方法的签名,因为它是一个重写。
您可以使用这样的方式:
protected override bool TryParseValueFromString(string value, out T result, out string validationErrorMessage)
{
if (typeof(T) == typeof(int))
{
if (int.TryParse(value, out var resultInt))
{
result = (T)(object)resultInt;
validationErrorMessage = null;
return true;
}
else
{
result = default;
validationErrorMessage = "The chosen value is not valid.";
return false;
}
}
else if (typeof(T).IsEnum)
{
if (EnumTryParse<T>(value, out var resultEnum))
{
result = (T)(object)resultEnum;
validationErrorMessage = null;
return true;
}
else
{
result = default;
validationErrorMessage = "The chosen value is not valid.";
return false;
}
}
else
{
return base.TryParseValueFromString(value, out result, out validationErrorMessage);
}
}
而这种程度的方法:
public static bool EnumTryParse<T>(string input, out T theEnum)
{
foreach (string en in Enum.GetNames(typeof(T)))
{
if (en.Equals(input, StringComparison.CurrentCultureIgnoreCase))
{
theEnum = (T)Enum.Parse(typeof(T), input, true);
return true;
}
}
theEnum = default(T);
return false;
}
最终使用
<InputSelectNumber @bind-Value="@language" T="@EnumLanguages">
<option value="English">English</option>
<option value="French">French</option>
</InputSelectNumber>