I am new to .Net and SignalR. I am looking at some code written by a former coworker and he added this line to the Route Config which is now throwing errors saying its obsolete but all the documentation I have read suggest mapping connections in this way.
namespace FailureInvestigationToolbox {
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 = "fit",
action = "Index",
id = UrlParameter.Optional
}
);
RouteTable.Routes.MapConnection<TaskListPersistence>("taskpersist", "/taskpersist");
}
}
}
The error is:
System.Web.Routing.SignalRRouteExtensions.MapConnection<T>
(System.Web.Routing.RouteCollection, string, string)' is obsolete:
'Use IAppBuilder.MapSignalR<TConnection> in an Owin Startup class. See
http://go.microsoft.com/fwlink/?LinkId=320578 for more details.'
C:\fit\FailureInvestigationToolbox\App_Start\RouteConfig.cs
Is it possible I have something wrong with my SignalR installation or is the IAppBuilder way of mapping things what I'm supposed to do...if so how?
I am using SignalR 2.0.3
You can use this article ,
1.In the global application class, remove the call to MapHubs.
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHubs();
}
2.Right-click the solution, and select Add, New Item.... In the dialog, select Owin Startup Class. Name the new class Startup.cs.
3.Replace the contents of Startup.cs with the following code:
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
Yes, you have to use IAppBuilder. Add a Owin Startup class, and in its Configuration method call MapConnection<T> on the app argument you receive. That should work. Check here and here.
To enable SignalR in your application, create a class called Startup with the following:
using Owin;
namespace MyWebApplication
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
Related
public void Configuration(IAppBuilder app)
{
// code is executed
}
public void ConfigureServices(IServiceCollection services)
{
// code is not executed
}
ConfigureServices(IServiceCollection services) method is only available in ASP.NET Core.
this might help- ASP.NET Classic OWIN StartUp ConfigureServices not called
Based on OWIN Startup Class Detection, you have to add the NuGet package Microsoft.Owin.Host.SystemWeb and then reference a OWIN Startup class from VisualStudio template, then in the following code you can access OWIN:
[assembly: OwinStartup("ProductionConfiguration", typeof(StartupDemo.ProductionStartup2))]
namespace StartupDemo
{
public class ProductionStartup
{
public void Configuration(IAppBuilder app)
{
app.Run(context =>
{
string t = DateTime.Now.Millisecond.ToString();
return context.Response.WriteAsync(t + " Production OWIN App");
});
}
}
public class ProductionStartup2
{
public void Configuration(IAppBuilder app)
{
app.Run(context =>
{
string t = DateTime.Now.Millisecond.ToString();
return context.Response.WriteAsync(t + " 2nd Production OWIN App");
});
}
}
}
I have a project where there is a controller within a web forms application.
My controller is called Token
public class TokenController : BaseTokenController
{
public override bool IsInherited => true;
}
this controller inherits from BaseTokenController
public abstract class BaseTokenController : ApiController
{
public abstract bool IsInherited { get; }
public virtual bool Post([FromBody]TokenValidateArgs args)
{
if (!IsInherited)
throw new Exception("Attempt to call base token controller not allowed");
return args.Validate();
}
public virtual string Get()
{
if (!IsInherited)
throw new Exception("Attempt to call base token controller not allowed");
return new Token()
}
}
In my global.asax I have a method called Register:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute("API default", "api/{controller}/{id}",
new { id = RouteParameter.Optional });
}
and in global.asax Application_Start the first line of code is
protected void Application_Start(object sender, EventArgs e)
{
Register(GlobalConfiguration.Configuration);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
I did have this working, however I then merged with the master branch for the project and it stopped working. I can't see anything that has changed.
this is the error:
No HTTP resource was found that matches the request URI 'https://localhost:44398/api/token'.
No type was found that matches the controller named 'token'.
Has anyone else experienced a similar issue and would know how to fix this. I have read other threads and tried to fix this by putting in a RoutePrefix on the controller, moving the order of execution on the global.asax and calling the get() method directly
So for my issue it turns out the project that has the "BaseTokenController" was running version 5.2.3 of WebApi however the web application project was running 5.2.4 which caused a conflict, resulting in a 404 error. To fix this I downgraded the app to 5.2.3
I am building an ASP.net WebApi, and trying to use Entity alongside. I am following this guide.
Getting Started with ASP.NET Web API 2 (C#)
I am receiving a 500 internal server error using Fiddler. The JSON Exception message states ExceptionMessage=An error occurred when trying to create a controller of type 'LocationsController'. Make sure that the controller has a parameterless public constructor.
Here is the Controller.cs
[RoutePrefix("api/Locations")]
public class LocationsController : ApiController
{
// GET api/<controller>
private IlocationsRepository LocationsRepo;
public LocationsController(IlocationsRepository _repo)
{
if (_repo == null) { throw new ArgumentNullException("_repo"); }
LocationsRepo = _repo;
}
[HttpGet]
[Route("")]
public IEnumerable<Location> GetAll()
{
return LocationsRepo.GetAll();
}
}
I can't use a parameterless public constructor because I need to use the Database Repository that was created for Locations. I verified the issue was with the IlocationsRepository by doing the following.
When I replace the LocationsController constructor with no parameters , and declare a List<Location> within the controller, and use dummy data. I receive a 200 with all the json data correct.
Here is the start of the Global.asax.cs file
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
protected void Session_Start(object sender, EventArgs e)
{
}
}
It seems as if I need to do the dependency injection in the Global, but none of the guides had any information regarding this part.
For posterity here is the ContextDB cs
public class WebServerContext : DbContext
{
public WebServerContext() : base("WebServerContext") {}
public DbSet<Order> dOrders { get; set; }
public DbSet<Location> dLocations { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
For additional posterity, here is the Locations Repository.
public class LocationsRepository : IlocationsRepository
{
private z_Data.WebServerContext db = new z_Data.WebServerContext();
public void Add(Location item)
{
db.dLocations.Add(item);
}
public IEnumerable<Location> GetAll()
{
return db.dLocations;
}
}
As per Dependency Injection for Web Api tutorial on MSDN, you are missing the line to register the dependency resolver (a concrete class that implements System.Web.Http.IDependencyResolver) with Web Api. It acts like a bridge between your DI container and Web Api so it can resolve your constructor dependencies.
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
container.RegisterType<IProductRepository, ProductRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container); // <- You need this
// Other Web API configuration not shown.
}
Of course, that assumes you are using Unity. If not, you should either use the DependencyResolver that came with your DI container or implement your own.
NOTE: With some DI containers, you also need to register all of your controllers explicitly.
I am facing issue in using WebAPI action filter.
I wrote the following custom filter to perform some logic on the http request header before executing the controller method.
using System;
using System.Web.Mvc;
namespace WebApi.Filters
{
public class dataCheck : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Console.Write("custom filter called");
}
}
}
Then added filter attribute on top of controller method
[dataCheck ]
[HttpGet]
[Route("GetInfo")]
public LatestInfo GetInfo()
{
TestContext context = new TestContext ();
LatestInfo latestReleaseInfo = new LatestInfo ();
return LatestInfo ;
}
Problem:
I put debugger to my custom filter and found it is never invoked.
What is wrong here?
Am i using the right type filter for my logic?
Please advise.
You have to be sure your code uses the ActionFilterAttribute from the System.Web.Http.Filters namespace and not the one from System.Web.Mvc.
Karthik's answer is correct - there are a couple of other things in your class that you should correct.
Your override function should accept a HttpActionContext as opposed to ActionExecutingContext. Also, you should call base.OnActionExecuting(actionContext); at the end of your function
using System;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace WebApi.Filters
{
public class dataCheck : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
Console.WriteLine("debugger stop here");
// custom filter code
base.OnActionExecuting(actionContext);
}
}
}
i have setup my project with Ninject IoC.
My project has regular Asp.Net MVC controllers and Web Api controllers. Now, Ninject works with Web Api but Ninject doesn't work with regular Asp.MVC controllers.
My regular MVC controller implementation;
public class GalleryController : BaseController
{
public GalleryController(IUow uow)
{
Uow = uow;
}
........
}
Error when using with regular controller
An error occurred when trying to create a controller of type 'Web.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.]
However, when i try the same code with Web Api, it works
public class GalleryController : BaseApiController
{
public GalleryController(IUow uow)
{
Uow = uow;
}
......
}
my interface which holds difference repositories (the factory pattern)
public interface IUow
{
// Save pending changes to the data store.
void Commit();
//Repositoryries
IRepository<Gallery> Gallery { get; }
IMenuRepository Menus { get; }
}
NinjectDependencyScope class;
public class NinjectDependencyScope : IDependencyScope
{
private IResolutionRoot resolver;
internal NinjectDependencyScope(IResolutionRoot resolver)
{
Contract.Assert(resolver != null);
this.resolver = resolver;
}
public void Dispose()
{
var disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();
resolver = null;
}
public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.GetAll(serviceType);
}
}
NinjectDependencyResolver class;
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel.BeginBlock());
}
}
Ninject configuration for Global.asax;
public class IocConfig
{
public static void RegisterIoc(HttpConfiguration config)
{
var kernel = new StandardKernel(); // Ninject IoC
//kernel.Load(Assembly.GetExecutingAssembly()); //only required for asp.net mvc (not for webapi)
// These registrations are "per instance request".
// See http://blog.bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/
kernel.Bind<RepositoryFactories>().To<RepositoryFactories>()
.InSingletonScope();
kernel.Bind<IRepositoryProvider>().To<RepositoryProvider>();
kernel.Bind<IUow>().To<Uow>();
// Tell WebApi how to use our Ninject IoC
config.DependencyResolver = new NinjectDependencyResolver(kernel);
}
}
Global.asax
protected void Application_Start()
{
// Tell WebApi to use our custom Ioc (Ninject)
IocConfig.RegisterIoc(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfig.CustomizeConfig(GlobalConfiguration.Configuration);
AreaRegistration.RegisterAllAreas();
}
I have written some gists to help configure Ninject with MVC and Web Api. Simply include the file(s):
https://gist.github.com/odytrice/5821087 (for MVC)
https://gist.github.com/odytrice/5842010 (for WebApi)
To add Bindings for concrete Types, Just put them in the Load() method of the MainModule. You can create as many modules as you like to keep bindings organized. but you'll also have to add them to the array that is returned in the Modules property.
Then Add to the Application_Start() method
NinjectContainer.RegisterModules(NinjectModules.Modules) (for MVC)
NinjectHttpContainer.RegisterModules(NinjectHttpModules.Modules) (for WebApi)
Note that you can use the same NinjectModules.Modules for both the MVC and WebApi registration. I just separated it for clearity
UPDATE: Remember to Remove NinjectWebCommon.cs from your project as it loads and bootstraps a new kernel at Runtime which unfortunately is only for MVC.
UPDATE: You can also use
NinjectContainer.RegisterAssembly() (for MVC)
NinjectHttpContainer.RegisterAssembly() (for WebApi)
This will scan your current assembly for all modules. This way you can put your modules anywhere in your project and it will be registered
With MVC 5 and Web API 2.2 I solved this problem by making sure I included the following NuGet packages:
Ninject.MVC5
Ninject.Web.WebApi.WebHost for Web API
This installed other Ninject dependencies and allowed me to RegisterServices through NinjectWebCommon.cs.
After searching a lot, it turns out there we can't use Ninject with web api and regular mvc. I mean, we have to configure the Repositories separately.
I then found a nice article which explains how you can use Ninject with asp.net mvc & web api: http://www.codeproject.com/Articles/412383/Dependency-Injection-in-asp-net-mvc4-and-webapi-us
And now, I don't get the error and it's working :D
Update 1:
Also try Writing a simple implementation of dependency injection in MVC 4 Web API with .NET Framework 4.5
Here is the simple solution that works fine for me:
In Visual studio, create new web application project named DemoApp and make sure you have selected Empty template with MVC and Web API references:
In Package manager console execute one by one:
Install-Package Ninject
Install-Package Ninject.MVC5
Add NinjectDependencyResolver.cs to IoC folder :
using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http.Dependencies;
namespace DemoApp.IoC
{
public class NinjectDependencyResolver : IDependencyResolver, System.Web.Mvc.IDependencyResolver
{
private readonly IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return this;
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
public void Dispose() { } //it is not necessary to implement any dispose logic here
}
}
Make the following changes in App_Start/NinjectWebCommon.cs :
Add these lines in CreateKernel method:
NinjectDependencyResolver ninjectResolver = new NinjectDependencyResolver(kernel);
DependencyResolver.SetResolver(ninjectResolver); //MVC
GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; //Web API
Add your bindings in RegisterServices method like:
kernel.Bind< IHelloService>().To< HelloService>();
Now NinjectWebCommon.cs should look like:
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(DemoApp.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(DemoApp.App_Start.NinjectWebCommon), "Stop")]
namespace DemoApp.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using DemoApp.IoC;
using System.Web.Mvc;
using System.Web.Http;
using DemoApp.Config;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
NinjectDependencyResolver ninjectResolver = new NinjectDependencyResolver(kernel);
DependencyResolver.SetResolver(ninjectResolver); //MVC
GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; //Web API
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IHelloService>().To<HelloService>();
}
}
}
Just for the completeness of the example, add some Mvc and Api controllers, and code for IHelloService, HelloService :
HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DemoApp.Config;
namespace DemoApp.Controllers
{
public class HomeController : Controller
{
private IHelloService helloService;
public HomeController(IHelloService helloService)
{
this.helloService = helloService;
}
// GET: /Home/
public string Index()
{
return "home/index: " + helloService.GetMessage();
}
}
}
UserController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using DemoApp.Config;
namespace DemoApp.Controllers
{
public class UserController : ApiController
{
private IHelloService helloService;
public UserController(IHelloService helloService)
{
this.helloService = helloService;
}
[HttpGet]
public string Data()
{
return "api/user/data: " + helloService.GetMessage();
}
}
}
IHelloService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DemoApp.Config
{
public interface IHelloService
{
string GetMessage();
}
}
HelloService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DemoApp.Config
{
public class HelloService : IHelloService
{
public string GetMessage()
{
return "Hi";
}
}
}
The final structure should look like:
Now make some tests in browser. For me it was:
http://localhost:51156/home/index
http://localhost:51156/api/user/data
And that's it.
I think the issue is that you are not registering a ControllerFactory that uses Ninject to build the controllers (and resolve their dependencies), have you tried implementing your own ControllerFactory yet? See also here http://bubblogging.wordpress.com/2012/06/04/mvc-controller-factory-ninject/.
There is a more elegant solution for this by Nenad - it took me 3 extra hours because I first tried to implement the solutions here conflicting with existing infrastructure I had. It is in reply to another stack overflow question. I am duplicating that answer here just in case it helps others to save the time I lost.
There is a way to share same container between MVC and ASP.NET Web API.
You just need to implement both interfaces.
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver, System.Web.Mvc.IDependencyResolver
{
private readonly IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(this.kernel.BeginBlock());
}
}
Check this article for solution:
Simple Way to share Dependency Resolvers between MVC and Web API