0

I have two applications, one is a WebAPI application that just serves data. The other is an AngularJS application that gets that data. I'm having a problem with my WebAPI GET method.

I'm trying to use URL parameters to call the correct GET method. From what I understand is that AngularJS will create the URl query for me, and the WebAPI will look for the correct GET method with the correct parameters.

What I'm having trouble with is that my correct GET method is getting skipped by the WebAPI because it doesn't think that the parameters in the URL query match up to the request. It essentially removes/ignores the parameters in the GET method, but I already have a blank GET method. So I'm getting a Multiple actions were found that match the request: error.

This is how my WebAPI looks. Note that the second GET method needs an SearchParameters object which just has two fields. SearchVariable which is what to search for, and SearchTerm which is what field(column) to search for the variable in.

public class ProductsController : ApiController
{
    // GET: api/Products
    public IEnumerable<Product> Get()
    {
        var productRepository = new ProductRepository();
        return productRepository.Retrieve();
    }

    // GET: api/Products
    public IEnumerable<Product> Get(SearchParameters search)
    {
        var productRepository = new ProductRepository();
        var products = productRepository.Retrieve();
        if(search.SearchField == null)
        {
            return products;
        }
        IEnumerable<Product> result = null;
        // Search on a certain field for the search variable
        switch(search.SearchType)
        {
            case "Product Code":
                result =  products.Where(p => p.ProductCode.ToUpper().Contains(search.SearchField.ToUpper()));
                break;
            case "Product Name":
                result =  products.Where(p => p.ProductName.ToUpper().Contains(search.SearchField.ToUpper()));
                break;
        }
        return result;
    }
}

This is my Controller where I'm calling the WebAPI.

(function () {
    "use strict";
    var app = angular.module("productManagement")

    var ProductListCtrl = function($scope, productResource) {
        var vm = this;

        vm.searchCriteria = {
            searchVariable: null,
            searchTerm: "Product Name"
        };
        productResource.query(function (data) {
            vm.products = data;
        });

        $("#searchBtn").click(function () {
            productResource.query({ search: vm.searchCriteria }, function (data) 
{
                vm.products = data;
            });
        });
        $("#searchCategories li").click(function (e) {
            e.preventDefault();
            var selText = $(this).text();
            vm.searchCriteria.searchTerm = selText;
            $scope.$apply();
        });

    }
    app.controller("ProductListCtrl", ["$scope", "productResource", ProductListCtrl]);
}());

I set my searchCriteria object from a search box on the UI. This is how the UI looks like.

<div class="panel panel-primary"
 ng-controller="ProductListCtrl as vm">
<div class="panel-heading"
     style="font-size:large">
    <div class="span5" style="display: inline;">
        Product List
    </div>
    <div class="span2 pull-right" style="display: inline;">

        <label id="searchTerm" for="searchItem" style="font-size: large; font-weight: normal;">
            {{ vm.searchCriteria.searchTerm }} 
        </label>

        <input id="searchItem" type="search" style="color: #337ab7;" ng-model="vm.searchCriteria.searchVariable"/>
        <div class="btn-group btn-group-sm" style="vertical-align: top;">
            <button id="searchBtn" type="button" class="btn btn-default">Search</button>
            <button id="searchCategoryBtn" class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" role="button" >
                <i class="caret"></i>
            </button>
            <ul id="searchCategories" class="dropdown-menu" role="menu">
                <li><a href="#">Product Code</a></li>
                <li><a href="#">Product Name</a></li>
            </ul>
        </div>
    </div>
</div>

<div class="panel-body">
    <table class="table">
        <thead>
            <tr>
                <td><b>Product</b></td>
                <td><b>Code</b></td>
                <td><B>Available</b></td>
                <td><B>Price</b></td>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="product in vm.products">
                <td>{{ product.productName}}</td>
                <td>{{ product.productCode }}</td>
                <td>{{ product.releaseDate | date }}</td>
                <td>{{ product.price | currency }}</td>
            </tr>
        </tbody>
    </table>
</div>

Why is it that my WebAPI is skipping over my second GET method when the search parameter is clearly getting put on the URL in my Controller? The problem isn't about defining duplicate methods with the same name but different parameters. It's about the WebAPI skipping over the second GET method because it doesn't recognize the search parameter when looking to see if the search parameter in the URL matches with a search parameter in the methods.

The moment I change public IEnumerable<Product> Get(String search) to public IEnumerable<Product> Get(SearchParameters search), the error appears.

Jimenemex
  • 3,104
  • 3
  • 24
  • 56
  • Possible duplicate of https://stackoverflow.com/questions/11548254/asp-net-c-same-name-method-that-takes-different-argument-type?noredirect=1&lq=1 [ASP.net c#, Same name method that takes different argument type [duplicate]] – Stephen Vernyi Sep 19 '17 at 18:24
  • Possible duplicate of [ASP.net c#, Same name method that takes different argument type](https://stackoverflow.com/questions/11548254/asp-net-c-same-name-method-that-takes-different-argument-type) – Stephen Vernyi Sep 19 '17 at 18:25
  • Just make one method `IEnumerable Get(SearchParameters search = null)` and handle the null condition inside – codeMonkey Sep 19 '17 at 18:40

0 Answers0