私は単純なViewModelを持っています:
public class CategoryViewModel
{
[Display(Name = "Category ID")]
[Editable(false)]
public int CategoryId { get; set; }
[Required(ErrorMessage = "Name is required")]
[StringLength(100, MinimumLength = 2, ErrorMessage = "You must enter a category name of at least 2 and maximum 100 characters")]
[Display(Name = "Name")]
public string Name { get; set; }
[HiddenInput(DisplayValue = false)]
public int? ParentId { get; set; }
}
ビューに送信するコントローラーと、CategoryId と ParentId が 0 に設定された新しい、入力されていないビューモデルがあります。ビューモデル (カスタム object.cshtml エディター テンプレート) を使用して @Html.EditorFor を使用していましたが、簡単にするために、次のように簡単に変更しました:
var options = new AjaxOptions()
{
Url = "/Api/Category/Post/"
OnComplete = "onCategorySaveComplete(xhr, status)",
OnBegin = "onCategorySaveBegin",
OnFailure = "onCategorySaveFailure(xhr, status)",
};
@using (Ajax.BeginForm(options))
{
<div class="inputForm">
<div class="header">@(Model.CategoryId == 0 ? "New Category" : "Edit "+Model.Name+" ("+Model.CategoryId+"/"+Model.ParentId+")")</div>
<div class="section">
<input type="hidden" name="CategoryId" value="" data-bind="value: CategoryId" />
<input type="hidden" name="ParentId" value="" data-bind="value: ParentId" />
<div class="line">
<div class="label">
@Html.LabelFor(m => m.Name) *
</div>
<div class="input">
@Html.TextBoxFor(m => m.Name,null,new {@data_bind = "value: Name"})
@Html.ValidationMessageFor(m => m.Name)
</div>
</div>
</div>
@Html.ValidationSummary("Some data is not correct:")
<div class="footer"> <input type="submit" id="btnSave" value="Save" /></div>
</div>
}
私のAPIコントローラーには、次のものがあります。
public CategoryViewModel Post(CategoryViewModel value)
{
value = CategoryService.AddOrUpdate(value);
return value;
}
ユーザーが KendoUI ツリービューからカテゴリを選択できるようにする他のクライアント側関数があり、API 呼び出しを介して ViewModel をロードし、KnockOut を使用してバインドしますが、すべてうまく機能するので、今はスキップさせてください。
ここで、フォームを送信してサーバーに送信された内容を確認すると、次のように表示されます。
Key Value
Request POST /Api/Category/Post/ HTTP/1.1
Accept */*
Content-Type application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With XMLHttpRequest
Referer http://localhost:3709/Category/
Accept-Language en-GB,nl-BE;q=0.5
Accept-Encoding gzip, deflate
User-Agent Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host localhost:3709
Content-Length 71
Connection Keep-Alive
Cache-Control no-cache
Cookie GUEST_LANGUAGE_ID=en_US; COOKIE_SUPPORT=true
およびリクエスト本文:
CategoryId=1130&ParentId=4&Name=Sensors&X-Requested-With=XMLHttpRequest
今までは、すべて正常だと思います。しかし、API コントローラーにブレークポイントを追加すると、CategoryViewModel の値が実際には「Name」と「ParentId」のみを保持し、「CategoryId」が 0 であることがわかります。私のサービスは、新しいカテゴリーを作成する必要があると判断します。クライアントに返される新しい CategoryViewModel は JSON 文字列です。
CategoryId が ViewModel に読み込まれない理由がわかりません。また、URLEcoded 方式ではなく、JSON 文字列を介してデータを送信しようとすることに頭を悩ませました。ヘルパーから離れて、jquery を直接使用する必要がありますか?
助けてくれて本当にありがとうございます
編集夜の睡眠後:
CategoryId が ViewModel に読み込まれない理由は非常に単純です。CategoryId には [Editable(false)] という注釈があります。これを削除すると機能します。これらの注釈は、フィールドへの実際の書き込みをブロックすることに気付かずに、EditorFor および検証メッセージにのみ使用します。
したがって、特定のフィールドを非表示の html フィールドとしてレンダリングするように EditorFor に指示する別の方法が必要です。何か案は?また、@Ajax.BeginForm を使用して、エンコードされた URL の代わりに JSON 文字列をサーバーに送信するように構成できないのはなぜですか。ありがとう