我有几个执行不同操作的事件处理程序(例如发出HTTP请求)。我想检查用户是否在从事件处理程序执行代码之前登录。
目前我这样做:
private void Publish_Click(object sender, RibbonControlEventArgs e)
{
try
{
var temp = GlobalVariables.sessionData["loggedUser"];
}
catch (Exception ex) {
if (ex is NullReferenceException || ex is KeyNotFoundException)
{
MessageBox.Show("Please log in");
return;
}
throw;
}
publishBTaskPane = new BTaskPane();
myTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(publishBTaskPane, "Publish");
myTaskPane.VisibleChanged += new EventHandler(myTaskPane_VisibleChanged);
myTaskPane.Visible = true;
}
我想在事件处理程序之外保留'try'子句。
在Python中,您可以使用装饰器。
def login_required(handler):
"""
Decorator which performs a user authentication before a particular handler is executed.
"""
def check_login(self, *args, **kwargs):
if not self.user:
return self.redirect('/login')
else:
return handler(self, *args, **kwargs)
return check_login
class LogoutHandler(BaseHandler):
"""
Terminate the user session and return them to the login screen.
"""
@login_required
def get(self):
self.auth.unset_session()
if not self.request.user_agent:
return self.response.write('OK')
self.redirect('/login')
是否有可能在C#中做类似的事情,所以我不必在每个事件处理程序中重复try子句?
答案 0 :(得分:1)
这将是一种通用的答案,因为我没有完整的问题背景来确定答案,但希望你可以根据自己的需要进行调整。
首先,获得最接近的方法是创建自己的注释并让它包装方法,但这需要一些额外的学习(假设你还不知道它)才能完成。< / p>
最简单的方法可以创建一个您在这些处理程序中首先调用的函数:
public boolean notLoggedIn() {
try {
var temp = GlobalVariables.sessionData["loggedUser"];
return false;
}
catch (Exception ex) {
if (ex is NullReferenceException || ex is KeyNotFoundException) {
MessageBox.Show("Please log in");
return true;
}
throw;
}
}
由处理程序使用:
private void Publish_Click(object sender, RibbonControlEventArgs e) {
if(notLoggedIn())
return;
publishBTaskPane = new BTaskPane();
myTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(publishBTaskPane, "Publish");
myTaskPane.VisibleChanged += new EventHandler(myTaskPane_VisibleChanged);
myTaskPane.Visible = true;
}
另一件要尝试的是Execute Around Method模式。您可以使用通用登录检查程序运行实际方法所执行的lambda。所以,使用这个:
public void ifLoggedIn(Action action) {
try {
var temp = GlobalVariables.sessionData["loggedUser"];
action();
}
catch(Exception e) {
if (ex is NullReferenceException || ex is KeyNotFoundException) {
MessageBox.Show("Please log in");
return true;
}
throw;
}
}
这样的处理程序可以使用:
public void Public_Click(object send, RibbonControlEventArgs e) {
ifLoggedIn( () => {
publishBTaskPane = new BTaskPane();
myTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(publishBTaskPane, "Publish");
myTaskPane.VisibleChanged += new EventHandler(myTaskPane_VisibleChanged);
myTaskPane.Visible = true;
}
}
还有一些其他方法可以轻松应用“包装”我想到的,但我认为任何方法都不能很好地解决您的问题。
答案 1 :(得分:0)
C#中Python装饰器的等价物是member attribute。一个区别是属性没有执行,只是通过反射访问。我想知道,由于C#支持为一个事件提供多个处理程序,因此可以为所有事件设置一个处理程序,以检查其他处理程序是否具有此属性,如果是,则执行登录检查。