2010-04-26 27 views
7

ASP.NET MVC - Posso avere più nomi per la stessa azione?ASP.NET MVC - Posso avere più nomi per la stessa azione?

Nello stesso controller ... Posso avere più nomi per la stessa azione?

Sto cercando una soluzione multilingue completa. In sostanza, voglio che tutta la logica sia la stessa cosa, ma cambiare le "parole chiave" (azioni, controller nell'URL) a seconda della lingua.

+0

Non potresti impostare Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.CurrentUICulture invece? http://msdn.microsoft.com/en-us/library/bz9tc508.aspx –

risposta

7

Non è possibile avere più nomi per la stessa azione. Saranno diverse azioni. Questo è il modo in cui funziona il mvc. Mabe è meglio implementare il comportamento descritto con il routing.

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 } 
); 

Naturalmente dovrete creare molti percorsi, ma si può fare file di configurazione o negozio di instradamento dei dati nel database, e appena li creare in loop all'avvio dell'applicazione. Comunque penso che sia meglio quindi creare metodi diversi, perché se vuoi aggiungere un'altra lingua dovrai trovare azioni su tutti i controller e ricompilare il codice. Ma in caso di percorsi e file di configurazione - non diventa così difficile. La seconda cosa è l'estensione Html.ActionLink ("Home", "Index", "Home") - dovrai implementare la tua per restituire il link di azione localizzato.

+0

Anche questa idea, dopo che ho postato. Pensi che io possa avere nomi di azioni diversi che chiamano la stessa classe per fare qualcosa e avere queste classi (logica di azione) in un file diverso? – unmircea

+0

Sì, è possibile. Ma come ho già detto, questo provocherà molto dolore quando si vorrà aggiungere un nuovo linguaggio. Inoltre sembrerà strano vedere nei metodi di codice chiamati in lingue diverse e fare la stessa cosa. Penso davvero che il routing sarà molto più appropriato nel tuo caso, perché usa stringhe. E ogni volta che localizziamo qualcosa, localizziamo le stringhe, non i nomi dei metodi. Ma è solo la mia opinione :) –

2

Non sono sicuro se è possibile avere più nomi di azioni. Un modo in cui posso pensare di farlo è definendo più azioni con nomi diversi che cal/eseguono la stessa azione.

+0

Soluzione piacevole! Ma l'url "finale" che viene prodotto avrà il nome dell'azione "principale" che ogni altra azione chiama. – unmircea

+0

Io non la penso così. Non sto suggerendo il reindirizzamento a un'altra azione. È possibile eseguire semplicemente un'altra azione (che è un altro metodo pubblico nella classe controller) e restituire il risultato al browser durante l'esecuzione di un'azione. – Roman

+0

Ok ... ora capisco. Semplicemente "avvolgo" l'azione "un'altra lingua" attorno a un'azione generica, sia "facendo" la stessa cosa Questo sembra logico :) – unmircea

2

So di essere in ritardo alla festa, ma in in caso qualcuno è googling, ho creato un attributo (ispirato da attributo ActionName) che corrisponde più nomi come segue:

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)); 
    } 
} 

Per utilizzare:

[ActionNames("CreateQuickItem", "CreateFullItem")] 
public ActionResult Create() {} 
Problemi correlati