如何在C#中以特定顺序处理事件?

Mat*_*tin 0 c# asp.net events event-handling

我有这个想法,在每个按钮的基本自定义页面中注册一个事件.我可以检查它是保存还是编辑,然后进行授权和验证.派生页面仍会处理单击事件以执行在该页面上保存的细节.我不确定哪个事件会先发生.(但它可能是连线的顺序)如果父页面首先运行,我可以通过设置IsAuthorized或IsValidated属性并在每个派生页面的单击处理程序中检查它来获得预期的行为.

无论如何,有没有办法确保基页的事件处理程序首先运行并完成,还是有办法挽救它?

编辑:我是否忽略了一个更简单的设计,不需要为应用程序中的每个编辑/保存/更新按钮添加锅炉板代码?什么是一个事件处理与另一个事件交流的正确方法?例如,基页需要传达成功或失败验证,派生类需要传达保存的成功或失败,以便可以将其记录在审计中.

//Base page-- seems like this will work if events happen in order of wireup.
protected override void OnInit(EventArgs e)
{
    foreach (Control possibleButton in Controls)
    {
        if(possibleButton is Button)
        {
            Button button = (Button) possibleButton;
            button.Command += ButtonCommandPreconditions;
        }
    }
    base.OnInit(e);
    foreach (Control possibleButton in Controls)
    {
        if(possibleButton is Button)
        {
            Button button = (Button) possibleButton;
            button.Command += ButtonCommandPostconditions;
        }
    }
}

void ButtonCommandPreconditions(object sender, CommandEventArgs e)
{
        if(e.CommandName=="Save" || e.CommandName=="Edit")
        {
            //Stuff that needs to happen before other handler   
            //Validate, display failures-- maybe set IsValdated property
            //Check for POST/GET, throw exception on GET.
            //Check for ID, throw exception on anonymous user
            //Check for authorization
            //Display authorization failures-- maybe set IsAuthorized property 
        }
}

void ButtonCommandPostconditions(object sender, CommandEventArgs e)
{
        if(e.CommandName=="Save" || e.CommandName=="Edit")
        {
             //Stuff that needs to happen *after* other handler
            //Log save
        }
}
Run Code Online (Sandbox Code Playgroud)

编辑:修改代码以反映事件处理程序应按照连线顺序处理.

wom*_*omp 5

事件只是多播委托,因此事件处理程序将按照它们添加到事件的顺序引发.

老实说,我会建议不要这样做.即使它工作,它也是非常不透明的 - 你在不同的类中有两个独立的事件处理程序处理相同的事件,它们之间没有明显的联系.

在执行自己的处理之前,将事件冒泡到父处理程序以便从每个继承的页面进行处理是更好的做法.这样就有了明确的联系,代码很容易理解,而且你不必依赖关于事件排序的假设.


编辑新问题:

什么是一个事件处理与另一个事件交流的正确方法?

你应该在这篇文章中看到我的答案. 事件处理程序实际上并不意味着在ASP.Net中相互通信(至少对于WebControl /页面生命周期事件处理程序),因为无法保证触发顺序.如果您的事件处理程序依赖于兄弟事件处理程序中设置的信息,那么您的设计可能存在缺陷.

例如,基页需要传达成功或失败验证,派生类需要传达保存的成功或失败,以便可以将其记录在审计中.

有几种方法可以解决这个问题.首先,只需使您的基类调用可以在派生页面中重写的抽象或虚拟方法.在基页中的按钮单击处理程序期间,执行所有验证,然后调用派生页面的抽象"DoSave()"方法,并检查以确保它成功.

或者,编写自己的事件,并在需要时提出它们.在基类中创建"验证"事件,如果需要响应,则让派生页面订阅它.确保您的基类在验证完成后引发它.在基类中创建一个"已保存"事件,它是一个事件处理程序,并让您的基类订阅它.让你的派生类引发该事件他们完成保存时.现在基类可以处理它的日志记录.


我想补充一点,好像你在基类按钮点击中加载了很多东西.您可以在页面呈现时执行匿名ID和GET/POST检查,如果没有权限则不会呈现按钮吗?