Reputation: 154
I have created a WebAPI project which works fine when utilizing the DELETE and GET methods, but when I try to POST or PUT I receive
{"Value cannot be null.\r\nParameter name: entity"} on line 84, db.Reviews.Add(review)
I am using Postman to test and I've also tried using XMLHttpRequest but both methods work on GET/DELETE and fail on PUT/POST.
var update1 = new XMLHttpRequest();
var params = "ReviewID=123";
update1.open("POST", "http://localhost:49681/Api/Reviews/", true);
update1.setRequestHeader("Content-type", "application/json");
update1.send(params);
ReviewsController
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Description;
using ReviewApp.Models;
namespace ReviewApp.Controllers
{
public class ReviewsController : ApiController
{
private CheetahEntities db = new CheetahEntities();
// GET: api/Reviews
public IQueryable<Review> GetReviews()
{
return db.Reviews;
}
// GET: api/Reviews/5
[ResponseType(typeof(Review))]
public async Task<IHttpActionResult> GetReview(string id)
{
Review review = await db.Reviews.FindAsync(id);
if (review == null)
{
return NotFound();
}
return Ok(review);
}
// PUT: api/Reviews/5
[ResponseType(typeof(void))]
public async Task<IHttpActionResult> PutReview(string id, Review review)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != review.ReviewID)
{
return BadRequest();
}
db.Entry(review).State = EntityState.Modified;
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ReviewExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
// POST: api/Reviews
[ResponseType(typeof(Review))]
public async Task<IHttpActionResult> PostReview(Review review)
{
/*
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
*/
db.Reviews.Add(review);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (ReviewExists(review.ReviewID))
{
return Conflict();
}
else
{
throw;
}
}
return CreatedAtRoute("DefaultApi", new { id = review.ReviewID }, review);
}
// DELETE: api/Reviews/5
[ResponseType(typeof(Review))]
public async Task<IHttpActionResult> DeleteReview(string id)
{
Review review = await db.Reviews.FindAsync(id);
if (review == null)
{
return NotFound();
}
db.Reviews.Remove(review);
await db.SaveChangesAsync();
return Ok(review);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool ReviewExists(string id)
{
return db.Reviews.Count(e => e.ReviewID == id) > 0;
}
}
}
Review
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ReviewApp.Models
{
using System;
using System.Collections.Generic;
public partial class Review
{
public string ReviewID { get; set; }
public string ReviewStatus { get; set; }
public Nullable<System.DateTime> Date { get; set; }
public string Account { get; set; }
}
}
CheetahEntities
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ReviewApp.Models
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class CheetahEntities : DbContext
{
public CheetahEntities()
: base("name=CheetahEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Review> Reviews { get; set; }
}
}
Upvotes: 1
Views: 1497
Reputation: 247631
In the request you have the content type as application/json
but send your params
with ReviewId=123
which is not json. params
should be properly formatted JSON object if you are sending Content-Type
as application/json
.
var update1 = new XMLHttpRequest();
var params = JSON.stringify({ ReviewID : 123 }); //JSON payload
update1.open("POST", "http://localhost:49681/Api/Reviews/", true);
update1.setRequestHeader("Content-type", "application/json");
update1.send(params);
In your PostReview
method there is the potential for review
variable to be null
if the POST
request was not properly sent but there was no check of the variable before trying to add it to the database. You commented out the validation check on the model.
// POST: api/Reviews
[ResponseType(typeof(Review))]
public async Task<IHttpActionResult> PostReview(Review review) {
if (review == null) ModelState.AddModelError("", "invalid data");
if (!ModelState.IsValid) {
return BadRequest(ModelState);
}
db.Reviews.Add(review);
try {
await db.SaveChangesAsync();
} catch (DbUpdateException) {
if (ReviewExists(review.ReviewID)) {
return Conflict();
} else {
throw;
}
}
return CreatedAtRoute("DefaultApi", new { id = review.ReviewID }, review);
}
Upvotes: 2