2011-09-03 4 views
4

내 컨트롤러는 다음과 같습니다ASP.NET MVC3 이중 유효성 검사 (쉼표, 점, 널 (null))

public class PortefeuilleController : Controller 
    { 
      public ActionResult Create() 
      { 
       return View(new PortefeuilleViewModel{Saldo = 0.0}); 
      } 
    } 

이보기를 만들 내는 다음과 같습니다

@model PortefeuilleViewModel 

@{ 
    ViewBag.Title = "Create"; 
} 

<h2>Create</h2> 

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>PortefeuilleViewModel</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Naam) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Naam) 
      @Html.ValidationMessageFor(model => model.Naam) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Saldo) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Saldo) 
      @Html.ValidationMessageFor(model => model.Saldo) 
     </div> 

     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 

을 그리고 내 PortefeuilleViewModel는 다음과 같습니다 :

public class PortefeuilleViewModel 
{ 
    [DisplayName("Naam")] 
    [Required(ErrorMessage = "Gelieve een naam in te voeren")] 
    public string Naam { get; set; } 

    [DisplayName("Saldo")] 
    public double Saldo { get; set; } 
} 

내 문제는 "Saldo"필드에 있습니다.

필드를 비워두면 유효합니다 (코드 숨김이 ""0.0 "로 변경되고 데이터베이스에 해당 값이 저장되므로). 그러나 예를 들어, '19, 99 '및 '19 .99'도 유효해야합니다. 나머지는 모두 유효하지 않습니다.

나는 이것을 어떻게 풀 수 있는지 정말로 모른다. 나는 이미이 기사를 찾았습니다 : http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx 하지만 제 문제 중 두 번째 부분을 해결하지 못했습니다 ...

도움이 될만한 모든 도움을 주실 수 있습니다. 감사.

답변

20

확인, 서버 쪽과 클라이언트 쪽의 2 가지 수준에서 유효성 검사가 활성화되었습니다. 우선 서버 측 검증 문제를 다루겠습니다.

돈으로 작업 할 때 제일 먼저하는 것은 (Saldo 필드가 나타내는 것은 십진법을 사용하는 것입니다. 그래서 첫 번째 변화는 다음과 같습니다

[DisplayName("Saldo")] 
public decimal Saldo { get; set; } 

확인 지금의이 상황에 Haacked 모델 바인더 조금 적응할 수 있도록

public class DecimalModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     if (string.IsNullOrEmpty(valueResult.AttemptedValue)) 
     { 
      return 0m; 
     } 
     var modelState = new ModelState { Value = valueResult }; 
     object actualValue = null; 
     try 
     { 
      actualValue = Convert.ToDecimal(
       valueResult.AttemptedValue.Replace(",", "."), 
       CultureInfo.InvariantCulture 
      ); 
     } 
     catch (FormatException e) 
     { 
      modelState.Errors.Add(e); 
     } 

     bindingContext.ModelState.Add(bindingContext.ModelName, modelState); 
     return actualValue; 
    } 
} 

(. 및 소수 구분뿐만 아니라 빈 값으로 ,을 승인)하는 물론 Application_Start에 등록됩니다

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder()); 

을 우리는 서버 측 유효성 검사 문제를 해결 한이 단계에서. 클라이언트 쪽 유효성 검사에 관한 한 Microsoft에서 릴리스 한 jQuery globalization plugin을 사용할 수 있습니다. Scott Hanselman도 blogged입니다. 당신이 그것을 설치하면 당신은 클라이언트 측 문화를 강제로 클라이언트 측 유효성 검사를 수행 할 책임이있는 $.validator.methods.number 방법 오버라이드 (override) 할 수 있도록 :

$.validator.methods.number = function (value, element) { 
    // TODO: return true or false if value is a valid decimal 
} 
+1

확인 감사를, 작동합니다. 그러나 단지 질문 : 십진법을 두 배 이상 사용하는 이유는 무엇입니까? – Matthias

+1

@Matthias, 항상 통화를 위해 소수를 사용하십시오 : 통화를 잃어 버리지 않으려는 경우를 제외하고는 : http://stackoverflow.com/questions/1165761/decimal-vs-double-which-one-should-i-use-and-when) Doubles는 IEEE 754를 사용하여 저장되며 십진수는 10base에 저장됩니다. –

+0

감사합니다. 테스트하는 동안 단지 한 가지 더 깨달은 것 : 사용자가 숫자 대신 문자열을 입력하면 경고를 내지 않습니다. [유효 (ErrorMessage = "10 진수를주세요")]와 같은 주석이 유효성 검사에 사용할 수 있습니까? – Matthias

관련 문제