DELETE localhost/ API not found, MVC - c#

I made a web API from Entity framework and then I tried to make a DELETE call so I can delete stuff from my jquery datatable through AJAX. I'm getting an error that DELETE localhost/ api is not found. Here is my code.
#section scripts{
<script>
$(document).ready( function () {
var table = $('#myTable').DataTable();
$("#myTable .js-delete").on("click", function () {
var button = $(this);
//bootbox.confirm("Do you want to delete this movie?", function (result) {
//if (result) {
$.ajax({
url: "/api/FriendApi/" + button.attr("data-friend-id"),
method: "DELETE",
success: function () {
table.row(button.parents("tr")).remove().draw();
}
});
//}
//});
})
} );
</script>
}
This is my web api
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace WebApplication2
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
ApiController
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.Web.Http;
using System.Web.Http.Description;
using WebApplication2.Models;
namespace WebApplication2.Controllers
{
public class FriendApiController : ApiController
{
private FriendContext db = new FriendContext();
// GET: api/FriendApi
public IQueryable<FriendModel> Getfriends()
{
return db.friends;
}
// GET: api/FriendApi/5
[ResponseType(typeof(FriendModel))]
public IHttpActionResult GetFriendModel(int id)
{
FriendModel friendModel = db.friends.Find(id);
if (friendModel == null)
{
return NotFound();
}
return Ok(friendModel);
}
// PUT: api/FriendApi/5
[ResponseType(typeof(void))]
public IHttpActionResult PutFriendModel(int id, FriendModel friendModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != friendModel.Id)
{
return BadRequest();
}
db.Entry(friendModel).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!FriendModelExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
// POST: api/FriendApi
[ResponseType(typeof(FriendModel))]
public IHttpActionResult PostFriendModel(FriendModel friendModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.friends.Add(friendModel);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = friendModel.Id }, friendModel);
}
// DELETE: api/FriendApi/5
[ResponseType(typeof(FriendModel))]
[Route("FriendModel/{id}")]
public IHttpActionResult DeleteFriendModel(int id)
{
FriendModel friendModel = db.friends.Find(id);
if (friendModel == null)
{
return NotFound();
}
db.friends.Remove(friendModel);
db.SaveChanges();
return Ok(friendModel);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool FriendModelExists(int id)
{
return db.friends.Count(e => e.Id == id) > 0;
}
}
}
Basically this is my WebApi and the Api I made myself (in this case I used Entity's framework Api). I wrote the same code like a week ago and it worked but now it doesn't work. I have no clue why.

Your C# code has:
[Route("FriendModel/{id}")]
But your script is requesting:
DELETE /api/FriendApi/{id}
Spot the difference!

Related

How do i get along with this webapi project error?

Im making a WebApi core project for school and everything seemed fine until i decided to start up the project to test it. When I start it up this error appears https://imgbbb.com/images/2020/01/16/error.png
Here's everything that my project consists of:
And here's the controller code:
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using webapi3.Models;
using webapi3.Models.Repository;
using RouteAttribute = Microsoft.AspNetCore.Components.RouteAttribute;
namespace webapi3.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class EmployeeController : ControllerBase
{
private readonly IDataRepository<Employee> _dataRepository;
public EmployeeController(IDataRepository<Employee> dataRepository)
{
_dataRepository = dataRepository;
}
// GET: api/Employee
[HttpGet]
public IActionResult Get()
{
IEnumerable<Employee> employees = _dataRepository.GetAll();
return Ok(employees);
}
// GET: api/Employee/5
[HttpGet("{id}", Name = "Get")]
public IActionResult Get(long id)
{
Employee employee = _dataRepository.Get(id);
if (employee == null)
{
return NotFound("The Employee record couldn't be found.");
}
return Ok(employee);
}
// POST: api/Employee
[HttpPost]
public IActionResult Post([FromBody] Employee employee)
{
if (employee == null)
{
return BadRequest("Employee is null.");
}
_dataRepository.Add(employee);
return CreatedAtRoute(
"Get",
new { Id = employee.EmployeeId },
employee);
}
// PUT: api/Employee/5
[HttpPut("{id}")]
public IActionResult Put(long id, [FromBody] Employee employee)
{
if (employee == null)
{
return BadRequest("Employee is null.");
}
Employee employeeToUpdate = _dataRepository.Get(id);
if (employeeToUpdate == null)
{
return NotFound("The Employee record couldn't be found.");
}
_dataRepository.Update(employeeToUpdate, employee);
return NoContent();
}
// DELETE: api/Employee/5
[HttpDelete("{id}")]
public IActionResult Delete(long id)
{
Employee employee = _dataRepository.Get(id);
if (employee == null)
{
return NotFound("The Employee record couldn't be found.");
}
_dataRepository.Delete(employee);
return NoContent();
}
}
}
If anyone helps me id be very gratheful! Thanks in advance!
Try changing [controller] to "Employee" in [Route("api/[controller]")]. Check this example from Microsoft 1
Replace [controller] with the name of the controller, which by convention is the controller class name minus the "Controller" suffix. For this sample, the controller class name is TodoItemsController, so the controller name is "TodoItems". ASP.NET Core routing is case insensitive.
Another option, check your Startup.cs file (post it here so we can check if everything is alright). And check this example explaining Attribute Route in .NET Attribute Routing
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}

View in areas cannot be located - Visual Studio 2015, C#, ASP.NET MVC 5

I've found many topic and suggestions on this and I think I've tried all of the combinations.
I had a working application that is going to grow larger so I decided to make use of areas. I sloughed through that and can access the controllers but then the application fails when it tries to return data to a view. I created a test data context, classes, etc. then to be sure that it wasn't something that I did wrong when moving into areas.
It's probably best to work through the somewhat smaller test situation and then apply what works to the larger actual application.
My link from _Layout.cshtml:
<li>#Html.ActionLink("Test", "Index", "testclasses")</li>
My model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Tracking.Areas.test.Models
{
public class testclass
{
public int ID { get; set; }
}
}
My testAreaRegistration:
using System.Web.Mvc;
namespace Tracking.Areas.test
{
public class testAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "test";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"test_default",
//"test/{controller}/{action}/{id}",
"test/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
}
My test controller:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Tracking.Areas.test.Models;
using Tracking.DAL.Test;
namespace Tracking.Areas.test.Controllers
{
[RouteArea("test")]
public class testclassesController : Controller
{
private testcontext db = new testcontext();
// GET: test/testclasses
public async Task<ActionResult> Index()
{
return View(await db.spas.ToListAsync());
}
// GET: test/testclasses/Details/5
public async Task<ActionResult> Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
testclass testclass = await db.spas.FindAsync(id);
if (testclass == null)
{
return HttpNotFound();
}
return View(testclass);
}
// GET: test/testclasses/Create
public ActionResult Create()
{
return View();
}
// POST: test/testclasses/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "ID")] testclass testclass)
{
if (ModelState.IsValid)
{
db.spas.Add(testclass);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(testclass);
}
// GET: test/testclasses/Edit/5
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
testclass testclass = await db.spas.FindAsync(id);
if (testclass == null)
{
return HttpNotFound();
}
return View(testclass);
}
// POST: test/testclasses/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "ID")] testclass testclass)
{
if (ModelState.IsValid)
{
db.Entry(testclass).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(testclass);
}
// GET: test/testclasses/Delete/5
public async Task<ActionResult> Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
testclass testclass = await db.spas.FindAsync(id);
if (testclass == null)
{
return HttpNotFound();
}
return View(testclass);
}
// POST: test/testclasses/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteConfirmed(int id)
{
testclass testclass = await db.spas.FindAsync(id);
db.spas.Remove(testclass);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
My RouteConfig file
namespace Tracking
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
My Global.asax.cs file
namespace Tracking
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
I've tried with and without [RouteArea("test")] in the controller; I've tried multiple options with adding a controller to the area registration file, removing the area name from in front of controller in the area registration file, and many other combinations.
The code finds the controller and model as I put breakpoints in those and reach them - when it attempts to return the view I get the error message about the index view not being found in the standard locations - it doesn't search within the areas at all.
Thanks!
I think you have an inconsistence in your "convention over configuration" setup. Might be helpful to add the error message and your solution structure. You should check, for example, that the Index.cshtml is found in the Areas\test\Views\testclasses folder. The only thing that I see at a first glance is that you didn't modify your action link to include the area. You should try:
#Html.ActionLink("Test", "Index", "testclasses", new { Area = "test" }, new{})
P.S.> I would recommend using camel case notation for the class names and areas... you know, for the clean code sake. Not to mention that you never know when you might stumble upon a case sensitive convention....

Repository bool to the view

I have:
GuestResponseRepository, IRepository -> Interface, HomeController -> Controlle, Thanks -> View
The GuestReresponseRepository has a list with responses in it. When I add a response via a form the response is added to the list. When you try to add a response for the second time with the same values the AddReponse method returns false. I want to use the bool in my view to display a different text. How can I do this? Below my code
GuestResponseRepository
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using PartyInvites.Abstract;
namespace PartyInvites.Models
{
public class GuestResponseRepository : IRepository
{
private static List<GuestResponse> responses = new List<GuestResponse>();
IEnumerable<GuestResponse> IRepository.GetAllResponses()
{
return responses;
}
bool IRepository.AddResponse(GuestResponse response)
{
if (responses.Any(x => x.Email == response.Email)) //here
{
if (responses.Any(x => x.WillAttend == response.WillAttend)) //here
{
return false;
}
var attend = responses.First(x => x.Email == response.Email && x.WillAttend != response.WillAttend);
attend.WillAttend = response.WillAttend;
return true;
}
responses.Add(response);
return true;
}
}
}
IRepository
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PartyInvites.Models;
namespace PartyInvites.Abstract
{
public interface IRepository
{
IEnumerable<GuestResponse> GetAllResponses();
bool AddResponse(GuestResponse response);
}
}
Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PartyInvites.Models;
using PartyInvites.Abstract;
namespace PartyInvites.Controllers {
public class HomeController : Controller {
private IRepository repository;
public HomeController(IRepository iRepository)
{
this.repository = iRepository;
}
public ViewResult Index() {
return View(repository.GetAllResponses());
}
public ViewResult PartyPeople()
{
return View(repository.GetAllResponses());
}
[HttpGet]
public ViewResult RsvpForm() {
return View();
}
[HttpPost]
public ViewResult RsvpForm(GuestResponse guestResponse) {
if (ModelState.IsValid) {
repository.AddResponse(guestResponse);
return View("Thanks", guestResponse);
}
else
{
// there is a validation error
return View();
}
}
}
}
view
#model PartyInvites.Models.GuestResponse
#{
ViewBag.Title = "Thanks";
}
<div class="text-center">
<h1>Thank you, #Model.Name!</h1>
<div class="lead">
#if (Model.WillAttend == true) {
#:It's great that you're coming. The drinks are already in the fridge!
} else {
#:Sorry to hear that you can't make it, but thanks for letting us know.
}
#if (bool from Addresponse is false) {
#:<p>You already submitted this response. Are you sure this is right?</p>
}
</div>
Link naar pp
</div>
Capture the return from AddResponses in a boolean variable and set a custom property in the ViewBag object
bool result = repository.AddResponse(guestResponse);
ViewBag.Response = result;
return View("Thanks", guestResponse);
Now in the Thanks view you can use this property to decide which text to write
#model PartyInvites.Models.GuestResponse
#{
ViewBag.Title = "Thanks";
bool response = (ViewBag.Response != null ? Convert.ToBoolean(ViewBag.Response) : false);
}
.....
#if (!response) {
#:<p>You already submitted this response. Are you sure this is right?</p>
}

CRUD operations in MVC 3 without using db context

I need help .Actually am using ADO net with 4.0 .net framework and create a own database using app_data in solution explorer with .mdf extension.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Crudoperations.Models;
using System.Data.Entity;
namespace Crudoperations.Controllers
{
public class EmployeeController : Controller
{
//
// GET: /Employee/
EmployEntities employContext;
public ActionResult Index()
{
using (var details= new EmployEntities())
{
return View(details.employs.ToList());
}
}
//
// GET: /Employee/Details/5
public ActionResult Details(int id)
{
employContext = new EmployEntities();
employ _TempEmploy = new employ();
_TempEmploy.Id = id;
return View(_TempEmploy);
}
//
// GET: /Employee/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Employee/Create
[HttpPost]
public ActionResult Create(employ objEmploy)
{
try
{
employContext = new EmployEntities();
employContext.AddToemploys(objEmploy);
employContext.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
public ActionResult Edit(int id)
{
employContext = new EmployEntities();
employ _employ = new employ();
//_employ = ( from Employ
// where ID = id)
return View();
}
[HttpPost]
public ActionResult Edit(int id, employ objEmploy)
{
try
{
return RedirectToAction("Index");
}
catch
{
return View();
}
}
//
// GET: /Employee/Delete/5
public ActionResult Delete(int id)
{
employ _TempEmploy = new employ();
return View(_TempEmploy);
}
//
// POST: /Employee/Delete/5
[HttpPost]
public ActionResult Delete(int id, employ objEmploy)
{
try
{
//employContext = new EmployEntities();
//employ _TempEmploy = new employ();
//_TempEmploy.Id = id;
//employ _employ = employContext.Find(_TempEmploy);
employContext.DeleteObject(objEmploy);
employContext.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return RedirectToAction("Delete", new { id = id, saveChangesError = true });
}
}
public IView detailsModel { get; set; }
}
}
Actually i'm getting problem in accessing the data using ID i.e in db context there is a method "Find(id)" but there is no such type of method in Object context.what i have to do for accessing the data for edit ,details and Delete the data from database
you can use FirstOrDefault() for fetching by id, It will fetch the first matching object.
db.Users.FirstOrDefault(x => x.UserId== Id);
Hope, it may help you. Have anice day.

The resource cannot be found MVC 4

I'm working on Visual Studio, MVC.
I generated an ADO model, created a new controller with this model and changed the route but my controller seem inusable, even if i try to redirect from another controller.
My controller :
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Garnak.Models;
namespace Garnak.Views
{
public class leIndex : Controller
{
private garnakEntities db = new garnakEntities();
//
// GET: /leIndex/
public ActionResult Index()
{
return View(db.compteSet.ToList());
}
//
// GET: /leIndex/Details/5
public ActionResult Details(int id = 0)
{
compteSet compteset = db.compteSet.Find(id);
if (compteset == null)
{
return HttpNotFound();
}
return View(compteset);
}
//
// GET: /leIndex/Create
public ActionResult Create()
{
return View();
}
//
// POST: /leIndex/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(compteSet compteset)
{
if (ModelState.IsValid)
{
db.compteSet.Add(compteset);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(compteset);
}
//
// GET: /leIndex/Edit/5
public ActionResult Edit(int id = 0)
{
compteSet compteset = db.compteSet.Find(id);
if (compteset == null)
{
return HttpNotFound();
}
return View(compteset);
}
//
// POST: /leIndex/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(compteSet compteset)
{
if (ModelState.IsValid)
{
db.Entry(compteset).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(compteset);
}
//
// GET: /leIndex/Delete/5
public ActionResult Delete(int id = 0)
{
compteSet compteset = db.compteSet.Find(id);
if (compteset == null)
{
return HttpNotFound();
}
return View(compteset);
}
//
// POST: /leIndex/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
compteSet compteset = db.compteSet.Find(id);
db.compteSet.Remove(compteset);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
My route :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace Garnak
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "leIndex", action = "Index", id = UrlParameter.Optional }
);
}
}
}
Any idea why Visual studio say me that the ressource cannot be found ?
ASP.NET MVC's controller factory, follows a naming convention that your controllers should follow it -by default. You can change it by creating your own factory, but for now, change
public class leIndex : Controller { ... }
to
public class leIndexController : Controller { ... }

Categories

Resources