Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Injecting IViewLocalizer into Razor Page causing IndexOutOfRangeException. #6694

Closed
pranavkm opened this issue Aug 22, 2017 · 7 comments
Closed
Assignees

Comments

@pranavkm
Copy link
Contributor

From aspnet/Localization#407

Title

When injecting IViewLocalizer using @inject directive into any Razor Page (not using MVC), System.IndexOutOfRangeException: Index was outside the bounds of the array. will be thrown.

Minimal repro steps

See this repo.

Expected result

The page should load successfully without ant error.

Actual result

The following error was thrown:

fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
      An unhandled exception has occurred: Index was outside the bounds of the array.
System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Microsoft.AspNetCore.Mvc.Localization.ViewLocalizer.BuildBaseName(String path)
   at Microsoft.AspNetCore.Mvc.Localization.ViewLocalizer.Contextualize(ViewContext viewContext)
   at Microsoft.AspNetCore.Mvc.Razor.Internal.RazorPagePropertyActivator.<>c__DisplayClass8_0.<CreateActivateInfo>b__1(ViewContext context)
   at Microsoft.Extensions.Internal.PropertyActivator`1.Activate(Object instance, TContext context)
   at Microsoft.AspNetCore.Mvc.Razor.Internal.RazorPagePropertyActivator.Activate(Object page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageFactoryProvider.<>c__DisplayClass4_0.<CreatePageFactory>b__0(PageContext pageContext, ViewContext viewContext)
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.<InvokeHandlerMethodAsync>d__29.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.<InvokeNextPageFilterAsync>d__31.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.<InvokeInnerFilterAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeFilterPipelineAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>d__6.MoveNext()
@pranavkm
Copy link
Contributor Author

Looks like the issue steams from us not setting the ViewContext.ExecutingFilePath when rendering a Razor Page. One possible workaround until we fix this would be to replace the Page Factory provider to set the value:

using System;
using System.Diagnostics;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;

namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
{
    public class LocFixPageFactoryProvider : DefaultPageFactoryProvider
    {
        public LocFixPageFactoryProvider(
            IPageActivatorProvider pageActivator,
            IModelMetadataProvider metadataProvider,
            IUrlHelperFactory urlHelperFactory,
            IJsonHelper jsonHelper,
            DiagnosticSource diagnosticSource,
            HtmlEncoder htmlEncoder,
            IModelExpressionProvider modelExpressionProvider)
            : base(pageActivator, metadataProvider, urlHelperFactory, jsonHelper, diagnosticSource, htmlEncoder, modelExpressionProvider)
        {
        }

        public override Func<PageContext, ViewContext, object> CreatePageFactory(CompiledPageActionDescriptor actionDescriptor)
        {
            var result = base.CreatePageFactory(actionDescriptor);
            return (pageContext, viewContext) =>
            {
                viewContext.ExecutingFilePath = actionDescriptor.RelativePath;
                return result(pageContext, viewContext);
            };
        }
    }
}

And change your Startup to use this service:

services.AddSingleton<IPageFactoryProvider, LocFixPageFactoryProvider>();
services.AddMvc().

@Eilon \ @rynowak would this be a 2.0.1 worthy? The workaround isn't very pleasant.

@zulfahmi93
Copy link

Thanks for the workaround.

However, I still unable to show the localized string. I have done the following:

  1. services.AddLocalization(options => options.ResourcesPath = "Resources");
  2. services.AddMvc().AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix, options => options.ResourcesPath = "Resources")
  3. Create Resources folder.
  4. Create RESX file inside the folder and name is as Pages.Index.en.resx by following the documentation here.
  5. Inside Pages/Index.cshtml file, I have set: ViewData["Title"] = Localizer["Home Page"];
  6. When running the project and navigate to the home page, the page title still show as 'Home Page' not 'Home Page in English' as I set in the RESX file.

For repro project, please see here and checkout to branch fix-test.

@pranavkm
Copy link
Contributor Author

@Eilon self-assigning this for further investigation.

@pranavkm
Copy link
Contributor Author

@zulfahmi93 I tried your fix-test branch and it prints the right localized string. Could you verify you're not running in to some sort of browser caching oddity?

@zulfahmi93
Copy link

@pranavkm sorry my bad. I tried to rerun it and now it's already working. Thanks for your help!

@pranavkm
Copy link
Contributor Author

Thanks @zulfahmi93. We'll use this work item to track the actual fix.

@pranavkm
Copy link
Contributor Author

@Eilon - this is a bug.

@Eilon Eilon added bug and removed investigate labels Aug 28, 2017
@Eilon Eilon added this to the 2.1.0 milestone Aug 28, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants