Reputation: 5228
I have a question.
I have a table of users. ID of user is a string
. I have GET that looks like that:
// GET: api/WatchedProduct
[HttpGet]
public IEnumerable<WatchedProduct> GetWatchedProduct(string id)
{
var productsList = id == String.Empty ?
db.WatchedProducts.Where(u => u.ApplicationUserId == id).ToList() :
db.WatchedProducts.Where(u => u.ApplicationUserId == loggedUserId).ToList();
return productsList;
}
When i call API in Postman, i get this response:
{
"message": "No HTTP resource was found that matches the request URI 'http://.../api/WatchedProduct'.",
"messageDetail": "No action was found on the controller 'WatchedProduct' that matches the request."
}
My question is, how to make GetWatchedProduct
method like when id
is int
(GetWatchedProduct(int? id)
) ? Is it possible to do the same with a string? I need another Get Method?
EDIT:
When i call my API with string param:
http://localhost.../api/WatchedProduct/StringidHere
It works, I want to have one method for GET in my controller. When String.Empty
and when i pass a string.
My RouteConfig.cs
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
//AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
EDIT2
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
/*var cors = new EnableCorsAttribute("http://localhost:4200", "*", "GET,POST,PUT,DELETE,OPTIONS");
cors.SupportsCredentials = true;
config.EnableCors(cors);*/
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
EDIT3:
For example, that method from another controller works:
// GET: api/Product/search?str=kaarol
[Route("search")]
public IEnumerable<Product> GetSearch(string str)
{
return db.Products.Where(p => p.Name.Contains(str)).ToList();
}
But in my case, i want to have one method to call /Api/Watched...
and with StringID
when i want to.
Upvotes: 1
Views: 2803
Reputation: 357
You can try something like this
public class WatchedProduct : ApiController
{
// GET: api/WatchedProduct
[HttpGet]
[Route("WatchedProduct")]
public IEnumerable<WatchedProduct> Get()
{
var context = Request.Properties["MS_HttpContext"] as HttpContext;
var id = context.Request.QueryString["id"];
var productsList = id == String.Empty ?
db.WatchedProducts.Where(u => u.ApplicationUserId == id).ToList() :
db.WatchedProducts.Where(u => u.ApplicationUserId == loggedUserId).ToList();
return productsList;
}
}
should work for both the cases as it satisfies both the routes.
Upvotes: 0
Reputation: 483
Normally your route works like GET /api/controllerName/
If you want to access it like GET /api/controllerName/customRoute
you need to Route your method.
// GET: api/WatchedProduct
[HttpGet]
[Route("WatchedProduct")]
public IEnumerable<WatchedProduct> GetWatchedProduct(string id)
{
var productsList = id == String.Empty ?
db.WatchedProducts.Where(u => u.ApplicationUserId == id).ToList() :
db.WatchedProducts.Where(u => u.ApplicationUserId == loggedUserId).ToList();
return productsList;
}
More info Microsoft docs here
If your controller name is WatchedProductController
then you dont need to specify it explicitly. What i am saying is:
public class WatchedProduct : ApiController
{
// GET: api/WatchedProduct
[HttpGet]
public IEnumerable<WatchedProduct> Get(string id)
{
var productsList = id == String.Empty ?
db.WatchedProducts.Where(u => u.ApplicationUserId == id).ToList() :
db.WatchedProducts.Where(u => u.ApplicationUserId == loggedUserId).ToList();
return productsList;
}
}
should works.
Upvotes: 4