MVC-DropDownList/PartialView问题-“;Viewdata具有关键字int..必须是IUnume

本文关键字:int 关键字 IUnume Viewdata PartialView 问题 MVC-DropDownList | 更新日期: 2023-09-27 18:09:32

具有关键字"SelectedRating"的ViewData项的类型为"System.Int32",但必须是"IEnumerable"类型。

这是我在尝试通过部分视图添加DropDownList时遇到的错误。我试图遵循这个解决方案,但由于我在编码方面的经验不足,不知何故我没能做到。

这就是我的代码目前的样子:

 [HttpGet]
    public ActionResult Rating()
    {
        RateReviewVM model = new RateReviewVM()
        {
            ReviewId = id,
            RatingList = new SelectList(Enumerable.Range(1, 10))
        };
        return View(model);
    }
     [HttpPost]
     public ActionResult Rating(RateReviewVM model) {
         if (!ModelState.IsValid)
         {                
            model.RatingList = new SelectList(Enumerable.Range(1, 10));
            return View(model);
         }
       //...

跟踪部分视图

@model xxxx.ViewModel.RateReviewVM
<h6>Rate the review</h6>
using (Html.BeginForm()) {
<div class="form-group">

    @Html.LabelFor(m => m.SelectedRating)
    @Html.DropDownListFor(m => m.SelectedRating, Model.RatingList, "-Please select-", new { @class = "form-control" })
    @Html.ValidationMessageFor(m => m.SelectedRating)
</div>
<button type="submit" class="btn btn-default submit">Rate</button>
    }
}

这就是我尝试显示_RatingPartial视图的方式

@{
    var newRating = new xxxx.ViewModel.RateReviewVM { ReviewId = Model.Id };
    Html.RenderPartial("_RatingPartial", newRating);
}

型号

    public class RateReviewVM {
            public System.Guid Id { get; set; }
            public System.Guid UserId { get; set; }
            public System.Guid ReviewId { get; set; }
            public bool HasLiked { get; set; }
            public Nullable<int> Rating { get; set; }
            public int SelectedRating { get; set; }
            public IEnumerable<SelectListItem> RatingList { get; set; }
     }

编辑:---

详细信息视图(主(

    @model xxxx.Review
    @{
        ViewBag.Title = "Details";
    }
    @*@{
        //var newRating = new xxxx.ViewModel.RateReviewVM { ReviewId = Model.Id };
        @Html.RenderPartial("_RatingPartial", newRating)
    }*@
    <h2>Details</h2>
    <div>
        <h4>Review</h4>
        <hr/>
        <dl class="dl-horizontal">
            <dt>
                @Html.DisplayNameFor(model => model.Title)
            </dt>
            <dd>
                @Html.DisplayFor(model => model.Title)
            </dd>
            <dt>
                @Html.DisplayNameFor(model => model.Description)
            </dt>
            <dd>
                @Html.DisplayFor(model => model.Description)
            </dd>
            @* and so on..  *@
        </dl>
    </div>
    <p>
        @Html.ActionLink("Back to List", "Index")
    </p>

控制器详情

            public ActionResult Details(Guid? id) {
            Review review = db.Reviews.Find(id);
            return View(review);
        }

详细信息的模型审查

        public System.Guid Id { get; set; }
        public System.Guid CreatorUserId { get; set; }
        [Required]
        public string Title { get; set; }
        [Required]
        public string Description { get; set; }
        public System.DateTime CreatedDate { get; set; }
        //etc - some irrelevant property        
        public virtual ICollection<RateReview> Users { get; set; }

MVC-DropDownList/PartialView问题-“;Viewdata具有关键字int..必须是IUnume

错误的原因是RatingList的值为null(有关详细解释,请参阅键为"XXX"的ViewData项的类型为"System.Int32",但必须为"IEnumerable"类型(。

在这种情况下,使用RenderPartial()方法将模型传递到视图,并且不设置属性RatingList的值(RenderPartial不调用public ActionResult Rating()方法。

你可以使用来解决这个错误

@{
    var newRating = new xxxx.ViewModel.RateReviewVM
    {
        ReviewId = Model.Id,
        RatingList = new SelectList(Enumerable.Range(1, 10))
    };
    Html.RenderPartial("_RatingPartial", newRating);
}

以便填充属性,但由于您已经有了GET方法,因此最好使用RenderAction()方法,它确实调用服务器方法

@{ Html.RenderAction("Rating", yourControllerName, new { id = Model.Id }); }

注意,我假设您的方法实际上是public ActionResult Rating(Guid id),因为当前代码会抛出异常,因为id没有声明。

然而,这并不能解决所有的问题,因为POST方法返回的评审是ModelState无效的(应该是这样(,但它与您当前的视图不同。它还会抛出一个异常,因为您没有重新填充RatingList属性。

解决此问题的正确方法是为Review创建一个视图模型,其中包含另一个用于注释的视图模型。

public class ReviewVM
{
    ... properties of review including property for collection of existing commnets
    public CommentVM Comment { get; set; } // for generating a new comment form
}

Review.cshtml视图中,添加用于生成新评论的表单,并将其发布回以ReviewVM为参数的方法。然后,如果ModelState无效,则根据其ID重新填充ReviewVM的属性,并重新填充其Comment属性的RatingList属性。或者,如果你想允许用户为一次评论添加多个评论,可以考虑一个添加新评论的对话框表单,并使用ajax发布该表单。

将ViewBag用于您的dropdrownlist,它也适用于partialView。然后你就不需要ViewModels了。您的模型类可以使用。

首先将CreateRate动作添加到Reviews控制器

 public ActionResult CreateRate(RateReview rate)
    {
        if (ModelState.IsValid)
        {
            rate.Id = Guid.NewGuid();
            db.RateReviews.Add(rate);
            db.SaveChanges();
            return RedirectToAction("Details", "Reviews", new { id = rate.ReviewId });
        }
        return View();
    }

修改Details操作以创建如下所示的可视包数据

public ActionResult Details(Guid? id)
{
    Review review = db.Reviews.Find(id);
    ViewBag.RatingList = new SelectList(Enumerable.Range(1, 10));
    return View(review);
}

按如下方式修改PartialView以针对CreateRate操作,为ReviewId添加HiddeFor Helper,并将dropdownloadfor修改为从ViewBag读取。我使用RateReview模型而不是您的ViewModel

@model WebApp.Models.RateReview

@using (Html.BeginForm("CreateRate", "Reviews")) 
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
    <h4>RateReview</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.HiddenFor(model => model.ReviewId)
    <div class="form-group">
        @Html.LabelFor(model => model.SelectedRating, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.SelectedRating, (ViewBag.RatingList as SelectList), new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.SelectedRating, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
}

最后你的Details视图很好:

@model WebApp.Models.Review
@{
ViewBag.Title = "Details";
}
@{
    var newRating = new WebApp.Models.RateReview { ReviewId = Model.Id };
    Html.RenderPartial("_RatingPartial", newRating);
}

<h2>Details</h2>
<div>
<h4>Review</h4>
<hr />
...