Skip to content
This repository has been archived by the owner. It is now read-only.

Get segment from mapped route for CustomRequestCultureProvider #122

Closed
Codenator81 opened this issue Oct 20, 2015 · 29 comments
Closed

Get segment from mapped route for CustomRequestCultureProvider #122

Codenator81 opened this issue Oct 20, 2015 · 29 comments
Assignees

Comments

@Codenator81
Copy link

@Codenator81 Codenator81 commented Oct 20, 2015

I tested after

app.UseMvc(routes =>

in startup class app.UseRequestLocalization not work.
For example user want culture segment been in:

routes.MapRoute(
                    name: "transRoute",
                    template: "{controller=Home}/{culture=en-US}/{action=Index}/{id?}");

So how I can get {culture} segment to find route match?

This is all way not processed:

options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context =>
            {
                var routeContext = new RouteContext(context); // IsHandled all ways false

Thanks Alex

@BenjiZombie
Copy link

@BenjiZombie BenjiZombie commented Oct 20, 2015

What I did was create a RouteRequestCultureProvider instead.

namespace Microsoft.AspNet.Localization
{
    /// <summary>
    /// Determines the culture information for a request via values in the route.
    /// </summary>
    public class RouteRequestCultureProvider : RequestCultureProvider
    {
        #region Overrides of RequestCultureProvider

        public override Task<RequestCulture> DetermineRequestCulture(HttpContext httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            var request = httpContext.Request;
            if (!request.Path.HasValue)
            {
                return Task.FromResult((RequestCulture) null);
            }

            var cultureValue = Regex.Match(
                request.Path.Value,
                @"^/([a-z]{2})",
                RegexOptions.IgnoreCase);

            if (cultureValue.Success)
            {
                var culture = CultureInfoCache.GetCultureInfo(cultureValue.Groups[1].Value);
                var uiCulture = CultureInfoCache.GetCultureInfo(cultureValue.Groups[1].Value);

                if (culture == null || uiCulture == null)
                {
                    return Task.FromResult((RequestCulture) null);
                }

                var requestCulture = new RequestCulture(culture, uiCulture);
                requestCulture = ValidateRequestCulture(requestCulture);

                return Task.FromResult(requestCulture);
            }

            return Task.FromResult((RequestCulture) null);
        }

        #endregion
    }
}

Then simply register it in the Configure method:

// Add localization to the request pipeline.
var requestLocalizationOptions = new RequestLocalizationOptions
{
    SupportedCultures = new List<CultureInfo>
    {
        new CultureInfo("en"),
        new CultureInfo("fr"),
        new CultureInfo("es")
    },
    SupportedUICultures = new List<CultureInfo>
    {
        new CultureInfo("en"),
        new CultureInfo("fr"),
        new CultureInfo("es")
    }
};
requestLocalizationOptions.RequestCultureProviders.Insert(2, new RouteRequestCultureProvider
{
    Options = requestLocalizationOptions
});
app.UseRequestLocalization(requestLocalizationOptions);

My route mapping is different from yours, but you can easily modify the code to fit your needs

// Add MVC to the request pipeline.
app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{culture?}/{controller}/{action}/{id?}",
        defaults: new { culture = "en", controller = "Home", action = "Index" });
});
@Codenator81
Copy link
Author

@Codenator81 Codenator81 commented Oct 20, 2015

@BenjiZombie thanks for good example.
I do similar in my code https://github.com/WeebDo/WeebDo.CMF/blob/master/src/WeebDoCMF/Startup.cs#L190
I think there no way to get segment {culture} from route for now before

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{culture?}/{controller}/{action}/{id?}",
        defaults: new { culture = "en", controller = "Home", action = "Index" });
});
@Codenator81
Copy link
Author

@Codenator81 Codenator81 commented Oct 20, 2015

@hishamco Thanks I implement my code based on your links 👍
Here question more about how get culture as I do in MVC 5 from Controller

RouteData.Values["culture"] as string;
@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 20, 2015

@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 20, 2015

What is the value of ViewBag.Trans when you print it out, because I don't know what is the issue in your sample

@Codenator81
Copy link
Author

@Codenator81 Codenator81 commented Oct 20, 2015

@hishamco There everything work great. My issue is how get route segment from route template before UseMVC middleware. But I think it is not possible. I will try different approach.

@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 20, 2015

Why you need it before MVC middleware?!! if that's the case i will try to look in your sample

@Codenator81
Copy link
Author

@Codenator81 Codenator81 commented Oct 20, 2015

@hishamco You are right 👍
I will write own middleware which going to work after UseMVC and set needed culture thread

@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 20, 2015

All the best @Codenator81 , be free to ask if you have an issue again

@danroth27
Copy link
Member

@danroth27 danroth27 commented Oct 20, 2015

@kirthik @DamianEdwards We should look at what our guidance is for using path segments for determining the culture and maybe provide a sample on how to do it.

@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 20, 2015

@danroth27 i provide a simple unit test in https://github.com/aspnet/Localization/blob/dev/test/Microsoft.AspNet.Localization.Tests/CustomRequestCultureProviderTest.cs#L46, also I already suggest #43, if this will help i will make a PR for that

@Codenator81
Copy link
Author

@Codenator81 Codenator81 commented Oct 20, 2015

Middlewares don`t work after UseMVC middleware

@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 20, 2015

@Codenator81 if what you are looking for is in culture segment in "{controller=Home}/{culture=en-US}/{action=Index}/{id?}", I will try to look to into your sample or i will write a code snippet to display the culture segment

@Codenator81
Copy link
Author

@Codenator81 Codenator81 commented Oct 20, 2015

@hishamco Yes I looking for that.

@damienbod
Copy link

@damienbod damienbod commented Oct 20, 2015

I think this should be an extra default Provider like the others as this is a common use case. What do you think?

Greetings Damien

@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 20, 2015

Ok @Codenator81 I will dig into that
@damienbod as I said before, I already suggest that in #43

@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 20, 2015

@Codenator81 for saving time do you have a repo with the latest changes that you did?

@damienbod
Copy link

@damienbod damienbod commented Oct 20, 2015

@hishamco

Thanks for your answer, your PR sounds great, I was thinking more of a MVC 6 extension which would allow me to define my culture in the MVC attribute routing.

Greetings Damien

@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 20, 2015

@damienbod IMHO while there's RequestCultureProvider is out-of-the-box it will be nice to be provider than extension

@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 28, 2015

@Codenator81 have you look to this sample https://github.com/aspnet/Mvc/tree/9342cb0ab78add8c527edcbc4c0988edc96f01e3/test/WebSites/LocalizationWebSite if you didn't get your answer, I will add a sample demo for that

@Codenator81
Copy link
Author

@Codenator81 Codenator81 commented Oct 28, 2015

@hishamco I see that example long time ago. For now it is outdated? For example app.UseCultureReplacer(); I don`t find (may be removed from code)?
I think there is good example for starters or people who moving from < MVC5.

As I wrote one comment before I looking for segment in Controller. Same people do simelar approach in filter. But for now it is not possible get segment from middleware. I think it is routing feature or issue.
Not Localization.

@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 28, 2015

I see, but as I mentioned before issue #54 and https://github.com/aspnet/Localization/blob/dev/test/Microsoft.AspNet.Localization.Tests/CustomRequestCultureProviderTest.cs#L57 do such thing without using routes, I used segments instead, probably the idea is same. I'm not sure such sample should be in localization repo or mvc?!!
/cc @Eilon

@Codenator81
Copy link
Author

@Codenator81 Codenator81 commented Oct 28, 2015

@hishamco I see all that examples. All of them great 👍 My issue different.
I wrote before:

routes.MapRoute(
         name: "transRoute",
         template: "{controller=Home}/{culture=en-US}/{action=Index}/{id?}");

So I wont detect culture segment if it is at end route or at middle without rewrite code and just get that segment as I do in code there:

string cultureFromRoute = RouteData.Values["culture"] as string;

but segments can be detected only after routes initilized. So there no way get segment in middleware. Hope I explain my issue?

@hishamco
Copy link
Contributor

@hishamco hishamco commented Oct 28, 2015

Could you please add a repo summarize your scenario without any other stuff (MiniMVC), i already saw WeebDoCMF but I don't wanna miss on any other stuff 😄

@Codenator81
Copy link
Author

@Codenator81 Codenator81 commented Oct 28, 2015

Ok I will do it. May be today evening.

@Eilon Eilon added this to the Backlog milestone Dec 2, 2015
@hishamco
Copy link
Contributor

@hishamco hishamco commented Aug 20, 2016

It's in the way @Codenator81 😄
53a8fa6

@Eilon Eilon added 1 - Ready and removed needs design labels Aug 20, 2016
@Eilon Eilon modified the milestones: 1.1.0, Backlog Aug 20, 2016
@kichalla kichalla added 2 - Working and removed 1 - Ready labels Aug 23, 2016
@kichalla kichalla added 1 - Ready and removed 2 - Working labels Sep 12, 2016
kichalla added a commit that referenced this issue Sep 24, 2016
…nformation.

[Fixes #122] Get segment from mapped route for CustomRequestCultureProvider
kichalla added a commit that referenced this issue Sep 25, 2016
…nformation.

[Fixes #122] Get segment from mapped route for CustomRequestCultureProvider
kichalla added a commit that referenced this issue Sep 25, 2016
…nformation.

[Fixes #122] Get segment from mapped route for CustomRequestCultureProvider
@kichalla kichalla added 2 - Working and removed 1 - Ready labels Sep 25, 2016
@kichalla kichalla closed this in 861ae52 Sep 30, 2016
@kichalla kichalla added 3 - Done and removed 2 - Working labels Sep 30, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
7 participants
You can’t perform that action at this time.