Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Sébastien Richer 194 posts 430 karma points
    Jun 18, 2013 @ 16:05
    Sébastien Richer
    0

    Getting CurrentPage context in Surface controller without BeginUmbracoForm

    I'm trying to place an ajax call to my SurfaceController without using the BeginUmbracoForm and I would need to get the CurrentPage context, mainly to get proper access to dictionary items.

    So here is my current test.

    I have this in my page:

    @using (Html.BeginUmbracoForm<MyFun.SurfaceControllers.FunController>("SuperFun")) { }

    Then I have this JS call:

    function jsFun() {
        var uformpostroutevals = $('[name="uformpostroutevals"]').val();
        $.ajax({
            type: "POST",
            url: "/umbraco/surface/Fun/SuperFun/",
            data: { uformpostroutevals: uformpostroutevals, text: "Some fun text" },
            dataType: "text",
            success: function (msg) {
                $("#fun").html(msg);
                console.log("jsFun");
            },
            error: function (msg) {
                // console.log("Message: " + msg);
            }
        });
    }

    This surface controller returns a partial view that calls the dictionary. When I include my partial view "normally" I get my dictionnary values correctly (multi-lingual) but through Surface it returns an empty string. Which makes sense because it has not set culture. So I'm trying to pick it up and send it to my controller so it can print my dictionnary correctly.

    Anyone has an idea about what's not working here?

     

    Thanks!

  • Lars-Erik Aabech 350 posts 1102 karma points MVP 8x c-trib
    Jun 21, 2013 @ 16:59
    Lars-Erik Aabech
    1

    Pass the culture you have in the view back to the controller via the ajax call.
    For instance:


    ...
    $.ajax({...
    data:{..., culture: $("#currentCulture").val(), ...}
    ...});

    In the controller, set Thread.CurrentThread.CurrentUICulture.

    System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(parameterInstance.culture);
    var libararyItemInThatLanguage = library.GetDictionaryItem(yourKey);

     Maybe I misunderstand though, if you use library in the partial view, pass the culture to the view, set and reset CurrentUICulture there.

  • Sébastien Richer 194 posts 430 karma points
    Jun 27, 2013 @ 00:07
    Sébastien Richer
    0

    This is an interesting idea! I got my dictionary values correctly! But I'm still missing something, it might not actually be a problem but I want to get this straightened out hehe So here is what I have now.

    My controller:

        public class FunController : Umbraco.Web.Mvc.SurfaceController
        {
    
            [System.Web.Mvc.HttpPost]
            public ActionResult Index()
            {
                return Content("ok");
            }
    
            [System.Web.Mvc.HttpPost]
            public ActionResult SuperFun(string text, string culture)
            {
                System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
                return PartialView("UltraFunPartial");
            }
        }
    }

    Now my initial page has this mark-up:

    <hr/><hr/><hr/>
    
    <div id="culture" class="box">@Culture</div>
    
    <div id="fun" style="min-height: 400px; background-color: springgreen;">
        @Html.Partial("UltraFunPartial")
    </div>
    
    <hr/><hr/><hr/>

    Here @Culture, will display "fr-CA" on the initial page load. And the @Culture inside my partial view, will also display "fr-CA"

    Here is my JS function now (I pick up the @Culture here basically):

    function jsFun() {
        var culture = $("#culture").val();
        $.ajax({
            type: "POST",
            url: "/umbraco/surface/Fun/SuperFun/",
            cache: false,
            data: { culture: culture, text: "Some fun text" },
            dataType: "text",
            success: function (msg) {
                $("#fun").html(msg);
                // console.log("jsFun");
            },
            error: function (msg) {
                // console.log("Message: " + msg);
            }
        });
    }

    I ran in debug mode and my controller gets the culture string correctly, and sets the culture in CurrentUICulture correctly. But when my partial view renders, the @Culture is en-CA.

    Here is my partial view:

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    
    @{
        // [...]
        var random = new Random();
        var randomNumber = random.Next(0, 100);
    }
    
    <div class="box" style="background-color: pink;">Culture in partial: @Culture</div>
    
    <div>This should have text: (@library.GetDictionaryItem("General_EnSavoirPlus"))</div>
    <div>And here is a random number: (@randomNumber)</div>
    <div>CurrentPage: (@CurrentPage)</div>
    <div>UmbracoContext.PageId: (@UmbracoContext.PageId)</div>

     

    Now the fun thing is that my "General_EnSavoirPlus" dictionary label pops out correctly! This all feels a bit awkward though, what do you think, is this kosher?

    Thanks for the help!

  • Lars-Erik Aabech 350 posts 1102 karma points MVP 8x c-trib
    Jun 27, 2013 @ 15:07
    Lars-Erik Aabech
    101
    System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture); //== UmbracoTemplatePage.UICulture
    
    System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(culture); //== UmbracoTemplatePage.Culture

    library.GetDictionaryItem uses System.Threading.Thread.CurrentThread.CurrentUICulture.

    L-E

  • Sébastien Richer 194 posts 430 karma points
    Jun 27, 2013 @ 15:21
    Sébastien Richer
    0

    This is great! I'll keep this as reference, thanks a lot for the help!

  • Lars-Erik Aabech 350 posts 1102 karma points MVP 8x c-trib
    Jun 27, 2013 @ 15:28
    Lars-Erik Aabech
    0

    pleasure :)

  • Andrei 68 posts 130 karma points
    Apr 15, 2017 @ 10:53
    Andrei
    1

    I just made a global filter attribute for this issue:

        public class AjaxRequestFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var request = filterContext.RequestContext.HttpContext.Request;
    
            if (request.IsAjaxRequest())
            {
                var domain = ApplicationContext.Current.Services.DomainService.GetByName(request.Url.Host);
    
                if (domain == null) // trick to make it work on domains with port specified, like http://localhost:8080
                {
                    domain = ApplicationContext.Current.Services.DomainService.GetByName(request.Url.Authority);
                }
    
                if(domain != null && !domain.LanguageIsoCode.IsNullOrWhiteSpace())
                {
                    Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(domain.LanguageIsoCode);
                }
            }
            base.OnActionExecuting(filterContext);
        }
    }
    

    This way I don't have to worry on each ajax request about culture and labels. Also this code will run only if it's an ajax request. Seems to work fine so far. I'm a bit worried it would interfere with umbraco's internal controllers (if any), but didn't notice a problem yet.

Please Sign in or register to post replies

Write your reply to:

Draft