How to integrate WebApi 2 with Spring.Net - c#

Im trying to integrate WebApi 2 with Spring.Net with not success. This is what i have tried:
public class MvcApplication : SpringMvcApplication
{
protected void Application_Start()
{
XmlConfigurator.Configure();
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
When is creating the SpringWebApiDependencyResolver instance, i'm getting this exception:
Error creating context 'spring.root': Request is not available in this context
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.DependencyResolver = new SpringWebApiDependencyResolver(ContextRegistry.GetContext());
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Im using Spring.Net 2.0.1

Now is working, the following line was not needed:
config.DependencyResolver = new SpringWebApiDependencyResolver(ContextRegistry.GetContext());
This is my implementation based on Spring.Net example:
public class MvcApplication : SpringMvcApplication
{
protected void Application_Start()
{
// More config...
GlobalConfiguration.Configure(WebApiConfig.Register);
// More config...
}
protected override System.Web.Http.Dependencies.IDependencyResolver BuildWebApiDependencyResolver()
{
var resolver = base.BuildWebApiDependencyResolver();
var springResolver = resolver as SpringWebApiDependencyResolver;
if (springResolver != null)
{
var resource = new AssemblyResource(
"assembly://assemblyName/namespace/ChildControllers.xml");
springResolver.AddChildApplicationContextConfigurationResource(resource);
}
return resolver;
}
}
I prefered to keep the common WebApi configuration:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
For registration of controllers in the IoC container is the same as MVC integration:
<object type="namespace.PrefixController, assemblyName" singleton="false" >
<property name="Dependency1" ref="Dependency1" />
</object>

Related

Can't integrate autofac with both web api 2 and mvc

this thing takes one week from me
i have done many methods to find a solution
mvc fully integrated with autofac, but web api NO and NO! :-(
here is my codes:
AutofacDi
public static class AutofacDi
{
public static ValueTuple<IContainer, HttpConfiguration> Initialize()
{
var assembly = Assembly.GetExecutingAssembly();
var builder = new ContainerBuilder();
var config = GlobalConfiguration.Configuration;
builder.RegisterControllers(assembly);
builder.RegisterApiControllers(assembly).PropertiesAutowired();
builder.RegisterHttpRequestMessage(config);
builder.RegisterAssemblyModules(assembly);
builder.RegisterAssemblyTypes(assembly).PropertiesAutowired();
builder.RegisterFilterProvider();
builder.RegisterWebApiFilterProvider(config);
builder.RegisterModelBinders(assembly);
builder.RegisterWebApiModelBinderProvider();
builder.RegisterModelBinderProvider();
builder.RegisterModule<AutofacWebTypesModule>();
builder.RegisterSource(new ViewRegistrationSource());
builder.RegisterType<T4MVC.Dummy>().AsSelf();
builder.RegisterType<FoodDbContext>()
.As<IUnitOfWork>()
.InstancePerLifetimeScope();
builder.Register(context => (FoodDbContext)context.Resolve<IUnitOfWork>())
.As<FoodDbContext>()
.InstancePerLifetimeScope();
builder.RegisterType<ApplicationDbContext>().As<DbContext>().InstancePerLifetimeScope();
builder.RegisterType<UserStore<ApplicationUser>>().As<IUserStore<ApplicationUser>>();
builder.RegisterType<ApplicationUserManager>();
builder.RegisterType<ApplicationSignInManager>();
builder.Register(c => new IdentityFactoryOptions<ApplicationUserManager>()
{
DataProtectionProvider = new DpapiDataProtectionProvider("FoodBaMa")
});
builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).InstancePerLifetimeScope();
builder.RegisterType<RoleStore<IdentityRole>>().As<IRoleStore<IdentityRole, string>>();
builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
return new ValueTuple<IContainer, HttpConfiguration>(container, config);
}
}
OWIN Startup
[assembly: OwinStartup(typeof(FoodBaMa.Startup))]
namespace FoodBaMa
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var iOc = AutofacDi.Initialize();
app.UseAutofacMiddleware(iOc.Item1);
app.UseAutofacMvc();
app.UseWebApi(iOc.Item2);
app.UseAutofacWebApi(iOc.Item2);
WebApiConfig.Register(iOc.Item2);
app.UseCors(CorsOptions.AllowAll);
ConfigureAuth(app);
}
}
}
Global
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());
ModelBinders.Binders.Add(typeof(string), new PersianModelBinder());
MvcHandler.DisableMvcResponseHeader = true;
DbInterception.Add(new ElmahEfInterceptor());
DbInterception.Add(new YeKeInterceptor());
GlobalConfiguration.Configuration.EnsureInitialized();
}
}
ApiController
[AutofacControllerConfiguration]
[WebApiCompress]
[RoutePrefix("api/v1")]
public class AppController : ApiController
{
private readonly IApiV1Service _apiService;
public AppController(
IApiV1Service apiService
)
{
_apiService = apiService;
}
[HttpPost]
[Route("app/mainview")]
public virtual async Task<IHttpActionResult> MainView([FromBody] Request model)
{
var Result = new Models.API.V1.App.MainView.Response { Status = CheckTokenEnum.Error };
try
{
if (ModelState.IsValid)
Result = await _apiService.MainView(model).ConfigureAwait(false);
}
catch (Exception ex)
{
ErrorLog.GetDefault(null).Log(new Error(ex));
}
return Json(Result, R8.Json.Setting);
}
}
WebApiConfig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.JsonIntegration();
config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
config.MessageHandlers.Add(new CachingHandler(new InMemoryCacheStore()));
config.MessageHandlers.Add(new PreflightRequestsHandler());
config.Filters.Add(new ElmahHandleErrorApiAttribute());
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
RouteConfig
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//routes.IgnoreRoute("{*browserlink}", new { browserlink = #".*/arterySignalR/ping" });
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
//routes.LowercaseUrls = true;
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
},
namespaces: new[] { "FoodBaMa.Controllers" }
);
}
}
on each web api request, returns:
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
Module: IIS Web Core
Notification: MapRequestHandler
Handler: StaticFile
Error Code: 0x80070002
It's a killing problem for me because it's two weeks that making my website application unusable.
i don't know what to do.
help me !!!
i fixed that issue by commenting:
builder.RegisterWebApiFilterProvider(config);
and
builder.RegisterHttpRequestMessage(config);
in AutofacDi
It appears you may have gotten past your issue, which I hope is true. There's a lot to digest in here, but I do see a common mistake in the very start with respect to OWIN integration and Web API as documented in the Autofac docs:
A common error in OWIN integration is use of the GlobalConfiguration.Configuration. In OWIN you create the configuration from scratch. You should not reference GlobalConfiguration.Configuration anywhere when using the OWIN integration.
You may run into additional/other challenges in your setup as it sits; if you do, try getting rid of the use of GlobalConfiguration.Configuration.

C# WebApi DI not working

Hello i need some assistance. I'm struggling on this second day and can't find a source of the problem. I'm working on web api with token authorization , identity and ninject.
This is my kernel :
public IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<AppContext>().ToSelf().InRequestScope();
kernel.Bind(x => { x.From(typeof(UserService).Assembly).SelectAllClasses().EndingWith("Service").BindDefaultInterface(); });
kernel.Bind(typeof(IUserStore<AppIdentityUser>)).To(typeof(UserStore<AppIdentityUser>)).InRequestScope()
.WithConstructorArgument("context", kernel.Get<AppContext>());
kernel.Bind(typeof(UserManager<AppIdentityUser>)).To(typeof(UserManager<AppIdentityUser>)).InRequestScope()
.WithConstructorArgument("store", kernel.Get<IUserStore<AppIdentityUser>>());
kernel.Bind(typeof(IRoleStore<IdentityRole, string>)).To(typeof(RoleStore<IdentityRole>)).InRequestScope().WithConstructorArgument("context", kernel.Get<AppContext>());
kernel.Bind(typeof(RoleManager<IdentityRole>)).To(typeof(RoleManager<IdentityRole>)).InRequestScope().WithConstructorArgument("store", kernel.Get<IRoleStore<IdentityRole, string>>());
kernel.Bind<IOAuthAuthorizationServerProvider>().To<AuthorizationServerProvider>();
kernel.Bind<IOAuthAuthorizationServerOptions>().To<MyOAuthAuthorizationServerOptions>();
return kernel;
}
This is my api controller :
public UsersController(IUserService userService)
{
this._userService = userService;
}
public IHttpActionResult Login()
{
//get user method
}
this is my service :
public UserService(UserManager<AppIdentityUser> userMenager, RoleManager<IdentityRole> roleManager)
{
this._userMenager = userMenager;
this._roleManager = roleManager;
}
public AppIdentityUser GetUser(string name, string password)
{
return _userMenager.Find(name, password); // here I recive error on second time
}
Problem is that this works only once. When i open application and perform one get action it works on the second time when i try after few seconds i get exception that Context in user Store is disposed. I suspect that it's problem with my ninject configuration but don't see any error.
Edit: this is my Owin Startup Class
public void Configuration(IAppBuilder app)
{
config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.EnableCors();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
var kernel = ConfigureNinject(app);
ConfigureOAuth(app, kernel);
config.DependencyResolver = new NinjectResolver(kernel);
//app.UseWebApi(config);
app.UseNinjectMiddleware(() => kernel);
app.UseNinjectWebApi(config);
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AutoMapperConfiguration.Configure();
}
public void ConfigureOAuth(IAppBuilder app, IKernel kernel)
{
app.UseOAuthBearerTokens(kernel.Get<IOAuthAuthorizationServerOptions>().GetOptions());
}

Web API: Odata route always returning a 404 response

I am new to OData. I have built an ASP.NET Web API controller as shown below:
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Web.OData.Routing;
namespace HelloWebApi.Controllers
{
public class TestsController : ODataController
{
ProductsContext db = new ProductsContext();
private bool TestExists(int key)
{
return db.tests.Any(p => p.key== key);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
[EnableQuery]
public IQueryable<test> Get()
{
return db.tests;
}
}
}
The model is as shown below:
public class Test
{
[Key]
public int key { get; set; }
public string aaa { get; set; }
}
I have also configured the RouteConfig, ODdataConfig, and WebApiConfig as shown below:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.Ignore("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "Default",
routeTemplate: "{controller}/{action}/{id}"
);
}
}
public class ODataConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Test>("Tests");
config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
As well as the global.asax file:
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(config =>
{
ODataConfig.Register(config); //this has to be before WebApi
WebApiConfig.Register(config);
});
//FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
I tried making a number of modifications in order to resolve this. But I am consistently getting an HTTP 404 Not Found response. I also tried explicitly adding an [ODataRoute] attribute to the action method name; when doing that I instead get an HTTP 406 Not Acceptable response.
The URL I am trying to configure is:
http://localhost:6701/odata/tests/
Where odata is the suffix and tests is the controller name. Please point out what I am doing wrong.
The routes configured by the ODataConventionModelBuilder are case-sensitive. In your code, you have defined:
builder.EntitySet<Test>("Tests");
Based on this, the endpoint will be:
http://localhost:6701/odata/Tests/
Note the upper-case T in Tests.
This is by design, in order to maintain compatibility with the OData specification.
That said, as of Web API OData 5.4, you can optionally enable case-insensitive routes using the HttpConfiguration class's EnableCaseInsensitive() method. E.g., in your ODataConfig.Register() method you could add:
config.EnableCaseInsensitive(caseInsensitive: true);
For more information, see Basic Case Insensitive Support under Microsoft's ASP.NET Web API for OData V4 Docs.

Unity doesn't resolve my classes

I have more projects in solution (mostly class library and one WebAPI project) and I have problem in Common project in resolving dependencies inside this project. Here is example how I setting up dependency
[Dependency]
public IDbContextFactory DbContextFactory
{
get { return _factory; }
set
{
_factory = value;
DbContext = _factory.Create();
}
}
[Dependency]
public IUnitOfWorkManager Manager
{
get { return _manager; }
set
{
_manager = value;
_manager.AddOpenUnitOfWork(this);
}
}
and in same project I have registration interfaces and classes into Unity container via this class
public class CommonUnityConfiguration : IUnityConfiguration
{
public void Configurate(UnityContainer container)
{
container
.RegisterType<IUnitOfWorkManager, UnitOfWorkManager>()
.RegisterType<IDbContextFactory, DbContextFactory>();
}
}
and finally in WebAPI I have WebApiConfiguration, where I'm creating Unity container and register all classes.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Create instance for Unity container - let's try to run!
var container = new UnityContainer();
container.RegisterType<IUserRepository, UserRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
// Add project classes to IoC container
new CommonUnityConfiguration().Configurate(container);
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Problem is, IDbContextFactory property and IUnitOfWorkManager aren't resolve. Do you have any advice, what should I check?
I think you need to switch these two lines:
config.DependencyResolver = new UnityResolver(container);
new CommonUnityConfiguration().Configurate(container);
You're setting the DependencyResolver to the UnityREsolver before you fully configure it in your CommonUnityConfiguration class

WebApiConfig error in Global.asax

Please have a look at my Global.asax, i put the "problem" in caps. When I try to build, I get "The name 'WebApiConfig' does not exist in the current context
What am I missing, I´ve added the nuget Microsoft.AspNet.WebApi.WebHost
using SportsStore.WebUI.Infrastructure;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace SportsStore.WebUI
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WEBAPICONFIG.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ControllerBuilder.Current.SetControllerFactory(new
NinjectControllerFactory());
}
}
}
The WebApiConfig class is normally created under App_Start if you choose to add Web API references when creating a new ASP.NET web app in visual studio.
Manually add the class if it's not present:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
}

Categories

Resources