Hi guys,
I am fairly new at MVC. Currently, I am trying to figure out how ASP.Net Web API 2 works. I have created 2 model classes and implemented the controllers using EF. I have also hosted the API on Azure. The problem when I test the API locally using IIS Express, I have no issues; everything works as expected, but when I hosted it and try to call action method from the controllers, I get an HTTP 500 error. Below is the code for my models and the controllers.
Student model
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ApiDemo.Models { public class Student { [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] public string Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Major { get; set; } public string Minor { get; set; } } }
Enrollment model
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ApiDemo.Models { public class Enrollment { [Key] public int Id { get; set; } public string Course { get; set; } public string Section { get; set; } public string Professor { get; set; } [ForeignKey("Student")] public string StudentId { get; set; } public virtual Student Student { get; set; } } }
StudentsController
using ApiDemo.Models; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using System.Net; using System.Web.Http; using System.Web.Http.Description; namespace ApiDemo.Controllers { public class StudentsController : ApiController { private StudentDbContext db = new StudentDbContext(); // GET: api/Students public IQueryable<Student> GetStudents() { return db.Students; } // GET: api/Students/5 [ResponseType(typeof(Student))] public IHttpActionResult GetStudent(string id) { Student student = db.Students.Find(id); if (student == null) { return NotFound(); } return Ok(student); } // PUT: api/Students/5 [ResponseType(typeof(void))] public IHttpActionResult PutStudent(string id, Student student) { if (!ModelState.IsValid) { return BadRequest(ModelState); } if (id != student.Id) { return BadRequest(); } db.Entry(student).State = EntityState.Modified; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!StudentExists(id)) { return NotFound(); } else { throw; } } return StatusCode(HttpStatusCode.NoContent); } // POST: api/Students [ResponseType(typeof(Student))] public IHttpActionResult PostStudent(Student student) { if (!ModelState.IsValid) { return BadRequest(ModelState); } db.Students.Add(student); try { db.SaveChanges(); } catch (DbUpdateException) { if (StudentExists(student.Id)) { return Conflict(); } else { throw; } } return CreatedAtRoute("DefaultApi", new { id = student.Id }, student); } // DELETE: api/Students/5 [ResponseType(typeof(Student))] public IHttpActionResult DeleteStudent(string id) { Student student = db.Students.Find(id); if (student == null) { return NotFound(); } db.Students.Remove(student); db.SaveChanges(); return Ok(student); } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } private bool StudentExists(string id) { return db.Students.Count(e => e.Id == id) > 0; } } }
EnrollmentsController
using ApiDemo.Models; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using System.Net; using System.Web.Http; using System.Web.Http.Description; namespace ApiDemo.Controllers { public class EnrollmentsController : ApiController { private StudentDbContext db = new StudentDbContext(); // GET: api/Enrollments public IQueryable<Enrollment> GetEnrollments() { return db.Enrollments; } //public IQueryable<Enrollment> GetEnrollments(string studentId) //{ // return db.Enrollments.Where(e => e.StudentId == studentId); //} // GET: api/Enrollments/5 [ResponseType(typeof(Enrollment))] public IHttpActionResult GetEnrollment(int id) { Enrollment enrollment = db.Enrollments.Find(id); if (enrollment == null) { return NotFound(); } return Ok(enrollment); } // PUT: api/Enrollments/5 [ResponseType(typeof(void))] public IHttpActionResult PutEnrollment(int id, Enrollment enrollment) { if (!ModelState.IsValid) { return BadRequest(ModelState); } if (id != enrollment.Id) { return BadRequest(); } db.Entry(enrollment).State = EntityState.Modified; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!EnrollmentExists(id)) { return NotFound(); } else { throw; } } return StatusCode(HttpStatusCode.NoContent); } // POST: api/Enrollments [ResponseType(typeof(Enrollment))] public IHttpActionResult PostEnrollment(Enrollment enrollment) { if (!ModelState.IsValid) { return BadRequest(ModelState); } db.Enrollments.Add(enrollment); db.SaveChanges(); return CreatedAtRoute("DefaultApi", new { id = enrollment.Id }, enrollment); } // DELETE: api/Enrollments/5 [ResponseType(typeof(Enrollment))] public IHttpActionResult DeleteEnrollment(int id) { Enrollment enrollment = db.Enrollments.Find(id); if (enrollment == null) { return NotFound(); } db.Enrollments.Remove(enrollment); db.SaveChanges(); return Ok(enrollment); } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } private bool EnrollmentExists(int id) { return db.Enrollments.Count(e => e.Id == id) > 0; } } }
DbContext
using System.Data.Entity; namespace ApiDemo.Models { public class StudentDbContext : DbContext { public DbSet<Student> Students { get; set; } public DbSet<Enrollment> Enrollments { get; set; } } }
Locally, when I execute .api/Students, I get the expected result (this is assuming that locahost can be anything. But my model is hosted athttp://apidemo.azurewebsites.net. So when I execute something likehttp://apidemo.azurewebsites.net/api/Enrollments, I get a 500 error. Can anyone please help me out?
Thanks, you are the best!