MVC路由属性间歇性地停止工作

时间:2018-02-23 17:57:14

标签: c# asp.net-mvc

我遇到了MVC路由属性的间歇性问题,这些属性停止在我们的Azure托管站点上运行。

控制器操作和属性如下所示:

[AllowAnonymous]
[RequireHttps]
[RoutePrefix("{lang}")]
public class HomeController : LocalizationController
{

[...]

[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
    [AllowAnonymous]
    [Route("sl", Name = "SelectLanguage")]
    public ActionResult SelectLanguage(LanguageVersions? id)
    {

这是使用BeginForm从这个视图中调用的动作:

@using (Html.BeginForm("SelectLanguage", "Home", null, FormMethod.Post, new { @class = "form", role = "form" }))
    {

或者像这样:

@Html.ActionLink(@Resources.Shared.LY_LEARN_SPANISH, "SelectLanguage", "Home", routeValues: new { id = CommonItems.LanguageVersions.SpanishVersion }, htmlAttributes: new { title = @Resources.Shared.LY_TO_SPANISH })

过去2-3天,它间歇性地停止工作,并且URL没有属性写入,即变为:

Home/SelectLanguage/SpanishVersion

这会产生404错误(并重新路由到错误页面)。

重新启动服务器后,属性再次开始工作。我已经做了几次,但问题似乎在10-20小时后再次出现。它也会以类似的方式与其他控制器操作一起发生。

有什么想法吗?

编辑:

这是本地化控制器:

 public abstract class LocalizationController : Controller
{

    /// <summary>
    /// Gets/sets the current user culture.
    /// </summary>
    public string strLang { get; set; }

    /// <summary>
    /// Executed before an action is executed.
    /// </summary>
    /// <param name="filterContext">The current filter context</param>
    protected override void OnActionExecuting(ActionExecutingContext filterContext) {

        // Check if there is a route data language version.
        strLang = (string)ControllerContext.RouteData.Values["lang"];

        // Check if there is a logged in user...
        if (Request.IsAuthenticated == true)
        {
            // There is an ASP.NET User, get the culture from that User.
            var UserManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
            ApplicationUser myUser = UserManager.FindById(User.Identity.GetUserId());

            // If there is a different culture than the route, we must set the value from the User
            if (myUser.UserCulture != strLang)
            {
                strLang = myUser.UserCulture;

                // Update the filter context to re - route using the "lang" - field.
                SetFilterContext(filterContext);
            }
            else if ((myUser.UserCulture == strLang) && strLang == null)
            {
                // At rare occasions, both can be null. Then we use default and re route using default.
                strLang = "en";
                Thread.CurrentThread.CurrentCulture =
                Thread.CurrentThread.CurrentUICulture = new CultureInfo(strLang);

                // Set and update the User's culture as well.
                myUser.UserCulture = strLang;

                UserManager.Update(myUser);
                HttpContext.GetOwinContext().Get<ApplicationDbContext>().SaveChanges();
            }

        } else if (strLang == null)
        {
            // Get the language from the browser setting.
            var userLanguages = Request.UserLanguages;
            CultureInfo ci;
            if (userLanguages.Count() > 0)
            {
                try
                {
                    ci = new CultureInfo(userLanguages[0]);
                }
                catch (CultureNotFoundException)
                {
                    ci = CultureInfo.InvariantCulture;
                }
            }
            else
            {
                ci = CultureInfo.InvariantCulture;
            }
            strLang = ci.TwoLetterISOLanguageName;

            // Update the filter context to re-route using the "lang"-field.
            SetFilterContext(filterContext);
        }

        // Set culture...
        try
        {
            Thread.CurrentThread.CurrentCulture =
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(strLang);
        }
        catch (System.Exception e)
        {
            // Can't set this culture, select default...
            strLang = e.Message;
            strLang = "en";

            Thread.CurrentThread.CurrentCulture =
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(strLang);
        }

        base.OnActionExecuting(filterContext);
    }


    private void SetFilterContext(ActionExecutingContext filterContext)
    {

        string actionName = this.ControllerContext.RouteData.Values["action"].ToString();
        string controllerName = this.ControllerContext.RouteData.Values["controller"].ToString();

        if (actionName == "ReRouteToIndex")
            // Set up as a default 
            actionName = "Index";

        // Move to the same action and controller, but with the "lang" parameter set...
        var controller = (LocalizationController)filterContext.Controller;
        filterContext.Result = controller.RedirectToAction(actionName, controllerName, new { lang = strLang });
    }

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

如果有人在这里搜索并找到答案,我会回答这个问题。

这种行为似乎是由来自Google AdWords的传入链接指向http://而不是https://引起的。当试图使用来自“不正确”http://的Html.ActionLink时,发生了上述错误。修复传入链接以指向https://按预期,突然和间歇性错误消失,所有似乎在过去24小时都没问题。

感谢@Nick和@ Nightowl888的支持。