1

我有一个简单的 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。我的视图使用 @Html.EditorFor 使用 viewmodel(自定义 object.cshtml 编辑器模板),但为了让事情变得简单,我将其更改为以下简单内容:

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 我的服务然后认为它需要创建一个新的 Category ,返回一个新的 CategoryViewModel,然后返回给客户端的是 JSON 字符串。

我不明白为什么我的 CategoryId 没有读入我的 ViewModel。另外,我对尝试通过 JSON 字符串而不是 URLEcoded 方式提交数据感到头疼。我应该简单地远离助手并直接使用 jquery 吗?

非常感谢您的帮助

编辑夜间睡眠后:

我的 CategoryId 没有被读入我的 ViewModel 的原因很简单: CategoryId 有一个注释 [Editable(false)] 如果我删除它,就可以了。实际上,我仅将这些注释用于 EditorFor 和验证消息,而没有意识到它会阻止对该字段的实际写入。

所以我需要另一种方法来告诉 Edi​​torFor 将某些字段呈现为隐藏的 html 字段。有任何想法吗?以及为什么使用 @Ajax.BeginForm 不能配置为向服务器发送 JSON 字符串而不是 url 编码,这仍然存在。谢谢

4

1 回答 1

0

所以我需要另一种方法来告诉 Edi​​torFor 将某些字段呈现为隐藏的 html 字段。有任何想法吗?

您可以使用HiddenInput将指示编辑器模板将其呈现为隐藏字段的属性:

[HiddenInput(DisplayValue = false)]
public int CategoryId { get; set; }
于 2012-07-13T09:06:10.180 回答