Banoona
Banoona

Reputation: 554

WebApi Multiple-Action Routing not working with AngularJs Attribute-Based Routes

I am trying to get the following code to route to actions on a self-hosted WebApi controller (ResourcesController), but the routing will not route to the Delete method as well as the GetAllResources method. It works with only one method, but not with both. I am using Attribute-Based routing. Any help gladly accepted!

  1. Using the following Web-Api Self-Hosting startup code:

    using DomainEntities; using Owin; using WebApiContrib.Formatting.Jsonp;

    namespace ResourcesWebApiHost { public class Startup { public void Configuration(IAppBuilder app) { var webApiConfiguration = ConfigureWebApi(); app.UseWebApi(webApiConfiguration); }

        private HttpConfiguration ConfigureWebApi()
        {
            var config = new HttpConfiguration();
            var corsAttr = new EnableCorsAttribute("http://localhost:5000/", "*", "*");
            config.Formatters.Insert(0, new JsonpMediaTypeFormatter(new JsonMediaTypeFormatter()));
            config.EnableCors();
            config.Filters.Add(new CrossDomainAccessFilter());
            config.MapHttpAttributeRoutes();
            return config;
        }
    
        public class CrossDomainAccessFilter : ActionFilterAttribute
        {
            public override void OnActionExecuting(HttpActionContext actionContext)
            {
                var routes = actionContext.Request.GetRouteData();
                base.OnActionExecuting(actionContext);
            }
    
            public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
            {
                if (actionExecutedContext.Response.Content != null)
                {
                    actionExecutedContext.Response.Content.Headers.Add("Access-Control-Allow-Origin", "null");
                    actionExecutedContext.Response.Content.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
                    actionExecutedContext.Response.Content.Headers.Add("Access-Control-Allow-Headers","Content-Type, X-Requested-With");
                }
            }
        }
    }
    

    }

  2. Using the following Controller:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Runtime.InteropServices.ComTypes;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web.Http;
    using DomainEntities;
    using Interfaces;
    using ResourceManagerService;
    
    namespace ResourcesWebApiHost
    {
    
    
    public class ResourcesController : ApiController
    {
        [Route("api/Resources/GetAllResources")]
        [HttpGet]
        public List<Resource> GetAllResources()
        {
            var service = new Service();
            return service.GetAllResources();
        }
    
        [ActionName("api/Resources/Delete")]
        [HttpPost]
        public HttpResponseMessage Delete(List<Resource> resources)
        {
            var service = new Service();
            var success = service.Delete(resources);
            var result = Request.CreateResponse(HttpStatusCode.OK,                  success.ToString());
            return result;
        }
    }
    

    }

  3. Using the following AngularJs code:

    var appUrl = "http://localhost:5001/api/Resources"; var model = {};

        var resourcesApp = angular.module("resourcesApp", []);
    
        resourcesApp.run(function ($http) {
            $http.defaults.headers.put = {
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
                'Access-Control-Allow-Headers': 'Content-Type, X-Requested-With'
            };
            $http.defaults.useXDomain = true;
    
            $http.get('http://localhost:5001/api/Resources/GetAllResources').success(function (data) {
                model.resources = data;
            }).error(function (data, status) {
                alert('ERROR ' + (data || 'No Error Description'));
            });
        });
    
        resourcesApp.filter("selectedItems", function () {
            return function (items) {
                var resultArr = [];
                angular.forEach(items, function (item) {
                    if (item.mustDelete == true) {
                        resultArr.push(item);
                    }
                });
                return resultArr;
            }
        });
    
        resourcesApp.controller("resourcesCtrl", function ($scope, $http) {
            $scope.theModel = model;
            $scope.close = function () {
                window.close();
            }
            $scope.deleteSelectedItems = function () {
                $http.defaults.useXDomain = true;
                $http.post('http://localhost:5001/api/Resources/Delete', $scope.theModel.resources);
            }
        });
    </script>
    

Upvotes: 0

Views: 422

Answers (1)

Banoona
Banoona

Reputation: 554

The problem was solved by adding the [EnableCors(origins: "", headers: "", methods: "*")] header to my controller class. The new code looks as follows:

namespace ResourcesWebApiHost
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class ResourcesController : ApiController
    {//...more code follows...

I was using CORS for cross-origin requests, but I implemented only the configuration part - I omitted to add the attribute to the class, which completes the enable-CORS implementation.

For further information, this problem concerns the ASP.Net WebApi routing system, and has nothing to do with the AngularJS code.

Upvotes: 0

Related Questions