I have an application with a custom database routing:
routes.Add("RouteWeb", new RouteWeb());
public override RouteData GetRouteData(HttpContextBase httpContext)
{
if (httpContext.Request.IsAjaxRequest() || httpContext.Request.Url == null) return null;
var page = FindPageFromDataBase(httpContext.Request.Url);
if (page == null) return null;
var pageResult = new RouteData(this, new MvcRouteHandler());
pageResult.Values["culture"] = page.Culture;
pageResult.Values["controller"] = page.controller;
pageResult.Values["action"] = page.action;
return pageResult;
}
As you see I get the pages from database, so the admin of the site could change the route of a page (www.site.com/page -> www.site.com/other-name) and the site works with the new name.
In the database I retrieve the culture of the page, because every page could be in different cultures, for example if you access to www.site.com/page it gets the content in English, while if you access to www.site.com/pagina it shows the content in Spanish.
This works perfect except for one detail, when the user can filter a page using a date.
@using (Ajax.BeginForm(null, null, new AjaxOptions { HttpMethod = FormMethod.Get.ToString(), InsertionMode = InsertionMode.Replace, UpdateTargetId = "content_list", Url = Url.Action("UsersItems", "Users"), OnComplete = "OnComplete" }, new { id = "formSearch" }))
{
...
@Html.DatePickerRangeFor(model => model.DateFrom, new { @class = "form-control", Value = Model.DateFrom == null ? "" : Convert.ToDateTime(Model.DateFrom).ToShortDateString()})
}
I have to use a custom ModelBinder to change the date to the correct format based on the language of the selected page.
public class NullableDateTimeBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var cultureInfo = new CultureInfo(controllerContext.RouteData.Values["culture"].ToString());
System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureInfo.Name);
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
return value?.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);
}
}
My problem is
controllerContext.RouteData.Values["culture"]
is always null. When I first load the page RouteData gets the culture, but when doing the partial ajax request all the values are gone and the ModelBinder gives me an error.
I don't want to store the current culture in a session variable since I read the language from the page of the database and I have the problem only with ajax requests to load partial views.
Is there any way to pass the ModelBinder the culture of the current page?
Thanks in advance.