Is it possible to call the same method on all Controller asp..net mvc without having to repeat the code?

1

On my Controller Home, I have this:

   /// <summary>
        /// Aqui estou trocando o idioma da página de acordo cam a seleção do 
        /// usuário.
        /// </summary>
        /// 

        public ActionResult AlteraIdioma(string LinguagemAbreviada)
        {

            if (LinguagemAbreviada != null)
            {
                Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(LinguagemAbreviada);
                Thread.CurrentThread.CurrentUICulture = new CultureInfo(LinguagemAbreviada);

            }

            //aqui estou gravando o cookie com o idioma para que seja recuperado no Global.asax
            HttpCookie cookie = new HttpCookie("Linguagem");
            cookie.Value = LinguagemAbreviada;
            Response.Cookies.Add(cookie);

            return View("Index");
        }

It changes the language of the page and saves a cookie so that the navigation continues in the chosen language, but I wanted to know if I can call this in all the controllers without having to repeat, how would it look? Thank you

    
asked by anonymous 19.10.2016 / 15:49

3 answers

1

There is a native Framework resource for this, called the ASP.NET MVC Filter Types .

Basically, you can set an Action filter to be executed at the beginning or end of each request to add your information. For example:

public class AlteraIdiomaFilterAttribute : ActionFilterAttribute 
{
    // nesse caso, adiciona ao fim da execução de uma Action
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // pega o valor da requisição, no seu caso uma QueryString
        string linguagemAbreviada = filterContext.HttpContext.Request.Params["LinguagemAbreviada"];

        if (linguagemAbreviada != null)
        {
            // tome cuidado ao usar informações vindo do usuário!
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(linguagemAbreviada);
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(linguagemAbreviada);
        }

        HttpCookie cookie = new HttpCookie("Linguagem");
        cookie.Value = linguagemAbreviada;

        // adiciona no context, que ele controla o Response que será processado de fato
        filterContext.HttpContext.Response.Cookies.Add(cookie);
    }
}

You use the Global Action Filter logging in Global.asax:

protected void Application_Start()
{    
    GlobalFilters.Filters.Add(new AlteraIdiomaFilterAttribute());
}

If you are using the default ASP.NET MVC 5 template, it creates the FilterConfig class for you and calls the registration method in Global.asax, it would just add your filter:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new AlteraIdiomaFilterAttribute());
    }
}   

In the case of ASP.NET Core, official documentation instructs you to add the global filters in Statup:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Filters.Add(new AlteraIdiomaFilterAttribute());
    });

    services.AddScoped<AddHeaderFilterWithDi>();
}
    
19.10.2016 / 19:19
1

Basically, to get what you need, there are 3 possibilities (2 of which have been explained very well above):

  • using a Filter, so you have this functionality globally;
  • using inheritance, so you will have this functionality locally, this is, you will need to include the call code in each action;
  • using some AOP (aspect orientation) tool to embed your code before the execution of each method, so you can choose to do by class, method, library;
  • Each of these solutions has its strengths and weaknesses. It's your choice.

        
    19.10.2016 / 21:02
    0

    One of the ways to reuse the code between controllers would be with inheritance

    I do not know if it would be ideal to change the language, but I will keep the answer focused on the question that is to reuse.

    You create a class inheriting Controller :

    public class BaseController : Controller
        {
            public void MeuMetodo()
            {
                ...
            }
        }
    

    From there all your Controllers stop using the controller inheritance and start using the BaseController now.

    public class HomeController : BaseController 
        {
            public ActionResult Index()
            {
    
                MeuMetodo();
    
                return View("Index");
            }
    

    This is a simple and quick way to do the reuse.

        
    19.10.2016 / 16:04