简体   繁体   English

ASP.Net MVC:从视图调用方法

[英]ASP.Net MVC: Calling a method from a view

In my MVC app the controller gets the data (model) from an external API (so there is no model class being used) and passes that to the view.在我的 MVC 应用程序中,控制器从外部 API 获取数据(模型)(因此没有使用模型类)并将其传递给视图。 The data (model) has a container in which there are several objects with several fields (string values).数据(模型)有一个容器,其中有几个对象和几个字段(字符串值)。 One view iterates over each object and calls another view to draw each of them.一个视图遍历每个对象并调用另一个视图来绘制它们中的每一个。 This view iterates over the fields (string values) and draws them.此视图遍历字段(字符串值)并绘制它们。

Here's where it gets tricky for me.这对我来说很棘手。 Sometimes I want to do some special formatting on the fields (string values).有时我想对字段(字符串值)进行一些特殊的格式化。 I could write 20 lines of code for the formatting but then I would have to do that for each and every field and that would just be silly and oh so ugly.我可以为格式编写 20 行代码,但是我必须为每个字段都这样做,这将是愚蠢的,哦,太丑陋了。 Instead I would like to take the field (string value), pass it to a method and get another string value back.相反,我想获取该字段(字符串值),将其传递给一个方法并返回另一个字符串值。 And then do that for every field.然后对每个领域都这样做。

So, here's my question:所以,这是我的问题:

How do I call a method from a view?如何从视图调用方法?

I realize that I may be asking the wrong question here.我意识到我可能在这里问错了问题。 The answer is probably that I don't, and that I should use a local model and deserialize the object that I get from the external API to my local model and then, in my local model, do the "special formatting" before I pass it to the view.答案可能是我没有,我应该使用本地模型并将从外部 API 获得的对象反序列化为本地模型,然后在我的本地模型中,在通过之前执行“特殊格式”它的视图。 But I'm hoping there is some way I can call a method from a view instead.但我希望有某种方法可以从视图中调用方法。 Mostly because it seems like a lot of overhead to convert the custom object I get from the API, which in turns contains a lot of other custom objects, into local custom objects that I build.主要是因为将我从 API 获得的自定义对象(又包含许多其他自定义对象)转换为我构建的本地自定义对象似乎需要很多开销。 And also, I'm not sure what the best way of doing that would be.而且,我不确定最好的方法是什么。

Disclaimer: I'm aware of the similar thread "ASP.NET MVC: calling a controller method from view" ( ASP.NET MVC: calling a controller method from view ) but I don't see how that answers my question.免责声明:我知道类似的线程“ASP.NET MVC:从视图调用控制器方法”( ASP.NET MVC:从视图调用控制器方法)但我不明白这如何回答我的问题。

This is how you call an instance method on the Controller:这是在 Controller 上调用实例方法的方式:

@{
  ((HomeController)this.ViewContext.Controller).Method1();
}

This is how you call a static method in any class这就是在任何类中调用静态方法的方式

@{
    SomeClass.Method();
}

This will work assuming the method is public and visible to the view.假设该方法是公共的并且对视图可见,这将起作用。

Building on Amine's answer, create a helper like:在 Amine 的答案的基础上,创建一个助手,如:

public static class HtmlHelperExtensions
{
    public static MvcHtmlString CurrencyFormat(this HtmlHelper helper, string value)
    {
        var result = string.Format("{0:C2}", value);
        return new MvcHtmlString(result);
    }
}

in your view: use @Html.CurrencyFormat(model.value)在您看来:使用@Html.CurrencyFormat(model.value)

If you are doing simple formating like Standard Numeric Formats , then simple use string.Format() in your view like in the helper example above:如果您正在执行像Standard Numeric Formats这样的简单格式化,那么在您的视图中简单地使用string.Format() ,就像上面的帮助器示例一样:

@string.Format("{0:C2}", model.value)

You can implement a static formatting method or an HTML helper, then use this syntaxe :您可以实现静态格式化方法或 HTML 助手,然后使用以下语法:

@using class_of_method_namespace
...
// HTML page here
@className.MethodName()

or in case of HTML Helper或者在 HTML Helper 的情况下

@Html.MehtodName()

Controller not supposed to be called from view.不应该从视图中调用控制器。 That's the whole idea of MVC - clear separation of concerns.这就是 MVC 的全部理念——清晰的关注点分离。

If you need to call controller from View - you are doing something wrong.如果您需要从 View 调用控制器 - 您做错了。 Time for refactoring.重构的时间。

why You don't use Ajax to为什么你不使用Ajax

its simple and does not require page refresh and has success and error callbacks它很简单,不需要page refresh ,并且有success and error回调

take look at my samlpe看看我的样品

<a id="ResendVerificationCode" >@Resource_en.ResendVerificationCode</a>

and in JQuery在 JQuery 中

 $("#ResendVerificationCode").on("click", function() {
                getUserbyPhoneIfNotRegisterd($("#phone").val());
 });

and this is my ajax which call my controller and my controller and return object from database这是我的ajax,它调用我的控制器和我的控制器并从数据库返回对象

function getUserbyPhoneIfNotRegisterd(userphone) {

              $.ajax({
                    type: "GET",
                    dataType: "Json",
                    url: '@Url.Action("GetUserByPhone", "User")' + '?phone=' + userphone,
                    async: false,
                    success: function(data) {
                        if (data == null || data.data == null) {
                            ErrorMessage("", "@Resource_en.YourPhoneDoesNotExistInOurDatabase");
                        } else {
                            user = data[Object.keys(data)[0]];
                                AddVereCode(user.ID);// anather Ajax call 
                                SuccessMessage("Done", "@Resource_en.VerificationCodeSentSuccessfully", "Done");
                        }
                    },
                    error: function() {
                        ErrorMessage("", '@Resource_en.ErrorOccourd');
                    }
                });
            }

除了使用控制器调用之外,您应该创建自定义帮助程序以仅更改字符串格式。

I tried lashrah's answer and it worked after changing syntax a little bit.我尝试了 lashrah 的答案,在稍微改变语法后它就起作用了。 this is what worked for me:这对我有用:

@(
  ((HomeController)this.ViewContext.Controller).Method1();
)

You should not call a controller from the view.您不应该从视图中调用控制器。

Add a property to your view model, set it in the controller, and use it in the view.向视图模型添加一个属性,在控制器中设置它,然后在视图中使用它。

Here is an example:这是一个例子:

MyViewModel.cs: MyViewModel.cs:

public class MyViewModel
{   ...
    public bool ShowAdmin { get; set; }
}

MyController.cs: MyController.cs:

public ViewResult GetAdminMenu()
    {
        MyViewModelmodel = new MyViewModel();            

        model.ShowAdmin = userHasPermission("Admin"); 

        return View(model);
    }

MyView.cshtml: MyView.cshtml:

@model MyProj.ViewModels.MyViewModel


@if (@Model.ShowAdmin)
{
   <!-- admin links here-->
}

..\Views\Shared\ _Layout.cshtml: ..\Views\Shared\ _Layout.cshtml:

    @using MyProj.ViewModels.Common;
....
    <div>    
        @Html.Action("GetAdminMenu", "Layout")
    </div>

我认为直接从视图调用控制器操作或类方法可能会产生解除锁定问题,因为它会在这里使用 UI 线程。如果我错了,请纠正我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM