1

Web API not populating parameter object After researching a number of articles (most specifically: Complex type is getting null in a ApiController parameter but others as well) I have arrived at the following code to pass an object parameter from an AngularJS $Resource factory to ASP.NET Web API (C#) controller. (ultimately the search object will be more complex, but I have reduced the number of properties for simplicity)

The Model:

public class SearchModel
{
    public long ClientId { get; set; }
    public string EmployeeName { get; set; }
    public string FromDate { get; set; }
    public string ToDate { get; set; }
}

The AngularJS Factory

(function () {
    'use strict';
    angular
        .module('mainApp')
        .factory('searchService', searchService);
    searchService.$inject = ['$resource', 'baseApiUrl'];

    function searchService($resource, baseApiUrl) {
        return $resource(baseApiUrl + "api/Search", null, {
            query: { method: "Get", url: baseApiUrl + "api/Search/Get:searchModel", params: { searchModel: '@searchModel' }, isArray: true }
        });
})
();

When executed this code results in this URI: https://localhost:44300/api/Search/Get?clientId=4&fromDate=3%2F1%2F2016&EmployeeName=Bob&toDate=3%2F30%2F2016

The request IS routed to the following SearchController:

[RoutePrefix("api/Search")]
public class SearchController : BaseController
{
//this c’tor contains all the necessary code to implement ninject bindings etc.
    public SearchController(…): base(…)
 {…}
 #if !DEBUG
    [Authorize]  //note: this allows me to execute from Fiddler w/o an auth token
 #endif
    [HttpGet]
    [Route("{searchModel}")]
    public IHttpActionResult Get([FromUri] SearchModel searchModel)
    {
        try
        {
           //Here is where I am breaking the execution to test the results:
           // search model “Is” (not null) but all properties of object ARE null strings or 0 (the long)
            var result = _searchQuery.Get(searchModel);
            return this.GetResult(result);
        }
        catch (Exception ex)
        {
            return InternalServerError(ex);
        }
    }
}

When I enter breakmode at the point noted above the immediate window tells me that the “Request” query string is complete as expected…

Why are my passed values NOT being populated in the SearchModel object of the controller.

[EDIT: after accepted answer I needed to add the angular controller to get to a working solution]

The Controller

(function () {
'use strict';

angular
    .module('mainApp')
    .controller('SearchController', SearchController);

SearchController.$inject = ['$filter', 'searchService'];

function SearchController($filter, searchService) {
    var vm = this;
    vm.searchModel = {
        fromDate: "3/1/2016",
        toDate: "3/30/2016",
        clientId: 4,
        employeeName: "Bob"
    }
    vm.data = searchService.query(vm.searchModel);
}})();

(note that 'next' I plan to use binding to populate these values...but that I expect to achieve easily...well except for the dates...)

8
  • I think you shouldn't have [Route("{searchModel}")] which would expect variable with name searchModel, It should be [Route("")] to make it working Commented Mar 30, 2016 at 19:23
  • yes, it does 'expect' the variable searchModel...that is what I want. The searchModel variable is, indeed, present...but not populated with the values from the URI as I am expecting...but not getting. Commented Mar 30, 2016 at 19:29
  • sorry to ask you again, but did you tried what I suggested? Commented Mar 30, 2016 at 19:32
  • can you try to change the object SearchModel to a dynamic type to see what is receiving the controller? because when an object remains empty on the controller side its because it cannot assign the values. i think it have something to do with the /Get you are using at the beginning of the query Commented Mar 30, 2016 at 19:37
  • @PankajParkar, yes just to be sure...I know I'm missing something here. Without that Route attribute the request is rejected with a 500 error. Commented Mar 30, 2016 at 19:38

1 Answer 1

3

If you want your query string parameters to bind to a complex object you will need to prefix each query parameter with the name of the parameter in your handling controller method.

In your case:

https://localhost:44300/api/Search/Get?searchModel.clientId=4&searchModel.fromDate=3%2F1%2F2016&searchModel.EmployeeName=Bob&searchModel.toDate=3%2F30%2F2016
Sign up to request clarification or add additional context in comments.

1 Comment

We have a winner...Thanks so much. Now please, how do I make sure that my Angular Controller, which calls the factory/service method serializes this correctly.. (I will edit in the controller code shortly)

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.