Reputation: 1515
I hope you guys can help me.
I have a simple project still in its infancy, but cannot get the AngularJS Controller (ingredientAdmin.controller) to find my C# API controller.
I get an Error: 404 / Not Found: Request URL: http://localhost:31021/api/ingredientAdmin/PostIngredient/
My AngularJS controller and C# controller is in different projects, and I have referenced my C# controller project in my AngularJS project.
I have also tried various spellings etc., but think I might be missing something.
Here is my AngularJS controller: ingredientAdminController:
(function () {
"use strict";
var controllerId = 'admin';
angular
.module('app.ingredientAdmin')
.controller('ingredientAdminController', ingredientAdminController, controllerId);
ingredientAdminController.$inject = ['$http', '$scope', 'common'];
function ingredientAdminController($http, $scope, common) {
var vm = $scope;
vm.formSubmmision = true;
vm.title = 'Ingredients Admin';
vm.ingredientData = null;
vm.save = save;
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
activate();
function activate() {
common.activateController([], controllerId)
.then(function () { log('Activated Admin View'); });
}
// Save
function save() {
if (vm.formIngredientsAdmin.$valid) {
postNewData();
}
else {
logger.error('Error: Validation failed. Please correct data and try again');
vm.formSubmmision = false;
}
}
function postNewData() {
//prepare data
var data = {
IngredientId: 0,
IngredientName: vm.NewIngredient.IngredientName,
IngredientDescription: vm.NewIngredient.IngredientDescription
}
$http.post('/api/ingredientAdmin/PostIngredient/', data)
.then(postDataComplete)
.catch(getDataFailed);
function postDataComplete(response) {
vm.NewIngredient = null;
vm.formSubmmision = true;
vm.formIngredientsAdmin.$setPristine();
vm.formIngredientsAdmin.$setUntouched();
return vm.NewIngredient;
}
function getDataFailed(error) {
log('Failed to create new Ingredient ' + error.data.Message);
return;
}
}
};
}
)();
Here is my C# controller: IngredientAdminController:
using System.Net;
using System.Net.Http;
using System.Web.Http;
using RecipeManager.Models;
using RecipeManager.DTO;
using RecipeManger.Common;
namespace RecipeManager.Controllers.Api
{
public class IngredientAdminController : ApiController
{
private RecipeManager.DTO.IngredientAdminDTO dto = new IngredientAdminDTO();
[HttpPost]
public HttpResponseMessage PostIngredient(Ingredient ingredient)
{
try
{
CommandResult<Ingredient> result = dto.CreateIngredient(ingredient);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
catch (RecipeManagerException ex)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
}
}
//[Authorize(Roles = "Admin, SupportCallIndex")]
public HttpResponseMessage UpdateIngredient(Ingredient ingredient)
{
try
{
CommandResult<Ingredient> result = dto.UpdateIngredient(ingredient);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
catch (RecipeManagerException ex)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
}
}
[HttpPost]
//[Authorize(Roles = "Admin, SupportCallIndex")]
public HttpResponseMessage DeleteIngredient(Ingredient ingredient)
{
try
{
CommandResult<Ingredient> result = dto.DeleteIngredient(ingredient);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
catch (RecipeManagerException ex)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
}
}
public HttpResponseMessage GetAll()
{
try
{
CommandResult<Ingredient> result = dto.ReadIngredient();
return Request.CreateResponse((result.Status == CommandStatus.Success ? HttpStatusCode.OK : HttpStatusCode.InternalServerError), result);
}
catch (RecipeManagerException ex)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
}
}
}
}
Here is my WebApiConfig code:
using System.Web.Http;
using Microsoft.Owin.Security.OAuth;
namespace RecipeManager.UI.Htmll5
{
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 }
);
}
}
}
This is the structure of my app skeleton:
Thank you greatly!
Upvotes: 1
Views: 1156
Reputation: 2364
You can add RoutePrefix and Route into your controller:
[RoutePrefix("api")]
public class IngredientAdminController : ApiController
{
private RecipeManager.DTO.IngredientAdminDTO dto = new IngredientAdminDTO();
[Route("PostIngredient")]
[HttpPost]
public HttpResponseMessage PostIngredient(Ingredient ingredient)
{
try
{
CommandResult<Ingredient> result = dto.CreateIngredient(ingredient);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
catch (RecipeManagerException ex)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
}
}
And your request:
var req = {
method: 'POST',
url: '/api/PostIngredient',
data: data
};
$http(req).then(function successCallback(responseSuccess) {
}, function errorCallback(responseError) {
});
hope it help.
Upvotes: 1
Reputation: 13248
If you want to keep your code as it currently is, then add this route before the default:
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
as mentioned by @Lex, added defaults for id
param.
Upvotes: 2
Reputation: 27874
WebApi / HttpPost has a few weird caveats about it.
See my answer (not question, but my answer) here:
Web api not supporting POST method
Note the Method on the Api Controller:
[System.Web.Http.HttpPost]
public MyOutputObject DoSomething([FromBody]MyInputObject args)
{
Console.Writeline(args.ToString());
}
Please note this article:
and this article
http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/
Upvotes: 1