我遇到了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 });
}
非常感谢任何帮助。
答案 0 :(得分:0)
如果有人在这里搜索并找到答案,我会回答这个问题。
这种行为似乎是由来自Google AdWords的传入链接指向http://而不是https://引起的。当试图使用来自“不正确”http://的Html.ActionLink时,发生了上述错误。修复传入链接以指向https://按预期,突然和间歇性错误消失,所有似乎在过去24小时都没问题。
感谢@Nick和@ Nightowl888的支持。