404 error on ASP.NET Web API Controller - asp.net-mvc-5

I have created a ASP.NET MVC5 web application and then added HelpPages and Web Api components. The MVC web app and HelpPages worked fine, but I couldn't reach to the API Controller via http://localhost:port/api/Samples/GetAll. What can be wrong and how can I troubleshoot this?
WebApiConfig.cs
namespace MySolution.ApiV1
{
using System.Web.Http;
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
}
}
}
API Controller
namespace MySolution.ApiV1.Controllers.Api
{
[System.Web.Http.RoutePrefix("api/Samples")]
public class SamplesController : System.Web.Http.ApiController
{
[System.Web.Http.HttpGet]
[System.Web.Http.Route("GetAll")]
public System.Web.Http.IHttpActionResult Get()
{
return Ok("Hello Web API!");
}
}
}
Global.ascx.cs
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
System.Web.Http.GlobalConfiguration.Configure(WebApiConfig.Register);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}

I found the problem. The web api route must be called before the mvc route. I don't know why it makes a differences, but after I swap the orders, it worked.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
System.Web.Http.GlobalConfiguration.Configure(WebApiConfig.Register); // call first
RouteConfig.RegisterRoutes(RouteTable.Routes); // call second
BundleConfig.RegisterBundles(BundleTable.Bundles);
}

Related

Anonymous Authentication with Custom Controller

I am trying to implement a custom controller in Acumatica for development purposes. But I cant seem to figure out how to sidestep Acumatica auth and allow access without authentication.
Here is my Controller:
https://www.acumatica.com/blog/using-asp-net-web-api-mvc-with-acumatica/
[RoutePrefix("test")]
public class TestController: ApiController
{
[HttpGet]
[Route()]
[AllowAnonymous]
public IHttpActionResult PerformAction()
{
return Ok("Actions Available");
}
}
And here is my startup
public class Startup
{
public static void Configuration(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
}
}
public class ServiceRegistration : Module
{
protected override void Load(ContainerBuilder builder)
{
GlobalConfiguration.Configure(Startup.Configuration);
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
}
}
But when I send a GET to {baseUrl}/test in Postman, it returns 401 unauthorized. If I open my browser, log in and go to that same route, I recieve "actions available"
What am I missing to allow anonymous Auth on a custom WebApi Controller?
Thanks
Authorization can be customized inside the Autofac module in the extension library. Reference PX.Export, PX.Hosting (this was done for 2021R1)
public class Startup
{
public static void Configuration(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
}
}
public class ServiceRegistration : Module
{
protected override void Load(ContainerBuilder builder)
{
GlobalConfiguration.Configure(Startup.Configuration);
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// Configuration of Authorize here
builder.Configure<AuthenticationManagerOptions>(options =>
options.AddLocation("sourcecontrol").WithAnonymous());
}
}

ServiceStack (5.5.0) - When testing a ServiceStackController Gateway is null and throws an exception

Using ServiceStack (v 5.5.0) I read the recommended approach to calling services via a controller is by using the Gateway.
Full example is found at https://github.com/RhysWilliams647/ServiceStackControllerTest
public class HomeController : ServiceStackController
{
public ActionResult Index()
{
var response = Gateway.Send<TestServiceResponse>(new TestServiceRequest());
IndexModel model = new IndexModel { Message = response.Message };
return View(model);
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
However when testing my controller via xUnit I get a null exception error as Gateway is null. Below is my AppHost
public class AppHost : AppSelfHostBase
{
public AppHost() : base("Test", typeof(TestService).Assembly)
{
}
public override IServiceGateway GetServiceGateway(IRequest req) =>
base.GetServiceGateway(req ?? new BasicRequest());
public override void Configure(Container container)
{
SetConfig(new HostConfig
{
HandlerFactoryPath = "api"
});
container.RegisterFactory<HttpContext>(() => HttpContext.Current);
// register container for mvc
ControllerBuilder.Current.SetControllerFactory(new FunqControllerFactory(container));
}
}
And my test
[Trait("Category", "Controllers")]
[Collection("AppHostFixture")]
public class ControllerTest
{
[Fact]
public void CanCallHomeControllerIndex()
{
var controller = new HomeController();
controller.Index();
}
}
Can someone please advise how to test a ServiceStackController calling the service gateway?
AppSelfHostBase on .NET Framework is a HttpListener self-host which doesn't support MVC so you're not going to be able to run any integration tests.
When you new an MVC controller instance like this:
var controller = new HomeController();
It's base.HttpContext required by ServiceStackController doesn't exist, it requires a ASP.NET HttpContext but the self-host in unit test is running on a self-hosted HttpListener server.
You could try accessing the Gateway via the HostContext singleton i.e:
var gateway = HostContext.AppHost.GetServiceGateway(new BasicRequest());
var response = gateway.Send<TestServiceResponse>(new TestServiceRequest());
In this example it calls the Gateway with a mock Http Request Context to simulate a request, but you wont be able to execute real MVC integration tests with a self-hosted Http Listener.

How to exclude parameters from AI log?

I would like to exclude some parameters (e.g. city, userId, app role, ...) from traces and dependencies logs in Application Insights.
Have you any suggestions?
You can use ITelemetryInitializer to change the value of userId / app role to empty. Then in the AI logs, city, userId, app role will be removed automatically.
I test it with a .net core web app:
1.Add a MyTelemetryInitializer class to the web project:
public class MyTelemetryInitializer: ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
//only apply for Trace and Dependency
if (telemetry is TraceTelemetry || telemetry is DependencyTelemetry)
{
telemetry.Context.User.Id = "";
telemetry.Context.Cloud.RoleInstance = "";
telemetry.Context.Cloud.RoleName = "";
}
}
}
2.In the Startup.cs -> ConfigureServices method, register the custom telemetry initializer:
public void ConfigureServices(IServiceCollection services)
{
//other code
services.AddSingleton<ITelemetryInitializer, MyTelemetryInitializer>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
3.In the HomeController.cs, create a TelemetryClient to send telemetry data:
public class HomeController : Controller
{
TelemetryClient client = new TelemetryClient();
public IActionResult Index()
{
client.TrackTrace("0624-2 index: this is a trace message!!!");
return View();
}
public IActionResult About()
{
client.TrackTrace("0624-2 about: this is a trace message!!!");
ViewData["Message"] = "Your application description page.";
return View();
}
public IActionResult Contact()
{
client.TrackTrace("0624-2 contact: this is a trace message!!!");
ViewData["Message"] = "Your contact page.";
return View();
}
}
4.After running the project, wait for a few minutes, then nav to azure portal -> your app insights -> search page, check the properties of the trace messages:

My MVC5 project cant work toghter with WebAPI2 on Visual Studio 2012

on Visual Studio 2012 update 5:
I have created MVC5 project,
I have also created WebAPI2 project
Both working fine alone. When I try to combine them to one project - It doesn't work for the webAPI2.
public class RouteConfig
{
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 }
);
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
Any ideas?
I just needed to change the routing ordering.
What happens is that the website goes online first so that the api is blocked.
To fix it need to change the order of the Application_Start
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}

WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" class

in my asp.net mvc projet, i tried to implement a membership provider to manage accounts and roles
i'm facing this stack
You must call the "WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" class. This call should be placed in an _AppStart.cshtml file in the root of your site.
acually i added this ligne to my Startup.Auth.cs
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true); in order to allow
i tried to change my global.asax.cs as bellow
using decidata.mennilik.Models;
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using WebMatrix.WebData;
namespace decidata.mennilik
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}
private static SimpleMembershipInitializer _initializer;
private static object _initializerLock = new object();
private static bool _isInitialized;
private static object _initializerLock = new object();
private static bool _isInitialized;
private class SimpleMembershipInitializer
{
public SimpleMembershipInitializer()
{
Database.SetInitializer<ApplicationDbContext>(null);
try
{
using (var context = new ApplicationDbContext())
{
if (!context.Database.Exists())
{
// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
catch (Exception ex)
{
throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
}
}
}
}
}
but i'm having a problem in
AuthConfig.RegisterAuth();
did i miss something ?

Resources