How do I solve the WebAPI 404 error with the sample module code from Virtocommerce - virtocommerce

I've going through the sample tutorial provided in the Virtocommerce documentation.
http://docs.virtocommerce.com/display/vc2devguide/Creating+new+module
I'm using the exact code from the following location provided in the documentation
http://docs.virtocommerce.com/download/attachments/13303913/ManagedModule.zip?version=6&modificationDate=1458663072657&api=v2
I have most of the code running but I keep getting a 404 error with the WebAPI sample for the module.
I have the Virtocommerce code running as an application under my default website on my local dev machine.
I feel like the issue is probably in my API controller. Here is my code
using System.Web.Http;
namespace VirtoCommerce.Module1.Web.Controllers.Api
{
[RoutePrefix("api/module1")]
public class Module1Controller : ApiController
{
// GET: api/module1/
[HttpGet]
public IHttpActionResult GetData()
{
return Ok(new[] { "Hello world!" });
}
}
}
What is a good way to debug this 404 error?

The GetData() method should also have the [Route("")] attribute:
[HttpGet]
[Route("")]
public IHttpActionResult GetData()
{
return Ok(new[] { "Hello world!" });
}

Related

Why does not working version in asp.net core controller

I want to use api version in my .net core project.Then search web and find that's solution.
Even though do exactly all solutions,but I can't get desired result.
So if any can help me,Please show me..
I add Microsoft.AspNetCore.Mvc.Versioning 4.0.0 Package in my project and ..
StartUp.cs
Then in my Controller Add Rout Attribute as Shown :
[ApiController]
[Authorize]
[Route("v{version:apiVersion}/[Controller]")]
[ApiVersion("1.0")]
public class SellerController : Controller
{
private readonly IBus _client;
private readonly string AppBaseUrl = MyHttpContext.AppBaseUrl;
//private readonly IGetUrl _globalUrl;
public SellerController(IBus client/*, IGetUrl globalUrl*/)
{
_client = client;
//_globalUrl = globalUrl;
}
[HttpGet("/Sellers/{SellerId}")] // Dashboard
public async Task<IActionResult> Info(long SellerId)
{
...
}
}
With these code I expected that I can send request to 'Info' method by this url :
But that's not working and get 404 error code status.. when I delete "/v1.0" from url and send request, that's working. I will be glad to help me .. Thanks
In your code, we can find that you applied [HttpGet("/Sellers/{SellerId}")] with route
template begin with / to Info action method, which don't get combined with route templates applied to the controller. To make request to 'Info' method, you could use below URL.
https://localhost:5090/sellers/17
I expected that I can send request to 'Info' method by this url : https://localhost:5090/v1.0/sellers/17
To achieve your requirement, you can try to modify the code like below.
[HttpGet("/v{version:apiVersion}/Sellers/{SellerId}")]
public async Task<IActionResult> Info(long SellerId)
{
//...
//for testing purpose
return Ok(SellerId);
}
Test Result
Update:
If you'd like to include v{version:apiVersion} in route template of controller level attribute routing, you can try to apply [HttpGet("{SellerId}")] to Info action method and make request with https://localhost:5090/v1.0/seller/17.
[ApiController]
[Authorize]
[Route("v{version:apiVersion}/[Controller]")]
[ApiVersion("1.0")]
public class SellerController : Controller
{
[HttpGet("{SellerId}")] // Dashboard
public async Task<IActionResult> Info(long SellerId)
{
//...

How do I get Route attribute to work in .net core api?

So I added a controller to a blank asp.net CORE Api.
public class IsAliveController : ControllerBase
{
[HttpPost]
[HttpGet]
[Route("isalive")]
public object Get()
{
return "I'm alive";
}
}
Then I try to access it via https://localhost:44361/isalive
and I get no response. Do I need to make some modifications to my Startup.cs?
First why have you declared your method both as a get and a post request? you can remove the post attribute.
By default your routing must start with your controller name, add this:
[Route("[controller]")]
[ApiController]
public class IsAliveController : ControllerBase
{
[HttpGet]
public object Get()
{
return "I'm alive";
}
}
Now when you call https://localhost:44361/isalive you will receive the expected response.
There are two solutions to your problem:
#1 Your controller Name is IsAlive and you have added a route attribute on your action method as isAlive, so this would work only if you call using this Url
https://localhost:44361/isalive/isalive
#2 Remove the Route attribute from the action method
public class IsAliveController : ControllerBase
{
[HttpGet]
public object Get()
{
return "I'm alive";
}
}
and you will be able to access using Url
https://localhost:44361/isalive
Found the issue. The template I choose (using Visual studio 2019) was:
Asp.net core web app > Web Application
The startup file in this template is missing a line that I needed to add:
app.UseEndpoints(endpoints =>
{
//Add this line
endpoints.MapControllers();
});
After adding that line the endpoint works without any changes to the controller.

Issue with API Versioning .NET Core 2.2 UnsupportedApiVersion

I am creating an API and need to have versioning done in it. I am using package Microsoft.AspNetCore.Mvc.Versioning 3.1.3
My StartUp.cs is as follows
In ConfigureServices
services.AddApiVersioning(o => {
o.ReportApiVersions = true;
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
});
services.AddMvc(options => options.EnableEndpointRouting = false).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
My 2 controllers on which I want to have versioning done are as below
namespace JWTWithRefresh.Areas.V1.CMS
{
[AllowAnonymous]
[ApiVersion("1.0")]
[Route("api/[controller]/[action]")]
public class AppController : Controller
{
public IActionResult GetApp()
{
return Ok("This is from API V1");
}
}
}
and another controller is as below
namespace JWTWithRefresh.Areas.V2.CMS
{
[AllowAnonymous]
[ApiVersion("2.0")]
[Route("api/[controller]/[action]")]
public class AppController : Controller
{
public IActionResult GetApp()
{
return Ok("This is from API V2");
}
}
}
The response I get when I make a call is as below
Endpoint = https://localhost:5001/api/App/GetApp?api-version=1.0
Response =
{
"error": {
"code": "UnsupportedApiVersion",
"message": "The HTTP resource that matches the request URI 'https://localhost:5001/api/App/GetApp' is not supported.",
"innerError": null
}
}
Please guide me in fixing this issue if anyone has gone through the same.
Thanks
For anyone else having the problem, I solved it by following suggestion from LGSon in comments above:
Solution 1:
Add [ApiController] in Controller
Solution 2:
Disable API Behavior
services.AddApiVersioning( options => options.UseApiBehavior = false );
Change Route attribute like this
[Route("v{version:apiVersion}/[controller]/[action]")]
and endpoint = https://localhost:5001/api/App/v1/GetApp or https://localhost:5001/api/App/v2/GetApp.
for more: https://www.hanselman.com/blog/ASPNETCoreRESTfulWebAPIVersioningMadeEasy.aspx
The issue can come if you dont change the version from the dropdown in the swagger ui and in the api call, you change the version number and execute.
Make sure you change the version number from the dropdown swagger api version, before giving the api version number in the api call.
version in api call

Web API 2 Post 404s, but Get works

I'm confused... I have a very simple Web API and controller, which works fine if I have a GET request, but 404's if I have a POST request.
[RoutePrefix("api/telemetry/trial")]
public class LoginTelemetryController : ApiController
{
[Route("login")]
[HttpPost]
public IHttpActionResult RecordLogin(string appKey) {
using (var context = new Core.Data.CoreContext()) {
context.ActivityLogItems.Add(new Domain.Logging.ActivityLogItem()
{
ActivityType = "Trial.Login",
DateUtc = DateTime.UtcNow,
Key = new Guid(appKey)
});
context.SaveChanges();
}
return Ok();
}
When I post against this in postman, I get:
{
"message": "No HTTP resource was found that matches the request URI 'http://localhost:47275/api/telemetry/trial/login'.",
"messageDetail": "No action was found on the controller 'LoginTelemetry' that matches the request."
}
If I change it to a [HttpGet] and put the appKey as a querystring, all is fine.
My app startup is very simple:
public void Configuration(IAppBuilder app)
{
log4net.Config.XmlConfigurator.Configure();
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.MapHttpAttributeRoutes(); // <------ HERE
FilterConfig.RegisterHttpFilters(httpConfig.Filters);
LoggingConfig.RegisterHandlers(httpConfig.Services);
ConfigureOAuth(app);
ConfigureWebApi(httpConfig);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(httpConfig);
}
Can anyone spot why POST requests aren't being found? Thanks
If I take string parameter out and replace it with a request object, it works...
Instead of: public IHttpActionResult RecordLogin(string appKey)
I create a request model class:
public class PostLoginTelemetryRequest{
public string appKey {get;set;}
}
Then alter the signature:
public IHttpActionResult RecordLogin(PostLoginTelemetryRequest request)
Everything works fine (why it can't take a regular string like MVC5 web dev, I don't know, but anyway...)
(also note that I had tried this in every format from the client with the string method: form-url-encode, raw body, etc, so I'm fairly certain it wasn't a calling format issue).

ASP.NET WebAPI with MVC - Unity Controller Injection Fails for HTTPPOST

I have a simple Login Controller that looks like this:
public class LoginController : Controller
{
private IAccountService _accountService = null;
private IFormsAuthenticationService _formsAuthenticationService = null;
public LoginController() {}
[InjectionConstructor]
public LoginController(IAccountService accountService, IFormsAuthenticationService formsAuthenticationService)
{
_accountService = accountService;
_formsAuthenticationService = formsAuthenticationService;
}
//
// GET: /Login/
public ActionResult Index()
{
return View();
}
//
// POST: /Login/
[HttpPost]
public ActionResult Index(Credentials credentials)
{
try
{
if (_accountService.ValidateUser(credentials) != null)
{
_formsAuthenticationService.SignIn(credentials.UserName, true);
return RedirectToAction("Index", "Home");
}
else
return RedirectToAction("Index", new { failed = true });
}
catch
{
throw;
}
}
}
Locally, everything works fine. When I put the application on my web server (shared hosting, ASP.NET 4.0) though, constructor injection works fine for the GET, but does not fire for the POST.
Essentially for POST, the default constructor is fired instead of the injection constructor. I'm not sure if Unity is even kicking in for the POST verb (how can I test this?).
I am using Boostrapper.cs and as I say, everything works fine on my development PC, so presumably there is an issue at the web server. I might be able to get some server settings changed. Any suggestions?
Cheers -
Bollocks - looks like the problem was due to me trying to load the wrong version of the EntityFramework DLL (v6 instead of 4.1). That wasn't coming up in the stack trace, but when I discovered this and replaced the DLL things started working OK again.