7

(basitlik için elimden):ASP.NET MVC varsayılan bağlayıcı: çok uzun ints, boş doğrulama hata mesajı ben şu modeli sınıf var

public class Info 
{ 
    public int IntData { get; set; } 
} 

İşte bu modeli kullanan benim Jilet biçimi şöyledir:

@model Info 
@Html.ValidationSummary() 
@using (Html.BeginForm()) 
{ 
    @Html.TextBoxFor(x => x.IntData) 
    <input type="submit" /> 
} 

Metin kutusuna sayısal olmayan bir veri girersem, doğru bir doğrulama iletisi alırım, örneğin: "Değer 'qqqqq', 'IntData' alanı için geçerli değil".

Fakat çok uzun bir rakam dizisi girersem (345234775637544 gibi), bir EMPTY doğrulama özeti alırım. Benim denetleyicisi kodunda

, ben ModelState.IsValid o beklendiği gibi false olduğunu görmek ve ModelState["IntData"].Errors[0] aşağıdaki gibidir: Gördüğünüz gibi, doğrulama normalde çalışır

{System.Web.Mvc.ModelError} 
ErrorMessage: "" 
Exception: {"The parameter conversion from type 'System.String' to type 'System.Int32' failed. See the inner exception for more information."} 

(exception itself) [System.InvalidOperationException]: {"The parameter conversion from type 'System.String' to type 'System.Int32' failed. See the inner exception for more information."} 
InnerException: {"345234775637544 is not a valid value for Int32."} 

ancak bir hata iletisi vermezse Kullanıcı.

Varsayılan model bağlama aracının davranışını değiştirebilir miyim, bu durumda uygun bir hata mesajı gösterebilir mi? Yoksa özel bir ciltleyici yazmam gerekecek mi?

cevap

8

bir yolu özel modeli cilt yazma olacaktır:

public class IntModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     if (value != null) 
     { 
      int temp; 
      if (!int.TryParse(value.AttemptedValue, out temp)) 
      { 
       bindingContext.ModelState.AddModelError(bindingContext.ModelName, string.Format("The value '{0}' is not valid for {1}.", value.AttemptedValue, bindingContext.ModelName)); 
       bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value); 
      } 
      return temp; 
     } 
     return base.BindModel(controllerContext, bindingContext); 
    } 
} 
Application_Start tescil edilebilir

:

ModelBinders.Binders.Add(typeof(int), new IntModelBinder()); 
+0

Teşekkür ederim, varsayılan bağlayıcıyı ayarlayamayacaksam bu çözümü seçeceğim. – Zruty

+0

'[Display (Name = ...)]' özniteliğine göre yerelleştirilmiş alan adı istiyorsanız 'bindingContext.ModelName'ı' bindingContext.ModelMetadata.DisplayName' olarak değiştirmeyi öneririm. – Gh61

1

Nasıl 10 ya da öylesine giriş sahada MaxLength ayarlama hakkında? Bunu, IntData'da bir aralık ayarlayarak birlikte yapardım. Elbette bir kullanıcının 345234775637544 numaralı telefona girmesine izin vermek istemezsiniz. Bu durumda bir dizeyle daha iyi durumdasınız demektir.

+0

şimdi düşünmediğim bir şey :) Teşekkür ederim. – Zruty

+0

bu akıllı :)! – frictionlesspulley