【问题标题】:MVC execution pipeline: Ajax call executing before Controller initializationMVC 执行管道:在 Controller 初始化之前执行 Ajax 调用
【发布时间】:2018-10-03 18:54:25
【问题描述】:

我对 MVC 中的执行顺序存在架构误解。

我正在重写我的初始化

public class HomeController: Controller {

    protected override void Initialize(RequestContext requestContext)
    { 
       var myVar = "AValue";
       // basically run some internal security 
       initialization
    }

然后在我的 javascript 中,我使用延迟的 promise() 运行一系列 10 个 Ajax 调用。

Onload 设置它们并使用 $when 运行

然后

js:

this.BeginMyAjaxQuery = function() {
   methodName:  MyAjaxQuery
};

在一个完全不同的控制器上,它继承了我的 HomeController

public JsonResult MyAjaxQuery()
{           
     return Perform(() =>
     { 
        return ThisQueryWithMyParameter(AValue); 
     });
 }

Perform 是我们成功用来创建 JsonResults 的包装器

关于我对 MVC 架构行为方式的误解: 当我加载我的 URL 时,AJAX 在我完成 HomeController 初始化之前一直在它自己的线程上运行。因此,我的变量没有设置,当我执行实际查询时,我收到不正确的结果......大多数时候但并非总是如此。这当然更烦人。

我的 ajax 调用如何绕过我的控制器初始化并直接转到控制器方法?

增加我的困惑 将我的代码添加到 HomeController 上的构造函数中的行为方式相同。结果不稳定。

最后一点,如果重要的话:使用 Partial Views 和 KnockoutJS 进行前端交付

【问题讨论】:

  • 可能涉及到任何“静态”吗?
  • 有静电!我试图在 Initialize 函数中设置的是我的安全用户。我不熟悉 a/a/a 过滤器。我会去看看那些,然后回复你。
  • 添加一点上下文,因为我的描述由于复杂性而显得相当简陋:我们有一个本土安全机制,它利用一些 AD 信息与特定的“功能”控制相结合。我们正在获取 Identity 的上下文,然后往返于数据库以获取我们的内部标识符以确定各种访问权限。正是从那次往返中,我获得了正确执行 ajax 查询所需的信息。我还不明白我的 ajax 是如何“绕过”控制器初始化的。这似乎违反直觉,但我可能只是看错了。
  • 好的,static 可能有问题,因为它没有重新初始化:它将在所有线程中保留其值。如果将其设置为1,则在所有线程上都是1。有关 mvc 管道,请参阅 this link。这里有一些例子about action filters。如果它是安全的,您可能需要一个身份验证操作过滤器。
  • 斯特凡——你真漂亮!谢谢你澄清说我整个早上都在角落里抽泣。

标签: javascript c# ajax asp.net-mvc controller


【解决方案1】:

staic 问题

如您所述,您使用的是static。虽然这有助于从基本上任何地方访问它,但它有另一个属性:它只初始化一次,你给它的值是所有线程上的值。 (嗯,实际上这有更多的细微差别,比如处理器级缓存,但我现在认为这超出了范围。)

至于现在:您应该认为它好像内存中只有 1 个 Security User 对象。如果你给它一个值,它将是所有线程上的那个值。

public class HomeController: Controller {

    //note! static: the `new` is called only once!
    static SecurityUser = new SecurityUser();

    protected override void Initialize(RequestContext requestContext)
    { 
       //so SecurityUser is not a fresh object.
       //setting values will be shared between all 
       //threads (since there is only one SecurityUser object in memory

       //shared across all threads
       SecurityUser.Ip = "127.0.0.2";
    }


MVC 管道

正如wikipedia 所说:

在计算中,管道,也称为数据管道,是一组串联的数据处理元素,其中一个元素的输出是下一个元素的输入。

一般来说,它描述了数据流以及处理请求时所涉及的操作。

到处都有关于它的文章,例如:herehere

MSDN 图片解释得很好(也很完整),我在下面添加了它。

如果您查看图片,您会看到AuthenticationFiltersAuthorizationFiltersActionFilters。 (有关它们的更多信息,请参阅此link。)

它们的目的是为部分或全部调用的 ActionMethod 执行代码、身份验证等。通过使用它们,您可以隔离您的身份验证行为(这是良好的 OO 实践)并保持您的代码可维护。这个想法是,您只需要定义一次您的特殊安全事物。

您可以使用它来初始化具有特定接口的对象,例如:ISecurity 具有一些属性,例如 ip 地址、用户名、管理员权限等。该对象可以填写在操作过滤器中,并且可以使用每个 http 调用中的依赖解析器。像魅力一样工作。

图片来源:msdn

【讨论】:

    猜你喜欢
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 2021-06-03
    • 2019-11-13
    • 2021-04-05
    相关资源
    最近更新 更多