# Multi-Language OWIN

**URL:** <https://forum.dotvvm.com/t/multi-language-owin/99>\
**Category:** Discussion in English\
**Created:** [December 26, 2023, 2:40pm UTC](https://forum.dotvvm.com/t/multi-language-owin/99 "2023-12-26T14:40:07Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![wolfstudiodev](https://forum.dotvvm.com/letter_avatar_proxy/v4/letter/w/3be4f8/32.png) [@wolfstudiodev](https://forum.dotvvm.com/u/wolfstudiodev)\
**Post date:** [December 26, 2023, 2:40pm UTC](https://forum.dotvvm.com/t/multi-language-owin/99/1 "2023-12-26T14:40:07Z")

</div>

Hello,  
I’m trying to add multi-language to my DotVVM web app. I’m currently using OWIN.  
I have adapted my DotvvmStatup file for my default page:

```auto
config.RouteTable.Add("Default", "{Lang?:length(2)}", "Views/default.dothtml", new { Language = "en"}, presenterFactory: LocalizablePresenter.BasedOnParameter("Lang"));

```

and I’ve added to my MasterPageViewModel:

```auto
public string CurrentCulture => Thread.CurrentThread.CurrentCulture.Name;
[FromRoute("Lang")]
public string CurrentLanguage { get; set; }

```

I also created 2 RESX files:

- Resources/Web/Strings.resx
- Resources/Web/Strings.en-EN.resx

I tried running my web app with and without the “en” route and the page is displayed correctly (without the multi-language).

Using OWIN, how do I setup my page to use the correct resx file? I have checked the github repo but it’s using .net core.

I’m able to import the text from 1 resx file into my Page file using `{{resource: Web.Strings.NavbarMenu1}}`, but how can I use the correct language file checking the CurrentLanguage (dynamically)?

---

<div class="post-metadata">

**Author:** ![wolfstudiodev](https://forum.dotvvm.com/letter_avatar_proxy/v4/letter/w/3be4f8/32.png) [@wolfstudiodev](https://forum.dotvvm.com/u/wolfstudiodev)\
**Post date:** [January 2, 2024, 3:00pm UTC](https://forum.dotvvm.com/t/multi-language-owin/99/2 "2024-01-02T15:00:22Z")

</div>

I was able to make it work but I had to remove this from my head tag:

```auto
<head>
...
<title>SomeTitle {{value: !string.IsNullOrWhiteSpace(PageTitle) ? " - " + PageTitle : null}}</title>
...
</head>

```

throws: System.IndexOutOfRangeException. This PageTitle only works if I remove the Resources.resx file.  
Why is it happening?

---

<div class="post-metadata">

**Author:** ![exyi](https://forum.dotvvm.com/user_avatar/forum.dotvvm.com/exyi/32/9_2.png) [@exyi](https://forum.dotvvm.com/u/exyi)\
**Post date:** [January 2, 2024, 8:41pm UTC](https://forum.dotvvm.com/t/multi-language-owin/99/3 "2024-01-02T20:41:11Z")

</div>

That is indeed very strange. Could you please share the stack trace of the IndexOutOfRange exception? It’s likely going to be some silly bug on our side.

I’m sorry, I don’t know how localization works on .NET Framework. However, you name the resource file `en-EN` which is an invalid culture (AFAIK), if you want British English, it’s `en-GB`. Maybe this could be causing a problem, otherwise your code looks fine to me, the LocalizablePresenter should set the CurrentCulture and CurrentUICulture variables, can you please verify they are set to the expected value?

---

<div class="post-metadata">

**Author:** ![wolfstudiodev](https://forum.dotvvm.com/letter_avatar_proxy/v4/letter/w/3be4f8/32.png) [@wolfstudiodev](https://forum.dotvvm.com/u/wolfstudiodev)\
**Post date:** [January 2, 2024, 8:58pm UTC](https://forum.dotvvm.com/t/multi-language-owin/99/4 "2024-01-02T20:58:10Z")

</div>

I’m still learning about localizations too. I’ll fix this issue about en-EN first and see if it fixes it. I tried with “en” only too but it wasn’t working.

Thank you again!

---

<div class="post-metadata">

**Author:** ![wolfstudiodev](https://forum.dotvvm.com/letter_avatar_proxy/v4/letter/w/3be4f8/32.png) [@wolfstudiodev](https://forum.dotvvm.com/u/wolfstudiodev)\
**Post date:** [January 3, 2024, 10:52am UTC](https://forum.dotvvm.com/t/multi-language-owin/99/5 "2024-01-03T10:52:43Z")

</div>

I renamed the resx file to Texts.en-GB.resx and now

```auto
{{resource: Texts.HomePageHeaderButton}}

```

throws

> System.IndexOutOfRangeException

My DotvvmStartup file has the following route config:

```auto
config.RouteTable.Add("Default", "{Lang?:length(2)}", "Views/default.dothtml", presenterFactory: LocalizablePresenter.BasedOnParameter("Lang"));

```

The DefaultCulture is set to “pt-PT”, I tried with `new { Lang = "pt" }` and whitout it.

I already have Access modifier public for Texts.resx. I also tried to create a Texts.pt-PT.resx file too but still same error

---

<div class="post-metadata">

**Author:** ![exyi](https://forum.dotvvm.com/user_avatar/forum.dotvvm.com/exyi/32/9_2.png) [@exyi](https://forum.dotvvm.com/u/exyi)\
**Post date:** [January 4, 2024, 2:55pm UTC](https://forum.dotvvm.com/t/multi-language-owin/99/6 "2024-01-04T14:55:15Z")

</div>

Could you please share the exception stack trace (or the entire error page)?

---

<div class="post-metadata">

**Author:** ![wolfstudiodev](https://forum.dotvvm.com/letter_avatar_proxy/v4/letter/w/3be4f8/32.png) [@wolfstudiodev](https://forum.dotvvm.com/u/wolfstudiodev)\
**Post date:** [January 5, 2024, 10:18am UTC](https://forum.dotvvm.com/t/multi-language-owin/99/7 "2024-01-05T10:18:12Z")

</div>

```auto
System.IndexOutOfRangeExceptionÍndice fora dos limites da matriz.
{
ClassName:"System.IndexOutOfRangeException"
Message:"Índice fora dos limites da matriz."
Data:null
InnerException:null
HelpURL:null
StackTraceString:" em FastExpressionCompiler.ImTools.FHashMap.GetOrAddValueRefByHash[K,V,TEq,TEntries](FHashMap`4& map, K key, Boolean& found)\r\n em FastExpressionCompiler.ImTools.FHashMap.GetOrAddValueRef[K,V,TEq,TEntries](FHashMap`4& map, K key, Boolean& found)\r\n em FastExpressionCompiler.Tools.FindConvertOperator(Type type, Type sourceType, Type targetType)\r\n em FastExpressionCompiler.ExpressionCompiler.EmittingVisitor.TryEmitConvert(UnaryExpression expr, IReadOnlyList`1 paramExprs, ILGenerator il, ClosureInfo& closure, CompilerFlags setup, ParentFlags parent)\r\n em FastExpressionCompiler.ExpressionCompiler.EmittingVisitor.TryEmit(Expression expr, IReadOnlyList`1 paramExprs, ILGenerator il, ClosureInfo& closure, CompilerFlags setup, ParentFlags parent, Int32 byRefIndex)\r\n em FastExpressionCompiler.ExpressionCompiler.EmittingVisitor.TryEmitAssignToParameterOrVariable(ParameterExpression left, Expression right, ExpressionType nodeType, Boolean isPost, Type exprType, IReadOnlyList`1 paramExprs, ILGenerator il, ClosureInfo& closure, CompilerFlags setup, ParentFlags parent, Int32 resultVar)\r\n em FastExpressionCompiler.ExpressionCompiler.EmittingVisitor.TryEmitArithmeticAndOrAssign(Expression left, Expression right, Type exprType, ExpressionType nodeType, Boolean isPost, IReadOnlyList`1 paramExprs, ILGenerator il, ClosureInfo& closure, CompilerFlags setup, ParentFlags parent)\r\n em FastExpressionCompiler.ExpressionCompiler.EmittingVisitor.TryEmit(Expression expr, IReadOnlyList`1 paramExprs, ILGenerator il, ClosureInfo& closure, CompilerFlags setup, ParentFlags parent, Int32 byRefIndex)\r\n em FastExpressionCompiler.ExpressionCompiler.EmittingVisitor.TryEmit(Expression expr, IReadOnlyList`1 paramExprs, ILGenerator il, ClosureInfo& closure, CompilerFlags setup, ParentFlags parent, Int32 byRefIndex)\r\n em FastExpressionCompiler.ExpressionCompiler.TryCompileBoundToFirstClosureParam(Type delegateType, Expression bodyExpr, IReadOnlyList`1 paramExprs, Type[] closurePlusParamTypes, Type returnType, CompilerFlags flags)\r\n em FastExpressionCompiler.ExpressionCompiler.CompileFast[TDelegate](LambdaExpression lambdaExpr, Boolean ifFastFailedReturnNull, CompilerFlags flags)\r\n em DotVVM.Framework.Compilation.ViewCompiler.ViewCompilingVisitor.VisitView(ResolvedTreeRoot view)\r\n em DotVVM.Framework.Compilation.ViewCompiler.DefaultViewCompiler.<>c __DisplayClass6_0.<CompileViewCore>b__ 0()\r\n em DotVVM.Framework.Compilation.ViewCompiler.DefaultViewCompiler.<>c __DisplayClass9_0.<CompileView>b__ 0()\r\n em DotVVM.Framework.Compilation.DefaultControlBuilderFactory.<>c __DisplayClass13_1.<CreateControlBuilder>b__ 1()\r\n em System.Lazy`1.CreateValue()\r\n em System.Lazy`1.LazyInitValue()\r\n em DotVVM.Framework.Runtime.DefaultDotvvmViewBuilder.BuildView(IDotvvmRequestContext context)\r\n em DotVVM.Framework.Hosting.DotvvmPresenter.<ProcessRequestCore>d__30.MoveNext()\r\n--- Fim do rastreio da pilha da localização anterior em que a excepção foi emitida ---\r\n em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n--- Fim do rastreio da pilha da localização anterior em que a excepção foi emitida ---\r\n em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n em System.Lazy`1.LazyInitValue()\r\n em DotVVM.Framework.Compilation.DefaultControlBuilderFactory.<>c__DisplayClass13_1.<CreateControlBuilder>b__2()\r\n--- Fim do rastreio da pilha da localização anterior em que a excepção foi emitida ---\r\n em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n em DotVVM.Framework.Hosting.Middlewares.DotvvmRoutingMiddleware.<Handle>d__3.MoveNext()\r\n--- Fim do rastreio da pilha da localização anterior em que a excepção foi emitida ---\r\n em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n em DotVVM.Framework.Hosting.Middlewares.DotvvmRoutingMiddleware.<Handle>d__3.MoveNext()\r\n--- Fim do rastreio da pilha da localização anterior em que a excepção foi emitida ---\r\n em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n em DotVVM.Framework.Hosting.DotvvmMiddleware.<Invoke>d__5.MoveNext()"
RemoteStackTraceString:null
RemoteStackIndex:0
ExceptionMethod:"8\nGetOrAddValueRefByHash\nFastExpressionCompiler, Version=4.0.1.0, Culture=neutral, PublicKeyToken=dfbf2bd50fcf7768\nFastExpressionCompiler.ImTools.FHashMap\nV& GetOrAddValueRefByHash[K,V,TEq,TEntries](FastExpressionCompiler.ImTools.FHashMap`4[K,V,TEq,TEntries] ByRef, K, Boolean ByRef)"
HResult:-2146233080
Source:"FastExpressionCompiler"
WatsonBuckets:null
}
MethodInfo FastExpressionCompiler.Tools.FindConvertOperator(Type type, Type sourceType, Type targetType)
bool FastExpressionCompiler.ExpressionCompiler+EmittingVisitor.TryEmitConvert(UnaryExpression expr, IReadOnlyList<ParameterExpression> paramExprs, ILGenerator il, ref ClosureInfo closure, CompilerFlags setup, ParentFlags parent)
bool FastExpressionCompiler.ExpressionCompiler+EmittingVisitor.TryEmit(Expression expr, IReadOnlyList<ParameterExpression> paramExprs, ILGenerator il, ref ClosureInfo closure, CompilerFlags setup, ParentFlags parent, int byRefIndex)
bool FastExpressionCompiler.ExpressionCompiler+EmittingVisitor.TryEmitAssignToParameterOrVariable(ParameterExpression left, Expression right, ExpressionType nodeType, bool isPost, Type exprType, IReadOnlyList<ParameterExpression> paramExprs, ILGenerator il, ref ClosureInfo closure, CompilerFlags setup, ParentFlags parent, int resultVar)
bool FastExpressionCompiler.ExpressionCompiler+EmittingVisitor.TryEmitArithmeticAndOrAssign(Expression left, Expression right, Type exprType, ExpressionType nodeType, bool isPost, IReadOnlyList<ParameterExpression> paramExprs, ILGenerator il, ref ClosureInfo closure, CompilerFlags setup, ParentFlags parent)
bool FastExpressionCompiler.ExpressionCompiler+EmittingVisitor.TryEmit(Expression expr, IReadOnlyList<ParameterExpression> paramExprs, ILGenerator il, ref ClosureInfo closure, CompilerFlags setup, ParentFlags parent, int byRefIndex) x 2
object FastExpressionCompiler.ExpressionCompiler.TryCompileBoundToFirstClosureParam(Type delegateType, Expression bodyExpr, IReadOnlyList<ParameterExpression> paramExprs, Type[] closurePlusParamTypes, Type returnType, CompilerFlags flags)
TDelegate FastExpressionCompiler.ExpressionCompiler.CompileFast<TDelegate>(LambdaExpression lambdaExpr, bool ifFastFailedReturnNull, CompilerFlags flags)
void DotVVM.Framework.Compilation.ViewCompiler.ViewCompilingVisitor.VisitView(ResolvedTreeRoot view)
ValueTuple<ControlBuilderDescriptor, Func<Func<IControlBuilderFactory, IServiceProvider, DotvvmControl>>> DotVVM.Framework.Compilation.ViewCompiler.DefaultViewCompiler.CompileViewCore(string sourceCode, string fileName)+() => { }
ValueTuple<ControlBuilderDescriptor, Func<IControlBuilder>> DotVVM.Framework.Compilation.ViewCompiler.DefaultViewCompiler.CompileView(string sourceCode, string fileName)+() => { }
ValueTuple<ControlBuilderDescriptor, Lazy<IControlBuilder>> DotVVM.Framework.Compilation.DefaultControlBuilderFactory.CreateControlBuilder(MarkupFile file)+() => { }
Boxed System.Lazy<T>.CreateValue()
T System.Lazy<T>.LazyInitValue()
DotvvmView DotVVM.Framework.Runtime.DefaultDotvvmViewBuilder.BuildView(IDotvvmRequestContext context)
async Task DotVVM.Framework.Hosting.DotvvmPresenter.ProcessRequestCore(IDotvvmRequestContext context)
T System.Lazy<T>.LazyInitValue()
ValueTuple<ControlBuilderDescriptor, Lazy<IControlBuilder>> DotVVM.Framework.Compilation.DefaultControlBuilderFactory.CreateControlBuilder(MarkupFile file)+() => { }
async Task<bool> DotVVM.Framework.Hosting.Middlewares.DotvvmRoutingMiddleware.Handle(IDotvvmRequestContext context) x 2
async Task DotVVM.Framework.Hosting.DotvvmMiddleware.Invoke(IOwinContext context)

```

---

<div class="post-metadata">

**Author:** ![wolfstudiodev](https://forum.dotvvm.com/letter_avatar_proxy/v4/letter/w/3be4f8/32.png) [@wolfstudiodev](https://forum.dotvvm.com/u/wolfstudiodev)\
**Post date:** [January 18, 2024, 11:15am UTC](https://forum.dotvvm.com/t/multi-language-owin/99/8 "2024-01-18T11:15:19Z")

</div>

Any idea about this? I’m kinda lost about how to solve this issue.

---

<div class="post-metadata">

**Author:** ![exyi](https://forum.dotvvm.com/user_avatar/forum.dotvvm.com/exyi/32/9_2.png) [@exyi](https://forum.dotvvm.com/u/exyi)\
**Post date:** [January 19, 2024, 12:27pm UTC](https://forum.dotvvm.com/t/multi-language-owin/99/9 "2024-01-19T12:27:21Z")

</div>

Hello, the exception is coming from FastExpressionCompiler. Which version are you using? Could you please try changing the version, minimal supported version by DotVVM is `3.3.4`.

I have just asked in the FEC discussions if Maksim has any idea. Since, I’m unable to replicate the crash, it’s hard to help any further 😕

---

<div class="post-metadata">

**Author:** ![wolfstudiodev](https://forum.dotvvm.com/letter_avatar_proxy/v4/letter/w/3be4f8/32.png) [@wolfstudiodev](https://forum.dotvvm.com/u/wolfstudiodev)\
**Post date:** [January 19, 2024, 5:27pm UTC](https://forum.dotvvm.com/t/multi-language-owin/99/10 "2024-01-19T17:27:33Z")

</div>

I’m using: DotVVM.Core 4.2.3, DotVVM.Owin 4.2.3 and FastExpressionCompiler vs 4.0.1

The project was previously using DotVVM 3.X

---

<div class="post-metadata">

**Author:** ![wolfstudiodev](https://forum.dotvvm.com/letter_avatar_proxy/v4/letter/w/3be4f8/32.png) [@wolfstudiodev](https://forum.dotvvm.com/u/wolfstudiodev)\
**Post date:** [January 21, 2024, 7:24pm UTC](https://forum.dotvvm.com/t/multi-language-owin/99/11 "2024-01-21T19:24:47Z")

</div>

I was able to make it work by creating a new project with Dotvvm 4.X already and the previous code and it worked after renaming the files to Texts.en.resx instead of Texts.en-GB.resx (for exemple). My RouteTable has `"{Lang?:length(2)}"` so I supposed the file only needs “en” instead of “en-GB”.

For dynamic labels like data coming from database, the only way is storing the data for each language in the database then look for the CurrentCulture to select from table?

---

<div class="post-metadata">

**Author:** ![exyi](https://forum.dotvvm.com/user_avatar/forum.dotvvm.com/exyi/32/9_2.png) [@exyi](https://forum.dotvvm.com/u/exyi)\
**Post date:** [January 22, 2024, 1:37pm UTC](https://forum.dotvvm.com/t/multi-language-owin/99/12 "2024-01-22T13:37:26Z")

</div>

> For dynamic labels like data coming from database, the only way is storing the data for each language in the database then look for the CurrentCulture to select from table?

Yes, basically.

Regarding the FastExpressionCompiler crash, Maksim Volkau released a new version (4.1.0) which fix the issue.

---

<div class="post-metadata">

**Author:** ![wolfstudiodev](https://forum.dotvvm.com/letter_avatar_proxy/v4/letter/w/3be4f8/32.png) [@wolfstudiodev](https://forum.dotvvm.com/u/wolfstudiodev)\
**Post date:** [January 23, 2024, 3:58pm UTC](https://forum.dotvvm.com/t/multi-language-owin/99/13 "2024-01-23T15:58:49Z")

</div>

Maybe I missed some stuffs while migrating to Dotvvm v4.X too…

In case we want to display different urls for different languages (for exemple “/home” for EN and “/inicio” for PT), is it possible to do it from the RouteTable config block ?

config.RouteTable.Add(“Eventos”, “{Lang?:length(2)}/eventos”, “Views/Eventos.dothtml”, new { Lang = “pt” }, presenterFactory: \_presenterFactory);

I wanted to display “en/events” and “pt/eventos” for each culture but I’m not sure how I can do it.

---

<div class="post-metadata">

**Author:** ![exyi](https://forum.dotvvm.com/user_avatar/forum.dotvvm.com/exyi/32/9_2.png) [@exyi](https://forum.dotvvm.com/u/exyi)\
**Post date:** [January 24, 2024, 11:20am UTC](https://forum.dotvvm.com/t/multi-language-owin/99/14 "2024-01-24T11:20:49Z")

</div>

I don’t know what is the best way to do this, but one way would be to register additional routes with contant `Lang` parameters:

```csharp
config.RouteTable.Add(“Eventos_pt”, “{Lang:regex(pt)}/eventos”, ...);
config.RouteTable.Add(“Eventos_en”, “{Lang:regex(en)}/home”, ...);

```
