ASP.NET MVC 模型绑定子对象

发布于 2024-11-07 20:44:19 字数 469 浏览 0 评论 0原文

我正在开发 ASP.NET MVC 3 应用程序。我有一个 Comment 类,它封装了一个 Post 类(每个评论都与博客中的帖子相关联),有一个用于编辑评论的操作方法,如下所示,

    [HttpPost]
    [Authorize(Users = admin)]
    public string EditComment(Comment comment)
    {
        //update the comment by calling NHiberante repository methods
    }

从 javascript 我只发布评论对象值,如评论 id,描述到服务器,因此在绑定时,我看到注释对象内的 Post 属性为 null,当我执行 ModelState.IsValid 时,我收到空错误。我的问题是如何将帖子对象绑定到评论?我可以将帖子 ID 与其他值一起传递到服务器。

谢谢 维贾亚·阿南德

I'm working on ASP.NET MVC 3 application. I have a Comment class that encapsulates a Post class (each comment is associated with a post in the blog), there is an action method for edit a comment as below,

    [HttpPost]
    [Authorize(Users = admin)]
    public string EditComment(Comment comment)
    {
        //update the comment by calling NHiberante repository methods
    }

From javascript I'm posting only the comment object values like comment id, description to the server, so when binding I see the Post property inside the comment object as null and when I do the ModelState.IsValid i'm getting empty errors. My question is how I can bind the post object to the comment? I can pass the post id to the server along with the other values.

Thanks
Vijaya Anand

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南巷近海 2024-11-14 20:44:19

提供附加字段

如果您还希望预先填充您的帖子实例,则还必须包含其必填字段。

我怀疑您有一个帖子视图,其中用户有一个显示评论字段的表单,以便他们可以在帖子上发表评论。

假设您有这样的类:

public class Post
{
    public int Id { get; set; }

    [Required]
    public string Title { get; set; }

    public string Content { get; set; }
}

public class Comment
{
    public int Id { get; set; }

    [Required]
    public string Author { get; set; }

    [Required]
    public string Content { get; set; }

    public Post Post { get; set; }
}

常用浏览器 POST

您需要做的是将帖子字段(隐藏类型)添加到您的表单中。我不知道你是如何创建表单的,无论你是否使用强类型视图......无论如何。您的输入必须具有名称:

  • Post.Id(为了将新评论附加到特定帖子
  • Post.Title(因为我已按要求设置它,但如果您愿意,您可以在此处输入任何虚拟文本)使用的是 Post.Id;只需设置标题,这样您的模型验证就不会失败)
  • 作者 - 可见(这是评论作者)
  • 内容 - 可见(这是是评论内容)

您是否使用以下方式创建这些字段Html 帮助程序或手动并不重要。默认模型绑定器将能够创建 post 对象实例,并且您的

Ajax POST

模型验证不会失败。如果您使用 Ajax 发布评论,则可以执行与中所述相同的操作。前面的示例并简单地使用 jQuery 的 .serialize() 函数,该函数将在调用 $.ajax() 时序列化表单字段,

但是您也可以使用 Javascript 以编程方式收集所有字段,也可以将该数据发布到服务器。您可以简单地创建一个 JSON 对象:

var comment = {
    Author: $("#Author").val(),
    Content: $("#Content").val(),
    Post: {
        Id: $("#Post_Id").val(),
        Title: $("#Post_Title").val()
    }
};

$.ajax({
    url: "someURL",
    type: "POST",
    data: $.toDictionary(comment),
    success: function(data) {
        // probably get a partial view with comment you can append it to comments
    },
    error: function(xhr, status, err) {
        // process error
    }
});

这里使用了两件事,需要一些解释:

  1. Ajax 错误处理也可能会消耗无效的模型状态错误(模型验证失败)和可以这种方式完成。

  2. 转换复杂(多级)JSON 对象是通过使用特殊的 $.toDictionary() 插件来完成的,该插件可以 可在此处找到,并提供简单地使用 Asp.net MVC 默认可理解的复杂 JSON 对象的功能模型粘合剂。它也适用于日期和列表。

Provide additional fields

If you want your post instance to be pre-populated as well, you will have to include its required fields as well.

I suspect you're having a post view where user has a form that displays comment fields so they can post a comment on the post.

suppose you have classes as:

public class Post
{
    public int Id { get; set; }

    [Required]
    public string Title { get; set; }

    public string Content { get; set; }
}

public class Comment
{
    public int Id { get; set; }

    [Required]
    public string Author { get; set; }

    [Required]
    public string Content { get; set; }

    public Post Post { get; set; }
}

Usual browser POST

What you would have to do is to add post fields (of hidden type) to your form. I don't know how you created your form whether you're using strong type views or not... Anyway. Your inputs would have to have names:

  • Post.Id (for the sake of attaching new comment to a particular post
  • Post.Title (because I've set it as required, but you could put in here whatever dummy text if all you'll be using is Post.Id; Title just needs to be set so your model validation won't fail)
  • Author - visible (this is comment author)
  • Content - visible (this is comment content)

Whether you're creating these fields using Html helpers or manually doesn't really matter. Default model binder will be able to create post object instance and your model validation won't fail.

Ajax POST

If you're posting your comments using Ajax you can do the same as described in the previous example and simply use jQuery's .serialize() function that will serialize form fields when calling $.ajax().

But you could as well programmaticaly collect all fields using Javascript and post that data to server just as well. You could simply create a JSON object:

var comment = {
    Author: $("#Author").val(),
    Content: $("#Content").val(),
    Post: {
        Id: $("#Post_Id").val(),
        Title: $("#Post_Title").val()
    }
};

$.ajax({
    url: "someURL",
    type: "POST",
    data: $.toDictionary(comment),
    success: function(data) {
        // probably get a partial view with comment you can append it to comments
    },
    error: function(xhr, status, err) {
        // process error
    }
});

There are 2 things that are being used here and need some explanation:

  1. Ajax error handling can also consume invalid model state errors (model validation failing) and can be accomplished this way.

  2. Converting a complex (multi-level) JSON object has been done by using a special $.toDictionary() plugin that can be found here and provides the ability to simply consume complex JSON objects that are understood by Asp.net MVC default model binder. It wors with dates and lists as well.

白云悠悠 2024-11-14 20:44:19

我认为您正在控制器上寻找 TryUpdateModel 或 UpdateModel 方法。您可以通过传递 Comment 作为参数(如您在示例中所做的那样)或通过调用 UpdateModel 方法进行绑定。

如果您从数据库中获取数据(正如您所做的那样),您应该使用这些方法来更新现有实体,而不是创建新实体。

我可能看起来像这样:

       [HttpPost]
       [Authorize(Users = admin)]
        public string EditComment(int id, FormCollection form)
        {
               //update the comment by calling NHiberante repository methods

               // Fetch comment from DB
                var comment =  NHibernateHelper.Get<Comment>(id);

                // Update the comment from posted values
                TryUpdateModel(comment);

                // Handle binding errors etc.
                if (!ModelState.IsValid)
                {
                    // On error
                }

            // Commit to DB
            NHibernateHelper.Update<Comment>(comment);


            //Done!



        }

我也在使用 NHibernate,它在这个实现中工作得很好。

I think your looking for the TryUpdateModel or UpdateModel methods on the Controller. You can bind either by passing Comment as an argument (as your doing in your example) or by calling the UpdateModel-methods.

If you're fetching from a db (as you are doing) you should use those methods to update the existing entity instead of creating a new one.

I't might look something like this:

       [HttpPost]
       [Authorize(Users = admin)]
        public string EditComment(int id, FormCollection form)
        {
               //update the comment by calling NHiberante repository methods

               // Fetch comment from DB
                var comment =  NHibernateHelper.Get<Comment>(id);

                // Update the comment from posted values
                TryUpdateModel(comment);

                // Handle binding errors etc.
                if (!ModelState.IsValid)
                {
                    // On error
                }

            // Commit to DB
            NHibernateHelper.Update<Comment>(comment);


            //Done!



        }

I'm also using NHibernate and it works great with this implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文