I've just installed ELMAH MVC (v2) into my web application but when I try to view the logs at /elmah I get the following exception
No component for supporting the service Elmah.Mvc.ElmahController was found
[ComponentNotFoundException: No component for supporting the service Elmah.Mvc.ElmahController was found]
Castle.MicroKernel.DefaultKernel.Resolve(Type service) +140
Castle.Windsor.WindsorContainer.Resolve(Type service) +40
N2.Engine.Castle.WindsorServiceContainer.Resolve(Type type) +40
N2.Engine.ContentEngine.Resolve(Type serviceType) +48
The web site includes the N2 CMS system which in turn uses Castle Windsor.
Any ideas on how I can resolve this?
I know this already has an accepted answer, and it's not entirely relevant to your question, but for anyone else not using N2 and running into issues with Elmah.MVC+Castle Windsor, you need to register the controllers in the Elmah.MVC assembly with Windsor. I made a simple installer to handle this for me:
public class ElamhInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromAssemblyNamed("Elmah.Mvc")
.BasedOn<IController>()
.LifestyleTransient());
}
}
Once I added this Castle seems to be able to find the ElmahController just fine.
Worked out the solution shortly after posting the question. I needed to register the Elmah controller with N2:
var engine = MvcEngine.Create();
engine.RegisterControllers(typeof(GlobalApplication).Assembly);
engine.RegisterControllers(typeof(ElmahController).Assembly);
ELMAH.MVC comes App_Start code, that uses Web.Activator to register ElmahController route.
So, it's strange for me, why Windor fails to load ElmahController. By default, it should try to resolve it by itself, then if not possible delegate to ControllerFactory.
Are you sure, application got restarted (iisreset.exe) after ELMAH installed?
Related
I have an mvc/forms hybrid webapplication hosted on a windows 2008 r2 instance on Azure. The webserver is IIS 7.5 . For the last 4-5 months my server is getting absolutely hammered by vulnerability scanners checking for php related vulnerabilities. example:
The controller for path '/wp-login.php' was not found or does not implement IController.
from Elmah
So I've gone in and specifically filtered .php and .cgi file extension requests in IIS 7.5 which is working great. However i am still getting hammered for requests like:
The controller for path '/admin/Cms_Wysiwyg/directive/' was not found or does not implement IController.
The controller for path '/phpmyadmin2018/' was not found or does not implement IController.
etc. etc. It's more an annoyance as everything is logged, a 404 is returned and it's all a useless resource throwaway.
Through Elmah i've queried a distinct list of URLs related to all these requests. What is the best way to short-circuit these requests? It would be good if i could optionally ban the IP's but right now there are 700 unique IPs making these requests in the last 3 months alone. Main priority is to just short circuit the requests from the dictionary of URLs I know are bogus and avoid the logging and response from my webserver. Thanks!
half pseudo code, but I think it will be helpful;
in Global.asax.cs:
public class MvcApplication : HttpApplication
{
protected void Application_BeginRequest(Object sender, EventArgs e)
{
var url = HttpContext.Current.Request.Url.AbsoluteUri;
if(checkUrl(url)){
// your code here
}
if (UserIsBanned(GetUserIp()))
{
Response.Write("ban");
Response.End();
}
}
private string GetUserIp()
{
return HttpContext.Current.Request.UserHostAddress;
}
I have a wcfservice that is coded in vb.net. I want to use it in a c# mvc 4 client application. But when I added this service with right click on references and Add Service References, I can not use this. How can I do this?
Your service codes contain contracts and the implementation. However, The service code should be used in only the service, not in the client programs. You should generate proxy classes to be used by client programs like your Asp.NET applications.
There are 2 typical ways:
1. You run the service, then create a Service Reference to the service instance, so VS IDE will generate proxy classes under folder Service References.
2. Generate proxy classes using svcutil.exe against the service assembly that contain contracts, and build a client API assembly.
The 2nd is the most tidy and efficient way. Please check this article for more details at http://www.codeproject.com/Articles/627240/WCF-for-the-Real-World-Not-Hello-World
This is a pretty basic question but generally speaking you can add a web service reference and endpoint info in the main Web.Config file but I suspect you are having trouble with calling the WCF service URL, if so I posted an example of a generic class/wrapper for calling WCF web services in an MVC application.
Add the Web Reference to Visual Studio 2012 (or similar):
Right click the project in the Solution Explorer
Choose Add–> Service Reference –> Then click the Advanced Button... –>
Then click the "Add Web Reference…" button –> then type the address of your Web Service into the URL box. Then click the green arrow and Visual Studio will discover your Web Services and display them.
You may have known the above already and might just need a generic wrapper class which makes calling the WCF Web Service easy in MVC. I've found that using the generic class works well. I can't take credit for it; found it on the internet and there was no attribution. There is a complete example with downloadable source code at http://www.displacedguy.com/tech/powerbuilder-125-wcf-web-services-asp-net-p3 that calls a WCF Web service that was made using PowerBuilder 12.5.Net, but the process of calling the WCF Web service in MVC is the same no matter if it was created in Visual Studio or PowerBuilder.
Generic wrapper class for calling WCF Web Services in ASP.NET MVC
Of course don't model your error handling after my incomplete example...
using System;
using System.ServiceModel;
namespace LinkDBMvc.Controllers
{
public class WebService<T>
{
public static void Use(Action<T> action)
{
ChannelFactory<T> factory = new ChannelFactory<T>("*");
T client = factory.CreateChannel();
bool success = false;
try
{
action(client);
((IClientChannel)client).Close();
factory.Close();
success = true;
}
catch (EndpointNotFoundException e)
{
LinkDBMvc.AppViewPage.apperror.LogError("WebService", e, "Check that the Web Service is running");
}
catch (CommunicationException e)
{
LinkDBMvc.AppViewPage.apperror.LogError("WebService", e, "Check that the Web Service is running");
}
catch (TimeoutException e)
{
LinkDBMvc.AppViewPage.apperror.LogError("WebService", e, "Check that the Web Service is running");
}
catch (Exception e)
{
LinkDBMvc.AppViewPage.apperror.LogError("WebService", e, "Check that the Web Service is running");
}
finally
{
if (!success)
{
// abort the channel
((IClientChannel)client).Abort();
factory.Abort();
}
}
}
}
}
I'm using castle windsor 3.1.0.0 for dependency injection in my MVC 3.0 application.
My container is setup to provide controllers like this:
container.Register(Classes.FromThisAssembly().BasedOn<IController>().LifestylePerWebRequest());
This seems to be working as I see a new controller instance created for every request. However according to the documenation: http://docs.castleproject.org/Windsor.LifeStyles.ashx, I must also place this in my web.config:
<httpModules>
<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor"/>
</httpModules>
which I don't have. What is the behavior of Castle Windsor if this module is missing? (The documentation says that In order to function properly per web request you must have this in your web config).
As far as I understand, the PerWebRequestLifestyle requires an IHttpModule so that it can piggy-back off the init method and the HttpApplication events such as BeginRequest.
The reason why everything seems to be working is because the module has been initialised and so the PerWebRequestLifestyle is functioning normally.
But why is that the case if you didn't include the registration module? I suspect that it is a legacy instruction and that the container will attempt a registration on its own, but this isn't documented explicitly.
If we take a peek inside CastleWindsor we find something called Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModuleRegistration. It has this method:
public static void Run()
{
Type type = Type.GetType("Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility, Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", false);
if (type == null)
{
return;
}
MethodInfo method = type.GetMethod("RegisterModule", BindingFlags.Static | BindingFlags.Public);
if (method == null)
{
return;
}
object[] objArray = new object[] { typeof(PerWebRequestLifestyleModule) };
method.Invoke(null, objArray);
}
What is DynamicModuleUtility? A quick search reveals a page written by K. Scott Allen called DynamicModuleUtility.
The DynamicModuleUtility will let you install an HTTP module into the ASP.NET pipeline without making any changes to web.config file.
This is only my speculation as to what's going on. You'd have to ask the creators of Castle Windsor for details on exactly how things are working.
I've got a legacy Web.Forms app that been partially rewritten to MVC. MVC part uses autofac as a dependency injection container.
MVC part have custom filter defined:
public class CustomActionFilter : ActionFilterAttribute
{
protected ILogger Logger { get; set; }
public CustomActionFilter(ILogger logger) { Logger = logger; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Logger.Log("OnActionExecuting");
}
}
It works fine when Web.Forms integration is disabled in web.config. Hovewer, when I try to use Web.Forms autofac integration, I've got the NullReferenceException related to AutofacFilterProvider somewhere in autofac internals (stack trace).
Global.asax.cs: http://pastebin.com/437Tnp0t
web.config: http://pastebin.com/5pU6SH6c
Note that CustomActionFilter is registered as global filter, thus it is registered with autofac:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(DependencyResolver.Current.GetService<CustomActionFilter>());
}
}
I've tried:
using separate containers for MVC and Web.Forms - same result
Use property injection instead of constructor - same result
Explicitly trigger dependencies resolution on web.forms pages (like this) - worked
So, the question is, are there any way to provide behind-the-scenes dependency resolution both to MVC and web.forms part. I'm new to autofac and somewhat new to dependency injection containers in general, so I might just miss something obvious.
Update: error has nothing to do with custom filters. If I remove all references to custom filters the bug behavior still the same, even the stack trace.
Actually there are two bugs? in Autofac which causing this behavior:
Bug #1: As side effect of the fix of Issue 351 the AutofacDependencyResolver needs to registered in the created Request bound LifeTimeScopes. The MVC intergration does this but the Winforms integration of course does not.
Bug? #2: Both the RequestLifetimeScopeProvider and the ContainerProvider stores the created ILifetimeScope with the same key HttpContext.Current.Items:
static ILifetimeScope LifetimeScope
{
get { return (ILifetimeScope)HttpContext.Current.Items[typeof(ILifetimeScope)]; }
set { HttpContext.Current.Items[typeof(ILifetimeScope)] = value; }
}
So there is a little bit race condition here because depending on which module gets executed first the WebForms or the MVC intergartion ILifetimeScope wins. So if the WebForms module wins the AutofacDependencyResolver won't be registered and you get the nice non descriptive exception.
Fix/workaround:
But there is an simple workaround: you just need to register the AutofacDependencyResolver in the ContainerProvider requestLifetimeConfiguration so no matter which one wins (WebForm vs. MVC) the AutofacDependencyResolver will be always registered:
var autofacDependencyResolver = new AutofacDependencyResolver(container);
DependencyResolver.SetResolver(autofacDependencyResolver);
_containerProvider = new ContainerProvider(container, requestContainerBuilder =>
requestContainerBuilder.RegisterInstance(autofacDependencyResolver)
.As<AutofacDependencyResolver>());
I'm having a class and interface like this in my wcf application IService1.cs
[ServiceContract]
public interface IService1
{
[OperationContract]
string insertValues(empInfo objInfo);
}
[DataContract]
public class empInfo
{
string _organizationName = string.Empty;
string _organizationAddr = string.Empty;
int? _totalemp;
}
And in Service1.svc.cs, i have implemented that interface.
public class Service1 : IService1
{
public string insertValues(empInfo objInfo)
{
.....
}
}
then i have created a empty mvc4 client application to consume this wcf service.
i have added the ServiceReference,Now its appear in the service reference folder as ServiceReference1.Then i did this
1. created a controller named Defalut1controller.
2. In this controller i try to add the following line
ServiceReference1.Service1Client proxy = new ServiceReference1.Service1Client();
inside the ActionResult. But unable to get the ServiceReference1 word.
its (ServiceReference1) appearing when i update my service like this
From - string insertValues(empInfo objInfo); - To - string insertValues(string objInfo);
and now i have build this wcf application, and update the service reference in my client mvc4 application. Now the
ServiceReference1.Service1Client proxy = new ServiceReference1.Service1Client();
line is enabled.
I have tried with the .net web application to consume the same, i can able to do without any problem, what i have missed with mvc4, please help. thanks in advance..
I got the answer, thanks to stackoverflow.
This is the solution:
Right click on Service Reference
Select Configure Service Reference
Select Reuse types in specified referenced assemblies
Just select everything except "Newtonsoft.json"
It worked for me as well.
The question itself and the problem you are facing is a bit unclear for me but have you actually tried exposing any public properties on your empInfo data contract? Cause right now you have only 3 private fields which will not be generated in the proxy code on the client side.
Microsoft has fixed this issue in this update: http://support.microsoft.com/kb/2750149