2010-04-26 2 views
7

ASP.NET MVC - Могу ли я иметь несколько имен для одного и того же действия?ASP.NET MVC - Могу ли я иметь несколько имен для одного и того же действия?

В том же контроллере ... Могу ли я иметь несколько имен для одного и того же действия?

Я ищу полное решение для нескольких языков. По сути, я хочу, чтобы вся логика была такой же, но меняла «ключевые слова» (действия, контроллеры в URL-адресе) в зависимости от языка.

+0

Не могли бы вы установить Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.CurrentUICulture вместо этого? http://msdn.microsoft.com/en-us/library/bz9tc508.aspx –

ответ

7

У вас не может быть нескольких имен для одного и того же действия. Это будут разные действия. Так работает mvc. Mabe лучше реализовать описанное поведение с помощью маршрутизации.

routes.MapRoute("Lang1RouteToController1Action1", 
"Lang1Controller/Lang1Action/{id}", 
new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
); 

routes.MapRoute("Lang2RouteToController1Action1", 
"Lang2Controller/Lang2Action/{id}", 
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
); 

Ofcourse вам придется создать множество маршрутов, но вы можете сделать конфигурационный файл или хранилище маршрутизации данных в базе данных, а просто создать их в цикле при запуске приложения. В любом случае, я думаю, что лучше создать набор методов, потому что, если вы захотите добавить еще один язык, вам нужно будет найти действия по всем вашим контроллерам и перекомпилировать код. Но в случае маршрутов и конфигурационного файла это становится не так сложно. Вторая вещь - расширение Html.ActionLink («Главная», «Индекс», «Домой») - вам нужно будет реализовать свои собственные, чтобы вернуть ссылку с локализованным действием.

+0

Если бы эта идея тоже после публикации. Как вы думаете, у меня могут быть разные имена действий, вызывающие один и тот же класс, чтобы что-то делать, и иметь эти классы (логику действий) в другом файле? – unmircea

+0

Да, вы можете. Но, как я уже сказал, это вызовет большую боль, когда вы захотите добавить новый язык. Кроме того, будет выглядеть странно, чтобы видеть в кодовых методах, названных на разных языках, и делать то же самое. Я действительно думаю, что маршрутизация будет гораздо более уместной в вашем случае, потому что она использует строки. И каждый tyme мы локализуем что-то - мы локализуем строки, а не имена методов. Но это только мое мнение :) –

2

Я не уверен, что возможно иметь несколько имен действий. Один из способов, которым я мог бы это сделать, - это определить несколько действий с разными именами, которые выполняют внутри cal/execute одно и то же действие.

+0

Хорошее обходное решение! Но «окончательный» url, который будет создан, будет иметь имя «основного» действия, которое вызывает все другие действия. – unmircea

+0

Я так не думаю. Я не предлагаю перенаправление к другому действию. Вы можете просто выполнить другое действие (это еще один открытый метод в классе контроллера) и вернуть результат в браузер при выполнении действия. – Roman

+0

Хорошо ... Теперь я понял. Я просто «обертываю» действие «другого языка» вокруг общего действия, «делая» одно и то же. Это кажется логичным :) – unmircea

2

Я знаю, что я опоздал на вечеринку, но в в случае, если кто-то прибегая к помощи, я создал атрибут (вдохновленный от атрибута ActionName), который соответствует несколько имен следующим образом:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection; 
using System.Web.Mvc; 

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class ActionNamesAttribute : ActionNameSelectorAttribute 
{ 
    public ActionNamesAttribute(params string[] names) 
    { 
     if (names == null) { 
      throw new ArgumentException("ActionNames cannot be empty or null", "names"); 
     } 
     this.Names = new List<string>(); 
     foreach (string name in names) 
     { 
      if (String.IsNullOrEmpty(name)) 
      { 
       throw new ArgumentException("ActionNames cannot be empty or null", "names"); 
      } 
      this.Names.Add(name); 
     } 
    } 

    private List<string> Names { get; set; } 

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) 
    { 
     return this.Names.Any(x => String.Equals(actionName, x, StringComparison.OrdinalIgnoreCase)); 
    } 
} 

использовать:

[ActionNames("CreateQuickItem", "CreateFullItem")] 
public ActionResult Create() {} 
Смежные вопросы