2016-09-30 81 views
0

具有'SelectedRating'键的ViewData项类型为 'System.Int32',但必须是'IEnumerable'类型的。MVC - DropDownList/PartialView问题 - “Viewdata有关键int .. ..必须是Iumeumerable ...”

这是我在尝试通过局部视图添加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

你的'RenderPartial()'只是初始化'RateReviewVM'的一个新实例,并且你没有填充该实例的'RatingList'属性(它的'null',因此是例外)。你为什么使用'RenderPartial()'?主视图中的模型是什么? –

+0

@StephenMuecke我认为这是适当的显示部分。我应该用什么来代替? – skylake

+0

您的GET方法建议在主视图中的模型已经是'RateReviewVM',那么'RenderPartial()'的意义何在。只要将'_RatingPartial.cshtml'部分的代码移动到'Rating.cshtml'文件中,并删除'RenderPartial()' –

回答

1

的原因错误是,RatingListnull(参见The ViewData item that has the key 'XXX' is of type 'System.Int32' but must be of type 'IEnumerable'进行了详细说明)。

在你的情况下,你使用RenderPartial()方法传递一个模型视图,你没有设置的属性RatingListRenderPartial值不打电话给你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发布该表单的对话框表单。

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行动创造一个viewbag数据如下

public ActionResult Details(Guid? id) 
{ 

    Review review = db.Reviews.Find(id); 
    ViewBag.RatingList = new SelectList(Enumerable.Range(1, 10)); 

    return View(review); 
} 

修改您的PartialView如下目标CreateRate行动,添加HiddenFor帮手ReviewId并修改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 /> 
... 
相关问题