具有“SelectedRating”键的ViewData项是类型 'System.Int32'但必须是'IEnumerable'类型。
当我尝试通过局部视图添加DropDownList时,这是我得到的错误。我试图跟随this solution,但由于我在编码方面的经验不足,我没有这样做。
这就是我的代码目前的样子:
[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);
}
//...
查看_RatingPartial
@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; }
答案 0 :(得分:1)
将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添加HiddenFor Helper并修改dropdownlist以从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 />
...
答案 1 :(得分:1)
错误的原因是RatingList
的值为null
(有关详细说明,请参阅The ViewData item that has the key 'XXX' is of type 'System.Int32' but must be of type 'IEnumerable')。
在您的情况下,您使用RenderPartial()
方法将模型传递给视图,而您没有设置属性RatingList
的值(RenderPartial
不会调用您的{{ 1}}方法。
您可以使用
解决错误public ActionResult Rating()
以便填充属性,但由于您已经有了GET方法,因此最好使用调用服务器方法的@{
var newRating = new xxxx.ViewModel.RateReviewVM
{
ReviewId = Model.Id,
RatingList = new SelectList(Enumerable.Range(1, 10))
};
Html.RenderPartial("_RatingPartial", newRating);
}
方法
RenderAction()
注意我假设您的方法实际上是@{ Html.RenderAction("Rating", yourControllerName, new { id = Model.Id }); }
,因为当前代码会抛出异常,因为public ActionResult Rating(Guid id)
未声明。
但是,由于POST方法返回的审核id
无效(应该如此),但这不会解决您的所有问题,但它与您当前的视图不同。它也会抛出异常,因为你没有重新填充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
无效,请根据其ID重新填充ModelState
的属性,并重新填充其ReviewVM
属性的RatingList
属性。或者,如果您希望允许用户为Review添加多个注释,请考虑使用对话框表单添加新注释并使用ajax发布表单。