直接从Razor View调用控制器操作方法

时间:2022-12-01 22:53:26

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.

我试过@GetUserName不起作用。我试过@ {GetUserName不起作用。

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

必须有一种从剃刀视图引擎调用方法的简单方法。

It is within a foreach loop.

它在foreach循环中。

I need GetUserName(item.userID)

我需要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;
}

4 个解决方案

#1


10  

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. 避免调用方法,而是将数据放入模型中,然后渲染模型
  3. Use Html.RenderAction
  4. 使用Html.RenderAction
  5. Put the method in another class and use normal function syntax.
  6. 将该方法放在另一个类中并使用普通函数语法。

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

(1)通常是我的默认方法,通常包含DisplayTemplates和EditorTemplates

For (3), e.g.

对于(3),例如

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

And the view:

并且观点:

@Util.MyUtilMethod(1)

#2


2  

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.

虽然您可以从视图中获取控制器实例,但这样做是完全错误的,因为它违反了整个MVC(和MVVM)范例,因为视图不应该知道它的控制器。

(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.

获得此结果的更好方法是让控制器预先填充,并将View所需的所有数据(例如userName)传递给自定义ViewModel(由顶部的@model指令键入)。 Razor页面),或ViewBag动态。

#3


0  

The obvious problem you have is that the UserName should come in as part of the model, or at least in the ViewBag.

您遇到的一个明显问题是UserName应该作为模型的一部分,或者至少在ViewBag中。

public ActionResult MyAction(int userID) {
    ViewBag.UserName = db.ProPit_User.Find(userID).username;

    return View();
}

Okay, but let's say for some crazy reason you don't have the user ID at the time. Then you can go ahead and have that method in a class outside of your controller, and create an instance in your view.

好的,但是让我们说出一些疯狂的原因,你当时没有用户ID。然后,您可以继续在控制器之外的类中使用该方法,并在视图中创建实例。

@{
     var db = new Db();
     var userName = db.ProPit_User.Find(userID).username;
}
<div>userName is @userName</div>

It happens, but your want to have all of your data in your model and sending that to your view. You're view should only be for displaying the data, and should be going out fetching information from databases.

它确实发生了,但您希望在模型中包含所有数据并将其发送到您的视图中。您的视图应仅用于显示数据,并且应该从数据库中获取信息。

#4


0  

Other answers say it's bad practice; As with most things, that depends on how you use it.

其他答案说这是不好的做法;与大多数事情一样,这取决于您如何使用它。

Microsoft's shared layout as part of the MVC template, _LoginPartial.cshtml calls the SignIn and SignOut methods on the controller directly from the view:

Microsoft的共享布局作为MVC模板的一部分,_LoginPartial.cshtml直接从视图调用控制器上的SignIn和SignOut方法:

   <li><a asp-area="" asp-controller="Account" asp-action="Signin">Sign in</a></li>

Using the asp-controller and asp-action tag helpers on the hyperlink.

在超链接上使用asp-controller和asp-action标签助手。

#1


10  

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. 避免调用方法,而是将数据放入模型中,然后渲染模型
  3. Use Html.RenderAction
  4. 使用Html.RenderAction
  5. Put the method in another class and use normal function syntax.
  6. 将该方法放在另一个类中并使用普通函数语法。

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

(1)通常是我的默认方法,通常包含DisplayTemplates和EditorTemplates

For (3), e.g.

对于(3),例如

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

And the view:

并且观点:

@Util.MyUtilMethod(1)

#2


2  

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.

虽然您可以从视图中获取控制器实例,但这样做是完全错误的,因为它违反了整个MVC(和MVVM)范例,因为视图不应该知道它的控制器。

(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.

获得此结果的更好方法是让控制器预先填充,并将View所需的所有数据(例如userName)传递给自定义ViewModel(由顶部的@model指令键入)。 Razor页面),或ViewBag动态。

#3


0  

The obvious problem you have is that the UserName should come in as part of the model, or at least in the ViewBag.

您遇到的一个明显问题是UserName应该作为模型的一部分,或者至少在ViewBag中。

public ActionResult MyAction(int userID) {
    ViewBag.UserName = db.ProPit_User.Find(userID).username;

    return View();
}

Okay, but let's say for some crazy reason you don't have the user ID at the time. Then you can go ahead and have that method in a class outside of your controller, and create an instance in your view.

好的,但是让我们说出一些疯狂的原因,你当时没有用户ID。然后,您可以继续在控制器之外的类中使用该方法,并在视图中创建实例。

@{
     var db = new Db();
     var userName = db.ProPit_User.Find(userID).username;
}
<div>userName is @userName</div>

It happens, but your want to have all of your data in your model and sending that to your view. You're view should only be for displaying the data, and should be going out fetching information from databases.

它确实发生了,但您希望在模型中包含所有数据并将其发送到您的视图中。您的视图应仅用于显示数据,并且应该从数据库中获取信息。

#4


0  

Other answers say it's bad practice; As with most things, that depends on how you use it.

其他答案说这是不好的做法;与大多数事情一样,这取决于您如何使用它。

Microsoft's shared layout as part of the MVC template, _LoginPartial.cshtml calls the SignIn and SignOut methods on the controller directly from the view:

Microsoft的共享布局作为MVC模板的一部分,_LoginPartial.cshtml直接从视图调用控制器上的SignIn和SignOut方法:

   <li><a asp-area="" asp-controller="Account" asp-action="Signin">Sign in</a></li>

Using the asp-controller and asp-action tag helpers on the hyperlink.

在超链接上使用asp-controller和asp-action标签助手。