Web api interface works locally but not on Azure - asp.net

My case is very similar to this question, but since he did not get an answer I thought I'd throw some more input.
Everything works fine locally (on the VS embedded server). When I deploy to Azure, I get a 404 error accompanied by "No type was found that matches the controller named...".
However, when I load the routedebugger module the mapping seems ok even on Azure.
What can I do to debug that problem?
Thanks,
Alex
Edit: my routes are created this way:
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
};
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Edit 2: Here my controller class
public class EmployeeController : ApiController
{
// GET api/<controller>
public IEnumerable<Employee> Get()
{
using (var context = new nws())
{
return context.Employees;
}
}
// GET api/<controller>/5
public Employee Get(int id)
{
using (var context = new nws())
{
return context.Employees.FirstOrDefault(e => e.ID == id);
}
}
// GET api/<controller>/getbyatid/5
public Employee GetByAtId(string id)
{
using (var context = new nws())
{
return context.Employees.FirstOrDefault(e => e.AtUserID == id);
}
}
// POST api/<controller>
public void Post([FromBody]string value)
{
}
// PUT api/<controller>/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/<controller>/5
public void Delete(int id)
{
}
// GET api/<controller>/timebank/5
public int? GetTimeBank(string id)
{
using (var context = new nws())
{
var employee = context.Employees.FirstOrDefault(e => e.AtUserID == id);
if (employee != null)
return employee.GetTimeBank();
return null;
}
}
}

Switch the order of routes and try again.
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
};

Related

(asp.net) how to create calculation in rest api

Method: HttpPost
URL: api/Calculation/CalculratePlus/20/30
Result: 50
This is my code:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApiPostPlus",
routeTemplate: "api/{controller}/{action}/{id}/{id}",
defaults: new {
id = RouteParameter.Optional,
id2 = RouteParameter.Optional
});
}
This is my controller (I want fixing my controllers and making models). I have no idea...
// GET: api/Calculator/PostPlusValue/item/value2
public HttpResponseMessage PostPlusValue(int i, int y)
{
var response = Request.CreateResponse(HttpStatusCode.Created);
string url = Url.Link("DefaultApiPostPlus", new { id = i, id2 = y});
response.Headers.Location = new Uri(url);
return response;
}
Please let me help..
thx..
I am not sure what you want correctly but you can try this:
config.Routes.MapHttpRoute(
name: "DefaultApiPostPlus",
routeTemplate: "api/{controller}/{action}/{id1}/{id2}",
defaults: new
{
id1 = RouteParameter.Optional,
id2 = RouteParameter.Optional
});
then your action:
// POST: api/Values/PostPlusValue/item/value2
public HttpResponseMessage PostPlusValue(int id1, int id2)
{
var response = Request.CreateResponse(HttpStatusCode.Created);
response.Content = new StringContent((id1 + id2).ToString());
return response;
}

"Message":"The requested resource does not support http method 'GET'." error

I have configured routing like this:
config.Routes.MapHttpRoute(
name: "Sales",
routeTemplate: "api/{Sales}/{jsonresponce}",
defaults: new { controller = "Sales", action = "Postsomething" }
);
config.Routes.MapHttpRoute(
name: "User",
routeTemplate: "api/{User}/{GetDetails}",
defaults: new { controller = "User", action = "GetDetails" }
);
Here is my UserController:
public class UserController : ApiController
{
userservice objservice = new userservice();
[HttpGet]
public CustDetails GetDetails(string Username, string Password, string BillingFeedID)
{
CustDetails model = new CustDetails();
//checking for encrypted password
model.UserName = Username;
model.Password = Password;
model.BillingFeedID = BillingFeedID;
model = objservice.Login(model);
//taking merchant configuration data
var data = objservice.Getcustomerconfig(model.MerchantID, BillingFeedID);
model.LastPosBillID = data.LastPosBillID;
model.LastTimeStamp = data.LastTimeStamp;
model.SyncStatus = data.SyncStatus;
model.SynsTimeInterval = data.SynsTimeInterval;
model.DataSorce = data.DataSorce;
model.DataAuthentication = data.DataAuthentication;
model.DataBaseQuery = data.DataBaseQuery;
return model;
}
}
I also have a SalesController:
public class SalesController : ApiController
{
[HttpPost]
public async Task<HttpResponseMessage> PostSomething()
{
StringBuilder sb = new StringBuilder();
try
{
string jsonData = await Request.Content.ReadAsStringAsync();
// dynamic dataList = JArray.Parse(jsonData);
if (File.Exists(#"C:\MCarrots\Umairbills\Umairbills.json"))
File.Delete(#"C:\MCarrots\Umairbills\Umairbills.json");
File.Create(#"C:\MCarrots\Umairbills\Umairbills.json").Close();
File.WriteAllText(#"C:\MCarrots\Umairbills\Umairbills.json", jsonData);
return Request.CreateResponse(HttpStatusCode.OK, "OK");
}
catch (Exception ex)
{
File.WriteAllText(#"C:\MCarrots\mcarrots\Umairbills.json", ex.ToString());
return Request.CreateResponse(HttpStatusCode.NoContent, ex.ToString());
}
}
When I try to call the GetUserDetails action with this url:
http://localhost:42945/api/User/GetDetails?Username=kay001&Password=kay501&BillingFeedID=KF1
It is throwing this error:
"Message":"The requested resource does not support http method"
But the POST method in SalesController is working.
Your route templates seem off. I think they should be:
config.Routes.MapHttpRoute(
name: "Sales",
routeTemplate: "api/Sales/{action}",
defaults: new { controller = "Sales", action = "Postsomething" }
);
config.Routes.MapHttpRoute(
name: "User",
routeTemplate: "api/User/{action}",
defaults: new { controller = "User", action = "GetDetails" }
);
I changed the route templates so that the controller name is essentially hard-coded, and the action is a placeholder. The action can be left out in this case though, defaulting to GetDetails.

Unable to reach ASP.NET MVC Web Api endpoint

I am working on an ASP.NET MVC app. I am trying to create a basic API. I created my first Web API controller by right-clicking on Controllers, Add -> Controller... then choosing "Web API 2 Controller - Empty". In the controller code, I have the following:
namespace MyProject.Controllers
{
public class MyApiController : ApiController
{
public IHttpActionResult Get()
{
var results = new[]
{
new { ResultId = 1, ResultName = "Bill" },
new { ResultId = 2, ResultName = "Ted" }
};
return Ok(results);
}
}
}
When I run the app, I enter http://localhost:61549/api/myApi in the browser's address bar. Unfortunately, I get a 404. I'm just trying to create an API endpoint that returns a hard-coded set of JSON objects. I need this to test some client-side JavaScript. What am I doing wrong?
Here are how my routes are registered:
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Make sure that you have the WebApiConfig registration being called, possibly in the Global.asax Application_Start() method. Something like:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
You did not add method name at the end of call. Try this one:
http://localhost:61549/api/myapi/get
Try this approach
namespace MyProject.Controllers
{
public class MyApiController : ApiController
{
public IHttpActionResult Get()
{
var results = new List<ResultModel>
{
new ResultModel() {ResultId = 1, ResultName = "Bill"},
new ResultModel() {ResultId = 2, ResultName = "Ted"}
};
return Ok(results);
}
}
public class ResultModel
{
public int ResultId { get; set; }
public string ResultName { get; set; }
}
}
Api: http://localhost:61549/api/MyApi/get
Hope this helps.

Accessing Route Data in DelegatingHandler using MVC 4

I just Register these routes now how can I get Apikey value in WebApiKeyHandler.cs since it is not part of query string so I am getting null. Also guide me how I am validating keys is best practice for Web Api Project?
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi2",
routeTemplate: "api/v1/users/{apikey}/{controller}/{action}/",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/v1/users/{apikey}/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.MessageHandlers.Add(new WebApiKeyHandler()); // global message handler
}
WebApiKeyHandler.cs
public class WebApiKeyHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
string apikey = HttpUtility.ParseQueryString(request.RequestUri.Query).Get(Constants.API_KEY_QUERY_STRING);
if (string.IsNullOrWhiteSpace(apikey))
{
HttpResponseMessage response = request.CreateErrorResponse(HttpStatusCode.Forbidden, ErrorCodes.API_KEY_EMPTY_ERROR);
var tsc = new TaskCompletionSource<HttpResponseMessage>();
tsc.SetResult(response);
return tsc.Task;
}
else if (!ValidateKey(apikey))
{
HttpResponseMessage response = request.CreateErrorResponse(HttpStatusCode.Forbidden, ErrorCodes.API_KEY_INVALID_ERROR);
var tsc = new TaskCompletionSource<HttpResponseMessage>();
tsc.SetResult(response);
return tsc.Task;
}
else
{
return base.SendAsync(request, cancellationToken);
}
}
private static bool ValidateKey(string apiKey)
{
Guid key;
Guid.TryParse(apiKey, out key);
return new StAccountsDomainContext().ApiSubscriptions.Any(x => x.ApiKey == key && x.IsActive == true && !x.ApiIBlacklists.Any());
}
private static bool ValidateSecretKey(string apiKey, string secretKey)
{
Guid key1;
Guid.TryParse(apiKey, out key1);
Guid key2;
Guid.TryParse(secretKey, out key2);
return new StAccountsDomainContext().ApiSubscriptions.Any(x => x.ApiKey == key1
&& x.SecretKey == key2
&& x.IsActive == true
&& !x.ApiIBlacklists.Any());
}
}
You can use the GetRouteData() extension on HttpRequestMessage to get the route data. Example: request.GetRouteData().Values

WebAPI No action was found on the controller

I got an error - No action was found on the controller 'Action' that matches the request.
The url is http://localhost:37331/api/action/FindByModule/1.
The routing I used is
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Controller:
public class ActionController : ApiController
{
private IActionRepository repository = null;
[HttpGet]
[ActionName("All")]
public IEnumerable<JsonAction> All()
{
return from action in this.repository.Get()
select new JsonAction
{
ID = action.ID,
Text = action.Text.Trim(),
Description = action.Description.Trim(),
};
}
[HttpGet]
[ActionName("FindByModule")]
public IEnumerable<JsonAction> FindByModule(Int64 moduleId)
{
return from action in this.repository.FindByModule(moduleId)
select new JsonAction
{
ID = action.ID,
Text = action.Text.Trim(),
Description = action.Description.Trim(),
};
}
}
This is because there is a parameter name mismatch. From your route the value 1 is assigned to parameter named id and your action is looking for parameter named moduleId.
First option is to change your route like this:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{moduleId}",
defaults: new { moduleId = RouteParameter.Optional }
);
Second is to change your URL like this:
http://localhost:37331/api/action/FindByModule?moduleId=1
So the parameter name match.
My api had too many parameters and I was getting an error. I solved the problem with Route.
[Route("addressverification/{id}/{no}/{day}/{month}/{year}")]
public AdressVerificationResult Get(long? id, long? no ,long? day, long? month, long? year)
{
return new AdressVerificationResult
{
Aciklama = "19........4 kimlik numaralı kişinin 18.......1 adres numarasında 'YerlesimYeri' adres tipi için geçerli bir yurtiçi adres beyanı mevcuttur.",
DurumKod = true
};
}

Resources