Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling controller action method directly from Razor View

I looked around and couldn't find an easy solution.

I've tried @GetUserName which doesn't work.
I've tried @ { GetUserName which doesn't work.

There has to be an easy way to call a method from the razor view engine.

It is within a foreach loop.

I need GetUserName(item.userID)

The below code is in my controller:

[ChildActionOnly]
public string GetUserName(int userID)
{
     ProPit_User user = db.ProPit_User.Find(userID);

     return user.username;
}
like image 885
James Wilson Avatar asked Apr 03 '14 16:04

James Wilson


People also ask

How do you call a controller from Razor view?

We can use @html. action to call controller method.

How do you call a controller action from partial view?

Partial and @Html. RenderPartial methods are not meant to call the Controller's Action method, these methods will directly populate the Partial View from Model and render it. In order to call the Controller's Action method of the Partial View, the @Html.


2 Answers

Trying to call a controller action method directly from your view is usually a sign of bad design.

You have a few options, depending on what you are trying to do:

  1. Avoid calling the method, instead put the data in your model, and render the model
  2. Use Html.RenderAction
  3. Put the method in another class and use normal function syntax.

(1) is usually my default approach, often incorporating DisplayTemplates and EditorTemplates

For (3), e.g.

public static class Util
{
    public string MyUtilMethod(int blah)
}

And the view:

@Util.MyUtilMethod(1)
like image 150
Nathan Avatar answered Oct 16 '22 00:10

Nathan


Although you can obtain the controller instance from your view, doing so is plain wrong as it violates the whole MVC (and MVVM) paradigm, as the view should not be aware of its controller.

(The only possible reason I can think of where this would be useful would perhaps be for testing the controller from a mocked view, although even here, it should be possible to test the exposed controller functionality directly from unit tests):

@{
    var controller = ViewContext.Controller as MyController;
    var userName = controller.GetUserName(123);
}

The better way to have arrived at this result is for the controller to pre-populate, and pass all the data needed by the View, such as the userName, to a custom ViewModel (as typed by the @model directive at the top of the Razor page), or to the ViewBag dynamic.

like image 41
StuartLC Avatar answered Oct 15 '22 23:10

StuartLC