2017-06-26 6 views
0

Asp.netコアを使用してWebアプリケーションを構築しています。私は組み込みコア検証方法を使用しています。私は、データ注釈を使用してクライアント側の検証を適用するフォームを持っています。私のモデルは次のようになります:nullの可能性があるにもかかわらず、ASP.netコアの視野モデルが必要です

[Display(Name= "Address")] 
[Required] 
[StringLength(80, MinimumLength = 5)] 
public string Address { get; set; } 

[Display(Name = "When it is needed")] 
[Required] 
[DataType(DataType.Date)] 
public DateTime TakeDownDate { get; set; } 

[Display(Name = "Exact time")] 
[Required] 
[DataType(DataType.Time)] 
public TimeSpan ExactTimeToTakeDown { get; set; } 

[Display(Name = "Content of container")] 
public ContainerContentEnum? Content { get; set; } 

[Display(Name = "When to take up")] 
[DataType(DataType.Date)] 
public DateTime? TakeUpDate { get; set; } 

[Display(Name= "Other comment")] 
[StringLength(250)] 
public string Other { get; set; } 

[Display(Name = "Multiple round")] 
public bool MaybeMoreRound { get; set; } 

TakeUpDateプロパティを見てみましょう。 nullableなので、フォームを送信するフィールドに何も入力しないようにします。フォームが送信された後、対応するコントローラのメソッドによって処理されます

[HttpPost] 
[ValidateAntiForgeryToken] 
public IActionResult SaveNewClaim(NewClaimViewModel newClaim) 
{ 
    if (ModelState.IsValid) 
    { 
     _claimsRepository.Insert(_newClaimViewModelToClaimConverterService.Convert(newClaim)); 
     return CreateJsonResult(true, "Az igény sikeresen lementésre került"); 
    } 

    return CreateJsonResult(false, GetErrorMessages()); 
} 

private JsonResult CreateJsonResult(bool isSuccess, string responseMessage) 
{ 
    return Json(new 
     { 
      success = isSuccess, 
      responseText = responseMessage 
     } 
    ); 
} 

private string GetErrorMessages() 
{ 
    return string.Join(";\n", ModelState.Values 
     .SelectMany(x => x.Errors) 
     .Select(x => x.ErrorMessage)); 
} 

とビュー用として、.cshtmlファイルには、次のようになります。

@using App.ViewModels.ClaimViewModels.ClaimModels 
@model App.ViewModels.ClaimViewModels.ClaimModels.NewClaimViewModel 

<div id="calendarModal" class="modal fade"> 
    <div class="modal-dialog"> 
     <div class="modal-content"> 
      <div class="modal-header"> 
       <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true"></span> <span class="sr-only">close</span></button> 
       <h3><b>Új igény felvétele</b></h3> 
      </div> 
      <div id="modalBody" class="modal-body"> 
       <div asp-validation-summary="ModelOnly" class="text-danger"></div> 
       <form asp-action="SaveNewClaim" id="EventForm" class="well"> 
        <input type="hidden" id="eventID" class="form-control"> 
        <div class="form-group"> 
         <label asp-for="Address" class=""></label> 
         <div class=""> 
          <input asp-for="Address" class="form-control"> 
          <span asp-validation-for="Address" class="text-danger"> </span> 
         </div> 
        </div> 
        <div class="form-group"> 
         <label asp-for="TakeDownDate" class=""></label> 
         <div class=""> 
          <input asp-for="TakeDownDate" class="form-control" /> 
          <span asp-validation-for="TakeDownDate" class="text-danger"> </span> 
         </div> 
        </div> 
        <div class="form-group"> 
         <label asp-for="ExactTimeToTakeDown" class=""></label> 
         <div class=""> 
          <input asp-for="ExactTimeToTakeDown" class="form-control" /> 
          <span asp-validation-for="ExactTimeToTakeDown" class="text-danger"> </span> 
         </div> 
        </div> 
        <div class="form-group"> 
         <label asp-for="Content" class=""></label> 
         <div class=""> 
          <select asp-for="Content" asp-items="@Html.GetEnumSelectList<MokaKukaMap.Domain.Model.ContainerContentEnum>()" class="form-control"> 
           <option selected="selected" value="">Kérem válassz</option> 
          </select> 
          <span asp-validation-for="Content" class="text-danger"> </span> 
         </div> 
        </div> 
        <div class="form-group"> 
         <label asp-for="TakeUpDate" class=""></label> 
         <div class=""> 
          <input asp-for="TakeUpDate" class="form-control" /> 
          <span asp-validation-for="TakeUpDate" class="text-danger"> </span> 
         </div> 
        </div> 
        <div class="form-group"> 
         <label asp-for="Other" class=""></label> 
         <div class=""> 
          <input asp-for="Other" class="form-control" /> 
          <span asp-validation-for="Other" class="text-danger"> </span> 
         </div> 
        </div> 
        <div class="form-group"> 
         <label asp-for="MaybeMoreRound" class=""></label> 
         <div class=""> 
          <input asp-for="MaybeMoreRound" type="checkbox" class="form-control" /> 
          <span asp-validation-for="MaybeMoreRound" class="text-danger"> </span> 
         </div> 
        </div> 
       </form> 
      </div> 
      <div class="modal-footer"> 
       <button type="button" id="btnPopupCancel" data-dismiss="modal" class="btn">Vissza</button> 
       <button type="button" id="btnPopupSave" class="btn btn-primary">Igény mentése</button> 
      </div> 
     </div> 
    </div> 
</div> 

少なくとも最後にではなく、私のAJAX送信ボタン上のポスト(イベントをクリックしてください):

$('#btnPopupSave').click(function() { 
    var dataRow = { 
     Address: $('#Address').val(), 
     TakeDownDate: $('#TakeDownDate').val(), 
     ExactTimeToTakeDown: $('#ExactTimeToTakeDown').val(), 
     Content: $('#Content').val(), 
     TakeUpDate: $('#TakeUpDate').val(), 
     Other: $('#Other').val(), 
     MaybeMoreRound: $('#MaybeMoreRound').val() 
    } 

    console.log('Submitting form...'); 
    $.ajax({ 
     type: 'POST', 
     url: 'SaveNewClaim', 
     data: dataRow, 
     headers: 
     { 
      "RequestVerificationToken": '@GetAntiXsrfRequestToken()' 
     }, 
     dataType: 'json', 
     success: function (response) { 
      if (response.success) { 
       $('#calendarModal').modal('hide'); 
       $('#calendar').fullCalendar('refetchEvents'); 
       alert(response.responseText); 
      } 
      else { 
       alert(response.responseText); 
      } 
     }, 
     error: function(xMlHttpRequest, textStatus, errorThrown) { 
      console.log(XMLHttpRequest.responseText); 
      console.log(textStatus); 
      console.log(errorThrown); 
     } 
    }); 
}); 

私はTakeUpDateのNULL可能に設定しているという事実にもかかわらず、私のモデルはまだ無効であると私は、次のエラーメッセージました:を'使用する時間'の値が無効です。 enter image description here

正直言って、ここでstackoverflowやその他のフォーラムで関連するすべてのQ/Asをチェックしました。すべてのフィールドでnullableフィールドを設定するのが正しい方法です。

あなたが任意のより多くのコードが必要な場合は、私はすぐにこの質問に追加してください...

+1

がどのようなタイプがTakeUpDate用コントローラに渡されていますか?あなたのフォームに空のテキストボックスがあれば、コントローラは空の文字列を受け取ります。 null可能なDateTimeではありません。 – melkisadek

+0

エラーメッセージ 'The value 'は、' When take up 'が無効です'は、 'When when take up'を文字列として解析しようとしていることを伝えています。あなたはあなたのマークアップ(剃刀)を投稿できますか? – Alex

+0

@melkisadek渡された型は: "System.Date.DateTime?"その値はnullです。 – mirind4

答えて

1

根本的な問題は、あなたが戻ってコントローラに空の文字列を渡しているということです。

モデルバインドが行われる前に、空の文字列をキャプチャしてヌルに変換するか、既知の「バグ」を回避して、この時点で検証が常に失敗するという事実を処理する必要があります。

明示的にnullを送信するようにAjax POSTを変更することができます。

また、(おそらく私がやっている)コントローラーであなたの日付をチェックするだけの正気です。空の文字列の場合は、ModelStateから削除して、無効であるとフラグを付けないようにします。 ModelStateは引き続き他のフィールドを通常通り検証します。次のような

何か:

public IActionResult SaveNewClaim(NewClaimViewModel newClaim) 
{ 
    if (newClaim.TakeUpDate == "") 
    { 
     ModelState.Remove("TakeUpDate"); 
    } 

    if (ModelState.IsValid) 
    { 
     newClaim.TakeUpDate = null; 

     _claimsRepository.Insert(_newClaimViewModelToClaimConverterService.Convert(newClaim)); 
     return CreateJsonResult(true, "Az igény sikeresen lementésre került"); 
    } 

    return CreateJsonResult(false, GetErrorMessages()); 
}