首页 > 解决方案 > 如何正确地将 JSON 发布到多对一关系

问题描述

我有两个模型,电影和评论,它们有一对多的关系。您可以看到我在 Movie 中包含了评论的 ICollection,在 Review 中我添加了外键和导航属性。

public class Movie
{
    [Key]
    public int MovieId { get; set; }

    [Required]
    public string imdbId { get; set; }
    public string title { get; set; }
    //Navigational Properties
    public virtual ICollection<Genre> Genres { get; set; }
    public virtual ICollection<Review> Reviews { get; set; }
}
public class Review
{
    public int ReviewID { get; set; }
    public virtual Movie Movie { get; set; }

    public int goreRating { get; set; }
    public int shockRating { get; set; }
    public int jumpRating { get; set; }
    public int plotRating { get; set; }
    public int supernaturalRating { get; set; }
    public int starRating { get; set; }

}

我正在尝试将评论发布到我的控制器,但查看 Swagger 中预期的 JSON 格式,我的 JSON 看起来像这样:

{
  "reviewID": 0,
  "movie": {
    "movieId": 0,
    "imdbId": "string",
    "title": "string",
    "genres": [
      {
        "genreId": 0,
        "movies": [
          null
        ]
      }
    ],
    "reviews": [
      null
    ]
  },
  "goreRating": 0,
  "shockRating": 0,
  "jumpRating": 0,
  "plotRating": 0,
  "supernaturalRating": 0,
  "starRating": 0
}

我希望能够只发送评论数据和电影 ID。如果我尝试发送整个 JSON blob,我会收到类似"Value cannot be null. (Parameter 'key')"这样的错误。但是从 JSON 对象的格式和 JSON 中的附加评论数组来看,我知道我不合时宜。

我想知道如何发送这个 JSON 来创建一个有效的审查条目,链接到一个movieId,或者如果我的模型不正确,是否应该(以及如何)修改以获得所需的结果。

标签: jsonentity-frameworkasp.net-coreentity-framework-coreasp.net-core-mvc

解决方案


尝试创建一个 ViewModel(名为 ReviewViewModel),并使用它将数据从视图传递到控制器。然后,在控制器中,创建一个 Review Model 实例并根据 MoviedId 找到 Movie,然后根据 ReviewViewModel 和 Movie 设置 Reivew Model 值。代码如下:

public class ReviewViewModel
{
    public int ReviewID { get; set; } 
    public int MovieId{ get; set; }    // Movie Id, 
    public int goreRating { get; set; }
    public int shockRating { get; set; }
    public int jumpRating { get; set; }
    public int plotRating { get; set; }
    public int supernaturalRating { get; set; }
    public int starRating { get; set; }

}

查看页面:单击 Create 按钮时,使用 JQuery Ajax 将 ReviewViewModel 发送到控制器:

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    <script>
        $(function () {
            $("#btnCreate").click(function () { 
                var review = {};
                review.ReviewID = $("#ReviewID").val();
                review.MovieID = $("#MovieID").val();
                review.goreRating = $("#goreRating").val();
                review.shockRating = $("#shockRating").val();
                review.jumpRating = $("#jumpRating").val();
                review.plotRating = $("#plotRating").val();
                review.supernaturalRating = $("#supernaturalRating").val();
                review.starRating = $("#starRating").val();
                $.ajax({
                    url: "/Home/AddReview",
                    method: "Post",
                    data: review,
                    success: function (response) {
                        alert(response);
                    },
                    error: function (response) {
                        console.log("error");
                    }
                })

            });
        })
    </script>
}

控制器:

public IActionResult AddReview()
{
    return View();
}
[HttpPost]
public IActionResult AddReview(ReviewViewModel reviewViewModel)
{
    if (ModelState.IsValid)
    {
        //find the movie based on the reviewViewModel.MovieID
        // var movie = //_dbcontext.Movies.Where(c=>c.MovieID == reviewViewModel.MovieID).FirstOrDefault();

        var review = new Review();
        review.starRating = reviewViewModel.starRating;
        //review.Movie == movie //set the existing movie or create a new movie instance.

        //add review to database via dbcontext.
        //save changes.
    }
    return View();
}

截图如下:

在此处输入图像描述


推荐阅读