Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception when requesting the first view #29

Closed
cervengoc opened this issue Oct 2, 2019 · 15 comments
Closed

Exception when requesting the first view #29

cervengoc opened this issue Oct 2, 2019 · 15 comments
Labels

Comments

@cervengoc
Copy link

Hi,

In the past few days I've migrated an existing MVC5+Owin+SignalR (latest) web application to use latest Autofac and the integration libraries.

After solving the first few issues, I get the following exception which I'm unable to sort out.

Autofac.Core.DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'System.Web.Mvc.AjaxHelper`1[System.Object]' can be invoked with the available services and parameters:
Cannot resolve parameter 'System.Web.Mvc.IViewDataContainer viewDataContainer' of constructor 'Void .ctor(System.Web.Mvc.ViewContext, System.Web.Mvc.IViewDataContainer)'.
Cannot resolve parameter 'System.Web.Mvc.IViewDataContainer viewDataContainer' of constructor 'Void .ctor(System.Web.Mvc.ViewContext, System.Web.Mvc.IViewDataContainer, System.Web.Routing.RouteCollection)'.

I'm registering everything using the sample code from the docs.

private void RegisterAutofacMVC(ContainerBuilder builder)
{
    // Register your MVC controllers. (MvcApplication is the name of
    // the class in Global.asax.)
    builder.RegisterControllers(typeof(AccountController).Assembly);

    // OPTIONAL: Register model binders that require DI.
    builder.RegisterModelBinders(typeof(AccountController).Assembly);
    builder.RegisterModelBinderProvider();

    // OPTIONAL: Register web abstractions like HttpContextBase.
    builder.RegisterModule<AutofacWebTypesModule>();

    // OPTIONAL: Enable property injection in view pages.
    builder.RegisterSource(new ViewRegistrationSource());

    // OPTIONAL: Enable property injection into action filters.
    builder.RegisterFilterProvider();
}

And I have some setup code using some of my custom solutions.

private void SetupMVC(IAppBuilder app, IContainer container)
{
    DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(container));

    app.UseAutofacMiddleware(container);
    app.UseAutofacMvc();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    AreaRegistration.RegisterAllAreas();
    ModelBinders.Binders.DefaultBinder = new CustomModelBinder();

    ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().FirstOrDefault());
    ValueProviderFactories.Factories.Add(new JsonNetValueProviderFactory());
}

Also, I have some ASP.NET SignalR hubs which require me to use Owin, and I'm trying to use Autofac there too.

private void RegisterAutofacSignalR(ContainerBuilder builder)
{
    builder.RegisterHubs(typeof(TermekBetoltesHub).Assembly);
}

private void SetupSignalR(IAppBuilder app, IContainer container)
{
    var hubConfiguration = new HubConfiguration()
    {
        Resolver = new AutofacDependencyResolver(container),
        EnableDetailedErrors = true
    };

    app.MapSignalR(hubConfiguration);

    // To add custom HubPipeline modules, you have to get the HubPipeline
    // from the dependency resolver, for example:
    var hubPipeline = hubConfiguration.Resolver.Resolve<IHubPipeline>();
    hubPipeline.AddModule(new CustomErrorModule());
}

I have a quite strong feeling that I'm mixing a few concepts but I cannot wrap my head around all these stuff and make them work together nicely.

Could anyone provide me some hints or tips what I should check?

@alistairjevans
Copy link
Member

Is your entire project going through OWIN, or are you running OWIN on top of the normal ASP.NET stack just for SignalR?

I ask because you appear to have the normal Autofac MVC registration, as well as the OWIN registration.

@cervengoc
Copy link
Author

cervengoc commented Oct 2, 2019

I'm using Owin only for SignalR. As far as I know the classic MVC5 cannot work on top of Owin, and requires the classic System.Web hosting environment and IIS.

I know this is not a fortunate setup, however I could not find a better way back then.

@cervengoc
Copy link
Author

FYI I tried removing the OWIN-based two lines

app.UseAutofacMiddleware(container);
app.UseAutofacMvc();

The issue is still the same.

@alistairjevans
Copy link
Member

Does the error still happen if you comment out the view page property injection?

    // OPTIONAL: Enable property injection in view pages.
    builder.RegisterSource(new ViewRegistrationSource());

@cervengoc
Copy link
Author

Yes, that was the point. After commenting it out, everything seems to work fine at first glance. And also, it seems like those two lines in my previous comment are really not needed in this setup.

@alistairjevans
Copy link
Member

I suspect you may still need the app.UseAutofacMiddleware to allow SignalR hubs to be loaded from your container (or at least, I have it in my app that does the same thing as yours).

You shouldn't need the app.UseAutofacMvc though, because you aren't serving MVC content over OWIN.

I still feel that there's something up here, adding the ViewRegistrationSource shouldn't cause everything to break like that.

Do your Views derive from a custom type, or directly from WebViewPage?

@cervengoc
Copy link
Author

I don't have anything special as far as I can tell. This is my Views\Web.config.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="ZbOriflame.Web" />
        <add namespace="Vertesz.Web"/>
      </namespaces>
    </pages>
  </system.web.webPages.razor>
  <appSettings>
    <add key="webpages:Enabled" value="false" />
  </appSettings>
  <system.web>
    <httpHandlers>
      <add path="*" verb="*" type="System.Web.HttpNotFoundHandler" />
    </httpHandlers>
    <!--
        Enabling request validation in view pages would cause validation to occur
        after the input has already been processed by the controller. By default
        MVC performs request validation before a controller processes the input.
        To change this behavior apply the ValidateInputAttribute to a
        controller or action.
    -->
    <pages validateRequest="false" pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <controls>
        <add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
      </controls>
    </pages>
    <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <remove name="BlockViewHandler" />
      <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
    </handlers>
  </system.webServer>
</configuration>

@alistairjevans
Copy link
Member

Ok, thanks; I wonder if there may actually be a defect with the ViewRegistrationSource, in that it doesn't support AjaxHelper properly.

Do you have a recreating project you can upload?

@alistairjevans
Copy link
Member

Just to update; I've had a go at re-creating this issue myself, but I can't get the error you're seeing when you have the ViewRegistrationSource in place.

If you are able to provide a sample project that would be great, because I still feel like there's something going on here; until then though I'm going to park this.

@cervengoc
Copy link
Author

Sorry for the delay. Unfortunately I don't have too much time for creating a repro project. However, I can try to reduce this project and remove all private information to reproduce the issue. Give me a few days to prepare it.

@alistairjevans
Copy link
Member

Thanks @cervengoc, I appreciate the effort.

@lars-nielsen
Copy link

@cervengoc

Do you by any chance use builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource())

I just ran into the same problem you described when migrating from Unity to Autofac and enabling AnyConcreteTypeNotAlreadyRegisteredSource

@cervengoc
Copy link
Author

@lars-nielsen Yes indeed I do use this special source. Unfortunately I still don't have the time to prepare a repro project, so I hope this additional information can help investigating the issue.

@tillig
Copy link
Member

tillig commented Mar 2, 2022

It's been a little over two years and we don't have a repro here. Given the limited time of the owners team to address core Autofac and all the integration libraries, without a repro we won't be able to pursue this. I'm going to close the issue and if a repro becomes available we can investigate.

@tillig tillig closed this as completed Mar 2, 2022
@dwillbarron
Copy link

Hi all!

I'm two years late to the party, but I wanted to chime in since I also had this issue and found an appropriate workaround for it. Like some of the others here, I was migrating an MVC project from Unity to Autofac, and needed to use AnyConcreteTypeNotAlreadyRegisteredSource due to the amount of code that depends on this behavior. I ran into the same exception as mentioned in the original issue.

While I don't fully understand the mechanisms involved here, it looks like the cause is that MVC is, for some reason, trying to use Autofac to resolve dependencies in some internal framework code. The workaround here is to provide a predicate that prevents Autofac from trying to resolve these objects:

_builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(type => !type.IsInNamespace("System")));
// Alternatively, you can check to see if types *do* belong to your project's namespace--for us, this wasn't an option due to legacy spaghetti.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants