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.