简体   繁体   English

在MVC3 / razor中的布局页面事件之后返回相同的视图

[英]Returning the same view after a layout page event in MVC3/razor

I have an MVC3 application using the razor view engine and twitter-bootsrap. 我有一个使用razor视图引擎和twitter-bootsrap的MVC3应用程序。 In my _Layout.cshtml file, I have a dropdown with a list of supported languages and have it's onchange wired to the following code: 在我的_Layout.cshtml文件中,我有一个下拉列表,其中包含受支持语言的列表,并将其onchange连接到以下代码:

 public ActionResult ChangeLanguage(string langue)
 {
     CultureInfo ci = new CultureInfo(langue);
     System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
     System.Threading.Thread.CurrentThread.CurrentCulture = ci;
     return View("Index", "_Layout");
 }

It works fine, but currently always return the Index view. 它工作正常,但目前总是返回索引视图。 I would like to return whatever view was currently displayed when the user changed language. 当用户更改语言时,我想返回当前显示的任何视图。 I tried: 我试过了:

  • return View(); return View(); //obviously doesn't work //显然不起作用
  • return View("Index", "_Layout"); return View(“Index”,“_ Layay”); //current code, not dynamic //当前代码,不是动态的
  • return Redirect(this.Request.UrlReferrer.AbsolutePath); return Redirect(this.Request.UrlReferrer.AbsolutePath); //does nothing, language doesn't change either //什么都不做,语言也不会改变
  • passing the view as a parameter and returning it: I couldn't find an object that actually work 将视图作为参数传递并返回它:我找不到实际工作的对象
  • This question seems to be a possible solution start but I'm not familiar enough yet to adapt it. 这个问题似乎是一个可能的解决方案开始,但我还不熟悉它还没有适应它。
  • return Redirect(Request.ServerVariables["HTTP_REFERER"]); return Redirect(Request.ServerVariables [“HTTP_REFERER”]); //good page, no culture change //好页面,没有文化变化

My question is in 2 parts: 我的问题分为两部分:

  • How can I return the same view that the user was seeing when he changed language? 如何更改用户在更改语言时看到的相同视图?
  • Where should I really put this code? 我应该把这段代码放在哪里? It's currently using the same controller as the homepage and that doesn't feel right. 它目前使用与主页相同的控制器,感觉不对。 Is there an equivalent to an ASP.NET webforms masterpage's codebehind file? 是否有相当于ASP.NET webforms母版页的代码隐藏文件?

I would pull the view off the request. 我会从请求中删除视图。

Request.Url.AbsoluteUri.

Not sure if you could hijack the routing engine to identify the view, but it shouldn't be too hard. 不确定你是否可以劫持路由引擎以识别视图,但它不应该太难。

You could also add a property to a base model you inherit all your models from. 您还可以向继承所有模型的基础模型添加属性。 Then you could create a hidden field everywhere but this seems like something that would eventually get lost. 然后你可以在任何地方创建一个隐藏的字段,但这似乎最终会丢失。 The only thing you can count on every time forever, would be the URL in the request. 您每次都可以永远依赖的唯一事情就是请求中的URL。

If your controller's and views are complex enough, you may have to cache this in the session. 如果您的控制器和视图足够复杂,您可能必须在会话中缓存它。 A single string per user shouldn't be that big of a deal. 每个用户一个字符串不应该是那么大的交易。 But perhaps there is a better solution to this problem in general. 但也许总的来说这个问题有更好的解决方案。

I would go about this one of two ways. 我会谈到这两种方式之一。

1. Build up your controller logic to accomadate a few useful things in a base controller and add the Change Language logic in the BaseController. 1.构建控制器逻辑,以便在基本控制器中添加一些有用的东西,并在BaseController中添加更改语言逻辑。

    public class BaseController : Controller
    {
        public BaseController()
        {
            this.SetCurrentCulture();
        }

        private void SetCurrentCulture()
        {
           If(String.IsNullOrEmpty(MySession.Language))
              MySession.Language="en-US";
           CultureInfo ci = new CultureInfo(MySession.Language);
           System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
           System.Threading.Thread.CurrentThread.CurrentCulture = ci;
        }

        public ActionResult ChangeLanguage(string language)
        {
           MySession.Language=language;
           this.SetCurrentCulture();
           return View();//or something 
        }
    }


   public class MyController:BaseController
   {
   }

2. Perform the task client side with a ajax post and reload. 2.使用ajax帖子执行任务客户端并重新加载。

    $.ajax({ type: "POST",
    url: '@Url.Action("ChangeLanguage","SomeController"),
        datatype: "json",
    traditional: true,
    data: {Language:'fr-CA'},
    success: function () {},
    error: function (xhr, status, error) {}
    });

   window.location.href=window.location.href;

You could use the Request.ServerVariables["HTTP_REFERER"] to get the page referring page. 您可以使用Request.ServerVariables["HTTP_REFERER"]来获取页面引用页面。

public ActionResult ChangeLanguage(string langue)
{
  CultureInfo ci = new CultureInfo(langue);
  System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
  System.Threading.Thread.CurrentThread.CurrentCulture = ci;
  var referer = Request.ServerVariables["HTTP_REFERER"];
  return Redirect(referer);
}

The way I've handled this in the past was to change the culture using an ActionFilterAttribute which I would apply to all controllers. 我过去处理这个问题的方法是使用ActionFilterAttribute更改文化,我将应用于所有控制器。

public sealed class CultureActionFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        object value;
        // get culture
        filterContext.RouteData.TryGetValue("culture", out value);
        var cultureName = value as string;
        if (cultureName == null)
        {
            cultureName = // resolve your default culture
        }

        var culture = new CultureInfo(cultureName);
        Thread.CurrentThread.CurrentCulture = culture;
        Thread.CurrentThread.CurrentUICulture = culture;

    }
}

(I had route constraints verify the culture before this actionfilter took affect. If you don't want to do that... because you're using querystring parametrs... the validation should probably go in this method.) (在此actionfilter生效之前,我有路由约束验证文化。如果您不想这样做...因为您正在使用查询字符串参数...验证应该可以使用此方法。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM