从局部视图设置主URL的路由值

时间:2014-01-29 09:27:59

标签: c# asp.net-mvc asp.net-mvc-routing partial-views

我正在开发一个多语言的ASP.NET MVC网站,我需要一些帮助从局部视图中设置主要操作中的语言。

我的默认路线声明为:

routes.MapRoute(
            name: "Default",
            url: "{language}/{controller}/{action}/{id}",
            defaults: new { language = "en", controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

在我的_Layout.cshtml中,我已将部分引用声明为:

@Html.Partial("_LanguagePartial")

此Partial调用语言控制器中的Action:

@Html.Action("Index","Language")

此控制器操作只是将已发布的语言泵入视图:

public class LanguageController : BaseController
{
    //
    // GET: /Language/
    public PartialViewResult Index()
    {
        List<Language> languages = new List<Language>();
        foreach (Language language in Global.Data.Languages.Values)
        {
            if (language.IsReleased)
                languages.Add(language);
        }
        return PartialView(languages);
    }

    public ActionResult SelectLanguage(string code)
    {
        //I tried to change the route value here, but this only affects the route to this action
        var routeDataDict = HttpContext.Request.RequestContext.RouteData.Values;
        routeDataDict["language"] = code;
        return RedirectToRoute(routeDataDict);
    }
}

部分显示的实际视图如下所示:

<div class="float-center">
<table><tr>
@foreach (var language in Model) {
    <td>
    <a href="@Url.Action("SelectLanguage", new { code = language.CultureCode })">
        <!--The css for the correct sprite is generated by language.Icon.ToString()
            The result will look like "background: url("/Images/Icons.png") -0px -100px; display: block; width: 32px; height: 20px; text-indent: -9999px;"-->
        <img alt="" src="" style="@Url.Content(@language.Icon.ToString());border=1" />
    </a>
    </td>
}
</tr></table>

现在这个部分会在网站的每个页面中呈现,就像它应该的那样,但是当我在mydomain / en / SomeController / SomeAction上时,我点击让我们说德语图标,它应该带我到mydomain / DE / SomeController / SomeAction。

当然,操作和控制器不固定。

关于如何执行此类操作的任何想法? 也许我已经实现了部分错误,如果我以不同的方式实现它,我将能够访问该路径。

修改 在meilke的回答的帮助下,我对语言控制器进行了以下编辑:

public ActionResult SelectLanguage(string code)
    {
        string url = ReplaceLanguageCode(Request.UrlReferrer.ToString(), code);
        return Redirect(url);
    }

    private string ReplaceLanguageCode(string url, string code)
    {
        Language language = GetLanguage(url);
        if (language == null)
        {
            //No Language is set in the url e.g. http://mydomain/
            string domain = Request.Url.AbsoluteUri.ToString().Replace(Request.Url.PathAndQuery, "");
            return url.Replace(domain, domain + "/" + code);
        }
        else
            //A Language was already set in the url e.g. http://mydomain/en/
            return url.Replace("/" + language.CultureCode + "/", "/" + code + "/");
    }

    private Language GetLanguage(string url)
    {
        //Loop the apps languages to see if one is set in the url
        foreach (Language language in Global.Data.Languages.Values)
        {
            if (url.ToLower().Contains("/" + language.CultureCode + "/"))
                return language;
        }
        return null;
    }

根据meilke的回答,SetLanguage操作被更改为使用UrlReferrer。我还添加了ReplaceLanguageCode来创建新的url和GetLanguage来获取语言,如果原始url包含一个。

1 个答案:

答案 0 :(得分:1)

有一个通用控制器,它与当前操作或当前控制器无关,并将SelectLanguage放在那里。然后使用Request.UrlReferrermore information)让您回到原来的位置(现在使用正确的语言):

public ActionResult SelectLanguage(string code)
{
  // set language here

  return Redirect(Request.UrlReferrer.ToString());    
}