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; }
错误的原因是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 />
...