F-ES Sitecore
Вам нужен совершенно другой подход, более гибкий. Это высокоуровневый пример кода, но он должен дать вам представление о том, что вам нужно сделать. Вместо того чтобы получать все возможные языковые версии в вашем новостном объекте, вы должны просто получить новостной объект, который имеет язык, на который в данный момент настроен сайт. Вы можете показывать только один язык за раз, так зачем же возвращать весь языковой контент? Кроме того, ваш способ затрудняет добавление или удаление языков из вашего решения.
Таким образом, здесь есть две вещи...обработка того, что такое текущий язык, а затем обработка того, как получать новости на этом языке. Разделяя их, вы можете повторно использовать свой выбор языка в другом месте, он не тесно связан с вашим новостным кодом.
Я собираюсь использовать один вид для всего, что делается для простоты. Так
/Индекс
покажет "статья не найдена", но
/ Индекс / 1
покажет новость пункт 1 на выбранном языке
Сначала мы обработаем язык, и он будет сохранен в файле cookie, так как это лучшее решение для веб-сайта. Поэтому мы определим интерфейс сервиса, который удовлетворяет нашему выбору языка, и конкретный интерфейс, который реализует его с помощью файлов cookie.
public interface ILanguageService
{
string GetLanguage();
void SetLanguage(string lang);
}
public class CookieLanguageService : ILanguageService
{
public string GetLanguage()
{
HttpCookie c = System.Web.HttpContext.Current.Request.Cookies["lang"];
string lang = c == null ? string.Empty : System.Web.HttpContext.Current.Request.Cookies["lang"].Value;
if (string.IsNullOrWhiteSpace(lang))
{
// default to UK English (the best language in the world) if no language is set
lang = "en-GB";
}
return lang;
}
public void SetLanguage(string lang)
{
HttpCookie c = new HttpCookie("lang", lang);
c.Expires = DateTime.Now.AddYears(1);
System.Web.HttpContext.Current.Response.Cookies.Add(c);
}
}
Этот тип архитектуры означает, что если вы хотите сохранить свой язык в другом месте, вы можете реализовать ILanguageService для данного носителя данных (например, вы можете использовать сеанс, вы можете управлять им из настроек вошедшего в систему пользователя и т. д.).
Модель выглядит так (я только обрабатываю заголовок, Вам нужно будет добавить свойства для LongDescription, ID и т. д)
public class News
{
public string Title { get; set; }
}
Наш контроллер будет выглядеть так
public class HomeController : Controller
{
private ILanguageService languageService;
public HomeController()
: this(new CookieLanguageService())
{
// if you have dependency injection set up you can omit this constructor
// and allow the DI to handle the creation of your services
}
public HomeController(ILanguageService languageService)
{
this.languageService = languageService;
}
[HttpGet]
public ActionResult Index(int? id)
{
// we'll flesh this action out later
News m = new News();
return View(m);
}
public ActionResult SetLanguage(string lang)
{
this.languageService.SetLanguage(lang);
return RedirectToAction("Index");
}
}
Вид-здесь я использую ссылки для выбора языка, вы, вероятно, захотите использовать выпадающий список или что-то в этом роде
@model MyProject.Models.News
<div>
@Html.ActionLink("English", "SetLanguage", "Home", new { lang = "en-GB" }, null) |
@Html.ActionLink("French", "SetLanguage", "Home", new { lang = "fr-FR" }, null)
</div>
<div>
<h1>@Model.Title</h1>
</div>
Это обрабатывает выбор языка. Теперь нам нужен новостной сервис, который будет получать заданную новостную статью из вашей базы данных на основе идентификатора статьи и выбранного в данный момент языка. Итак, определение сервиса
public interface INewsService
{
News GetNews(int id);
}
Для реализации я делаю некоторое жесткое кодирование заголовка новости, вы, очевидно, получите это из своей базы данных.
public class NewsService : INewsService
{
private ILanguageService languageService;
public NewsService(ILanguageService languageService)
{
this.languageService = languageService;
}
public News GetNews(int id)
{
// get the current language
string lang = this.languageService.GetLanguage();
// get the news item for that language from your database
// I am hard-coding this data for simplicity
News news = new News();
news.Title = string.Format("Article {0} in {1}", id.ToString(), lang);
return news;
}
}
Теперь мы внедрили наш выбор языка и нашу службу новостей мы можем конкретизировать наши действия контроллера;
[HttpGet]
public ActionResult Index(int? id)
{
News m;
// my action allows for the id to be provided or not, in reality you'll
// have a dedicated "news" page that must have an id supplied or else
// you'll redirect somewhere
if (id.HasValue)
{
// if you have dependency injection set up you'd treat the INewsService the
// same way you do ILanguageService. As INewsService needs an instance of
// ILanguageService I can creating an instance of NewsService here rather
// than letting DI handle the creation
INewsService ns = new NewsService(this.languageService);
m = ns.GetNews(id.Value);
}
else
{
m = new News();
m.Title = "Article not found";
}
return View(m);
}
Я написал код таким образом, чтобы он работал как есть, но таким образом, чтобы вы обычно использовали инъекцию зависимостей. Я добавил комментарии, чтобы показать, где DI сделает код немного проще, если вы не используете DI, то я бы посоветовал вам изучить его (это совершенно новая тема сама по себе).
Я использую код языка для определения языка, но если ваша система использует идентификаторы или какой-то другой механизм, то измените его по мере необходимости. Как вы можете видеть, любой сервис, который вы затем пишете, также может использовать инъекцию данного ILanguageService, чтобы он мог работать с текущим языком.