{"action":"reopened","issue":{"url":"https://api.github.com/repos/aspnet/Localization/issues/203","labels_url":"https://api.github.com/repos/aspnet/Localization/issues/203/labels{/name}","comments_url":"https://api.github.com/repos/aspnet/Localization/issues/203/comments","events_url":"https://api.github.com/repos/aspnet/Localization/issues/203/events","html_url":"https://github.com/aspnet/Localization/issues/203","id":127876706,"number":203,"title":"Custom Cultures not working with RequestLocalizationMiddleware","user":{"login":"mmoron","id":3398332,"avatar_url":"https://avatars.githubusercontent.com/u/3398332?v=3","gravatar_id":"","url":"https://api.github.com/users/mmoron","html_url":"https://github.com/mmoron","followers_url":"https://api.github.com/users/mmoron/followers","following_url":"https://api.github.com/users/mmoron/following{/other_user}","gists_url":"https://api.github.com/users/mmoron/gists{/gist_id}","starred_url":"https://api.github.com/users/mmoron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mmoron/subscriptions","organizations_url":"https://api.github.com/users/mmoron/orgs","repos_url":"https://api.github.com/users/mmoron/repos","events_url":"https://api.github.com/users/mmoron/events{/privacy}","received_events_url":"https://api.github.com/users/mmoron/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-01-21T09:06:52Z","updated_at":"2016-01-21T13:25:53Z","closed_at":null,"body":"### Title\r\nCustom Cultures not working with `RequestLocalizationMiddleware`\r\n\r\n### Functional impact\r\nIt is impossible to use custom settings for Cultures when using `RequestLocalizationMiddleware`\r\n\r\n### Minimal repro steps\r\n- Create custom CultureProvider\r\n```\r\npublic class SampleCultureProvider : RequestCultureProvider\r\n{\r\n    public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)\r\n    {\r\n        var providerResultCulture = new ProviderCultureResult(\"en-US\");\r\n        return Task.FromResult(providerResultCulture);\r\n    }\r\n}\r\n```\r\n- Create custom localization options (changed CurrencySymbol in this example)\r\n```\r\nprivate RequestLocalizationOptions CreateLocalizationOptions()\r\n{\r\n    var supportedCulturesList = new List<CultureInfo>\r\n    {\r\n        new CultureInfo(\"en-US\", true) { NumberFormat = { CurrencySymbol = \"kr\" } }\r\n    };\r\n\r\n    var localizationOptions = new RequestLocalizationOptions\r\n    {\r\n        SupportedCultures = supportedCulturesList,\r\n        SupportedUICultures = supportedCulturesList\r\n    };\r\n            \r\n    localizationOptions.RequestCultureProviders.Clear();\r\n    localizationOptions.RequestCultureProviders.Add(new SampleCultureProvider());\r\n    return localizationOptions;\r\n}\r\n```\r\n- Add RequestLocalizationMiddleware using these options\r\n```\r\npublic void Configure(IApplicationBuilder app)\r\n{\r\n    app.UseIISPlatformHandler();\r\n\r\n    var globalizationOptions = this.CreateLocalizationOptions();\r\n    app.UseRequestLocalization(globalizationOptions, new RequestCulture(new CultureInfo(\"en-GB\")));\r\n\r\n    (...)\r\n}\r\n```\r\n- display text using currency formatting\r\n```\r\npublic void Configure(IApplicationBuilder app)\r\n{\r\n    (...)\r\n    app.Run(async (context) =>\r\n    {\r\n        await context.Response.WriteAsync(123.ToString(\"C\"));\r\n    });\r\n}\r\n```\r\nSample solution reproducing this bug attached: [RequestLocalizationMiddlewareBug.zip](https://github.com/aspnet/Localization/files/98886/RequestLocalizationMiddlewareBug.zip)\r\n\r\n### Expected result\r\nChanged currency symbol should be displayed: **kr123.00**\r\n\r\n### Actual result\r\nDefault currency symbol is used: **$123.00**\r\n\r\n### Further technical details\r\nProblem is - most likely - caused by `CultureInfoCache`. When `GetCultureInfo` is called `supportedCultures` are checked to see whether requested culture is supported. \r\n\r\n```\r\nif (name == null || supportedCultures == null ||\r\n    !supportedCultures.Any(supportedCulture => string.Equals(supportedCulture.Name, name, StringComparison.OrdinalIgnoreCase)))\r\n{\r\n    return null;\r\n}\r\n```\r\nLater on, however, instead of adding provided culture to the cache new culture is created with a given name and added\r\n```\r\nvar entry = _cache.GetOrAdd(name, n =>\r\n{\r\n    try\r\n    {\r\n        return new CacheEntry(CultureInfo.ReadOnly(new CultureInfo(n)));\r\n    }\r\n    catch (CultureNotFoundException)\r\n    {\r\n        (...)\r\n    }\r\n});\r\n```\r\nI guess that using\r\n```\r\nvar culture = supportedCultures.Single(supportedCulture => string.Equals(supportedCulture.Name, name, StringComparison.OrdinalIgnoreCase));\r\nreturn new CacheEntry(CultureInfo.ReadOnly(culture));\r\n\r\n```\r\ninstead of\r\n```\r\nreturn new CacheEntry(CultureInfo.ReadOnly(new CultureInfo(n)));\r\n```\r\nshould fix this"}}