问题
I am trying to figure out if there is a way to make sure that numeric only input is allowed using Data Annotations and Entity Framework.
I am using the following code
[Required]
[DisplayName("Client No")]
[Column("client_no", TypeName = "smallint")]
public virtual Int16 Number { get; set; }
I want this to be displayed using number class.
In one place I use the following
<input type="number" name="searchClientNo" class="numericOnly" /><br />
but in the entry form I am using
@Html.EditorFor(m => m.Number, EditorTemplate.TextBox)
where I have a custom made EditorFor with the following code
<div class="editor-label">
@Html.Label((ViewData.ModelMetadata.DisplayName??ViewData.ModelMetadata.PropertyName),
new Dictionary<string, object>
{
{ "for", ViewData.ModelMetadata.PropertyName }
})
</div>
<div class="editor-field">
@Html.TextBox("", (object)Model,
new Dictionary<string, object>
{
{ "id", ViewData.ModelMetadata.PropertyName },
{ "name", ViewData.ModelMetadata.PropertyName },
{ "class", "text-box single-line"},
{ "data-bind", "value: " + ViewData.ModelMetadata.PropertyName },
})
@Html.ValidationMessage(ViewData.ModelMetadata.PropertyName,
new Dictionary<string, object>
{
{ "data-valmsg-for", ViewData.ModelMetadata.PropertyName }
})
</div>
I am wondering how can I keep this code without changes but still use the numeric only textbox. Do I need to use UIHint?
Or alternatively, is it possible to make my existing EditorFor smarter?
I found this blog post http://robseder.wordpress.com/2012/06/01/uihint-displaytemplates-and-editortemplates-in-mvc/ but I am already using a custom EditorFor. May be I need to add a new type, say, EditorTemplate.NumericTextBox and add another editor? This sounds like it may work, I am going to try this tomorrow...
Thanks a lot in advance.
回答1:
You could write a custom editor template ~/Views/Shared/EditorTemplates/NumberTemplate.cshtml
:
@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { type = "number" })
and then decorate your view model property with the UIHint
attribute:
[Required]
[DisplayName("Client No")]
[Column("client_no", TypeName = "smallint")]
[UIHint("NumberTemplate")]
public virtual Int16 Number { get; set; }
and inside your view:
@Html.EditorFor(x => x.Number)
or if you don't want to use the UIHint
attribute on your view model you could define EditorTemplate.NumericTextBox = "NumberTemplate"
and then:
@Html.EditorFor(m => m.Number, EditorTemplate.NumericTextBox)
回答2:
Just want to share my solution in case it may help someone:
My New EditorFor:
<div class="editor-label">
@Html.Label((ViewData.ModelMetadata.DisplayName??ViewData.ModelMetadata.PropertyName),
new Dictionary<string, object>
{
{ "for", ViewData.ModelMetadata.PropertyName }
})
</div>
<div class="editor-field">
@if (ViewData.ModelMetadata.ModelType.IsNumeric())
{
@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { type = "number", @class = "numericOnly" })
}
else
{
@Html.TextBox("", (object)Model,
new Dictionary<string, object>
{
{ "id", ViewData.ModelMetadata.PropertyName },
{ "name", ViewData.ModelMetadata.PropertyName },
{ "class", "text-box single-line"},
{ "data-bind", "value: " + ViewData.ModelMetadata.PropertyName },
})
}
@Html.ValidationMessage(ViewData.ModelMetadata.PropertyName,
new Dictionary<string, object>
{
{ "data-valmsg-for", ViewData.ModelMetadata.PropertyName }
})
</div>
And the IsNumeric extension method is based on the code I found in C# MSDN forum and this is its implementation:
/// <summary>
/// Checks is the object is of numeric type
/// see http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/66a7dc8d-f276-4d45-8da4-f8d9857db52c/
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static bool IsNumeric(object obj)
{
return (obj == null) ? false : IsNumeric(obj.GetType());
}
public static bool IsNumeric(this Type type)
{
if (type == null)
return false;
TypeCode typeCode = Type.GetTypeCode(type);
switch (typeCode)
{
case TypeCode.Byte:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.SByte:
case TypeCode.Single:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
return true;
}
return false;
}
来源:https://stackoverflow.com/questions/13984602/how-to-make-entry-field-to-allow-numbers-only-using-ef-and-data-annotations