0

I am trying to pass an integer and string parameters from an AngularJS client to an ASP.NET Web API server, without using a POCO class to wrap the parameters in. I've tried the following:

The parameters I want to pass are "id", which is an integer, and "name", a string.

My AngularJS service looks like this:

function myResource($resource, myServerUrl) {

    return {
        testFunction: $resource(myServerUrl + "/api/testing/:id/:name/MethodB", null,
        {
            'get': { method: 'GET' }
        })
    };
}

The code in the AngularJS controller is the following:

var vm = this;

vm.testFunction = function (Id, Name) {
        myResource.testFunction.get({ id: Id, name: Name },
            function(response) {
                // Do something
            },

            // Handles errors
            function(error) {
                // Process error
            });
    }

And finally, the Web API controller:

[RoutePrefix("api/testing")]
public class MyController : ApiController
{
    // This is NOT the method I am using for hit example.
    // It's a different one with a similar signature
    // so I am showing it here just in case it has
    // impact on what I am trying to do.
    [Authorize]
    [Route("{name}/{id:int}/MethodA")]
    public IHttpActionResult GetData(string name, int id)
    {
        // Do something
    }

    // This is the method I am using for this example
    [Authorize]
    [Route("{id:int}/{name}/MethodB")]
    public IHttpActionResult MyTestMethod(int id, string name)
    {
        // Do something
    } 

}

When I try to run the above code, I get the following error:

{"message":"The requested resource does not support http method 'GET'."}

If I change the code to use POST instead of GET, i.e.:

testFunction: $resource(myServerUrl + "/api/testing/:id/:name/MethodB", null,
        {
            'get': { method: 'POST' }
        })

and

    // This is the method I am using for this example
    [Authorize]
    [HttpPost]
    [Route("{id}/{name}/MethodB")]
    public IHttpActionResult MyTestMethod(int id, string name)
    {
        // Do something
    }

I get this:

{"message":"The requested resource does not support http method 'POST'."}

And if I modify my AngularJS service to not use colon in front of the parameters, i.e. this:

testFunction: $resource(myServerUrl + "/api/testing/id/name/MethodB", null,
        {
            'get': { method: 'POST' }
        })

I get this error instead:

{"message":"The request is invalid.","messageDetail":"The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Http.IHttpActionResult MyTestMethod(Int32, System.String)' in 'MyController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."}

What is the problem here? How can I pass an integer and a string from AngularJS to a Web API controller, without using a POCO class? I am aware I can wrap both parameters in a value object and pass it that way to the Web API, but that's unnecessary complexity for me at this point. There should be a simple way to do this.

I've done this with two or three integer parameters without a problem, but for some reason an integer and a string is not working. Any advice on this would be appreciated. It's one of those things that should be simple to do, but apparently it's not.

10
  • Test your API isolated with Postman, to ensure Backend works fine Commented Sep 18, 2017 at 19:52
  • This is an API that has been in production for years. I just added this new method, MyTestMethod, for my particular scenario. I don't think the API is the problem. It has to be something with the way I am calling it, or possibly the way I am defining the route above method MyTestMethod. Commented Sep 18, 2017 at 19:55
  • Also, what about the more general question, how would you pass an integer and a string from AngularJS to a Web API? Commented Sep 18, 2017 at 19:56
  • For Post I do like this public IHttpActionResult MyTestMethod([FromBody]int id) Commented Sep 18, 2017 at 20:00
  • @CryingFreeman I tried that, but it didn't work for me. Could you give a code sample (consisting of Angular JS controller, AngularJS resource, and a Web API controller)? Commented Sep 18, 2017 at 21:03

2 Answers 2

1

Ok here's an example where I passed an object from controller to service, and the service uses $resource

var navApp = angular.module('navApp', [
    'ngResource',
    'ui.bootstrap',
    'ngAnimate'    
]);


navApp.controller('menuController', [
    '$scope',
    'navSectionList',
    'navGetCategories',

    function ($scope, navSectionList, navGetCategories) {
        $scope.navSectionList = navSectionList.query();
        $scope.getSectionID = function (event) {
            $scope.navGetCategories = navGetCategories
                .getResource([event])
                .query();
        };
    }
]);

navApp.factory('navSectionList', [
    '$resource',
    function ($resource) {
        return $resource('/api/navigation/section/list', {}, {
            query: { method: 'GET', params: {}, isArray: true }
        });
    }
]);

navApp.factory('navGetCategories', [
    '$resource',
    function ($resource) {
        var service = {
            getResource: function (sectionID) {
                return $resource('/api/navigation/category/' + sectionID, {}, {
                    query: { method: 'GET', params: {}, isArray: true }
                });
            }
        };
    return service; 
    }
]);

getSectionID kept passing undefined to navGetCategories.getResource() until I put event into a box [event].

I still don't really know why it wouldn't work without the square brackets, maybe someone else can explain why.

Sign up to request clarification or add additional context in comments.

1 Comment

Interesting, so you can actually pass values of parameters in a $resource service. That is kind of what I was looking for, although I did solve my problem yesterday in a different way. What I found out was that my Web API method ('MyTestMethod' above) wasn't being found because of the other method in the same class with a similar signature. Once I moved it into its own, new Web API controller and changed the route to something unique, things started working.
1

well, I do it this way

Server

[HttpGet]
        [Route("Api/Account/GetPasswordReset")]
        public dynamic GetPasswordReset(string UserName, string OldPassword, string NewPassword)
        {}

Client

$http({
            method: "GET",           
            url: CTHelper.ApiUrl() + '/Api/Account/GetPasswordReset?UserName=' + CTHelper.UserName()
                + '&OldPassword=' + $scope.CurrentPassword + '&NewPassword=' + $scope.NewPassword,
        }).then(function mySuccess(response) {

        }, function myError(response) {
             });

1 Comment

Your example uses the $http directive. I want to use $resource.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.