简体   繁体   English

asp.net MVC项目中的“索引超出范围”错误

[英]“Index was out of range” error in asp.net MVC project

I'm working on asp.net MVC 5 project.I have two models Post and Comment having one to many relationship between them. 我正在asp.net MVC 5项目上工作。我有两个模型Post和Comment,它们之间存在一对多的关系。 In Post's Details view, I want to add comments in that Post. 在帖子的“详细信息”视图中,我想在该帖子中添加评论。 How can I do it without using any ViewModel? 不使用任何ViewModel怎么办? Only Post model is passed in the view. 视图中仅传递Post模型。 I want to access Comment and its properties by using Post model reference, after all they have one many relationship between them, Post model have Comment's reference. 我想使用Post模型引用访问Comment及其属性,毕竟它们之间有很多关系,Post模型具有Comment的引用。

Here is my code example Details actions in Post's controller 这是我的代码示例Post控制器中的Details动作

    [HttpPost]
    public ActionResult Details(Comment comment, string post_id)
    {
        int id = int.Parse(post_id); 

        if (ModelState.IsValid)
        {


            var post = db.Posts.FirstOrDefault(u => u.id == id);



            comment.post = post;

            db.Comments.Add(comment);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(comment);
    }
    //
    // GET: /Post/Details/5

     public ActionResult Details(int id = 0)
     {
         Post post = db.Posts.Find(id);
         if (post == null)
         {
             return HttpNotFound();
         }
         return View(post);
     }

here is Details.schtml 这是Details.schtml

  @model Blog.Models.Post

@{
ViewBag.Title = "Details";
}

  <h2>Details</h2>

<fieldset>
<legend>Post</legend>

<div class="display-label">
     @Html.DisplayNameFor(model => model.title)
</div>
<div class="display-field">
    @Html.DisplayFor(model => model.title)
</div>

<div class="display-label">
     @Html.DisplayNameFor(model => model.body)
</div>
<div class="display-field">
    @Html.DisplayFor(model => model.body)
</div>

@for (int i = 0; i <Model.comments.Count; i++)
{

     <div class="display-label">
     @Html.DisplayNameFor(model => model.comments[i].comment)
</div>

<div class="display-field">
    @Html.DisplayFor(model => model.comments[i].comment)

</div>
}

<h2>Comment</h2>

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Article</legend>

        <div class="editor-label">


            @Html.LabelFor(model =>model.comments[Model.comments.Count].comment)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model =>model.comments[Model.comments.Count].comment))
            @Html.ValidationMessageFor(model => model.comments[Model.comments.Count].comment)
        </div>


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

  </fieldset>

There is an error 发生错误

"Index was out of range. Must be non-negative and less than the size of the collection.\\r\\nParameter name: index" “索引超出范围。必须为非负数,并且小于集合的大小。\\ r \\ n参数名称:index”

how can I successfully add comments ? 如何成功添加评论?

The error itself pretty much explains the problem. 错误本身几乎可以解释问题。 On the line where you get the error the Model.comments.Count is out of the range. 在出现错误的行上, Model.comments.Count超出范围。 The indexation starts from 0 so the last comment should be retrieved this way .... model => model.comments[Model.comments.Count - 1].comment . 索引从0开始,因此应该以这种方式检索最后一条注释.... model => model.comments[Model.comments.Count - 1].comment

Your exception is generated by the following line in your view 您的异常是由视图中的以下行生成的

@Html.LabelFor(model =>model.comments[Model.comments.Count].comment)

and will also be generated by the subsequent EditorFor() and ValidationMessageFor() methods. 并且还将由后续的EditorFor()ValidationMessageFor()方法生成。

Collection indexers are zero based, whereas .Count() returns the number of items in the collection. 集合索引器从零开始,而.Count()返回集合中的项目数。 If say you collection contained 2 Comment , then you would access them as 如果说您的收藏集包含2条Comment ,则您可以按以下方式访问它们

model.Comments[0].comment
model.Comments[1].comment

but your [Model.comments.Count] equates to 但您的[Model.comments.Count]等于

model.Comments[2].comment

which throws the exception because your referring to the 3rd item in the collection (which does not exist). 抛出异常是因为您引用的是集合中的第三个项目(不存在)。 Even if you referred to an existing item in the collection, you code would fail because you would be posting back a collection (defined by the indexer) but you POST method only excepts a single object 即使您引用了集合中的现有项目,您的代码也会失败,因为您将回发一个集合(由索引器定义),但是您的POST方法仅适用于单个对象

It appears you wanting to add a new comment to the Post in which case you can either use a view model containing an additional property for Comment 似乎您想向Post添加新评论,在这种情况下,您可以使用包含附加Comment属性的视图模型

public Comment NewComment { get; set; }

and then in you view, generate the form controls using 然后在您查看的情况下,使用

@Html.EditorFor(m => m.NewComment.comment)

and change the POST method signature to 并将POST方法签名更改为

public ActionResult Details([Bind(Prefix = "NewComment")]Comment comment, int post_id)

Note the use of the Bind.Prefix property which is necessary to strip the "NewComment" prefix from the name/value pair posted to the method. 请注意Bind.Prefix属性的使用,这对于从张贴到该方法的名称/值对中删除"NewComment"前缀是必需的。 Note also that you can make the second parameter int and avoid the unnecessary conversion from string to int (although you do not appear to be generating a form control for property post_id so it will be null anyway). 还要注意,您可以将第二个参数设置为int ,避免不必要的从stringint转换(尽管您似乎没有为属性post_id生成表单控件,所以无论如何它将为null )。

An alternative would be to use @Html.Action() to call a child action method that returns a partial view (containing the form) based on a new Comment . 一种替代方法是使用@Html.Action()调用子操作方法,该方法将基于新的Comment返回部分视图(包含表单)。

It is because of db.Posts.Find(id); 这是因为db.Posts.Find(id); . you have given initial value for id in public ActionResult Details(int id = 0) . 您已在public ActionResult Details(int id = 0)为id赋予了初始值。 Check your code to be sure you always pass value to id. 检查您的代码,以确保始终将值传递给id。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM