0

我可能没有正确的词,但我已经尽力了。

假设我在 c# 中有一个函数,例如 DoWork,并且在该函数中我想调用另一个函数,例如 CheckScore()。但是, CheckScore() 是我想从多个地方调用的通用函数。

因此,在我的课堂上,当我创建另一个函数 DoWork2、DoWork3 时,有什么方法可以将 CheckScore() 作为第一行执行,而不是每次都输入这些函数?

例如。我可以避免吗

string DoWork2(){
CheckScore()
}

相反,只有

string DoWork2(){}

但是 CheckScore() 无论如何都会执行?

4

4 回答 4

2

一种可能的(尽管仍然不是万无一失的)方法是将您的安全检查抽象为属性。这样,您可以使用以下内容装饰您的方法:

[CheckToken]
public string DoWork() {
  ....
}

这不一定是最好的答案,因为它仍然需要您对方法进行归因。您可以改为为您的 Web 服务类创建一个属性,该属性将在该类的任何方法调用上执行 [CheckToken]。

[CheckToken]
public class MyWebService {
   ...
}

这里唯一的问题是,如果您有一些方法要执行不同的安全检查,或者没有安全检查。

具有很好的安全功能的 AC# Web 服务框架是 Service Stack。http://www.servicestack.net/它已经内置了可以使用的安全属性,它促进了关注点的清晰分离。

另一个非常强大的选项涉及拦截方法调用。C# 有一个可用于此目的的“ContextBoundObject”类。您需要让您的类从 ContextBoundObject 继承,然后您可以开始动态拦截方法调用并根据正在进行的方法调用的上下文及其参数执行安全检查。ContextBoundObject 确实为您的调用增加了一些开销,因此您需要将其纳入您的决定。方法拦截非常适合安全、性能监控、健康检查、方法重试和其他横切关注点。

这是一篇关于 ContextBoundObject(和面向方面编程)的简单入门文章。http://www.codeproject.com/Articles/8414/The-simplest-AOP-scenario-in-C

对于杰...

我不会让方法代码查询结果。由于我们谈论的是 Web 服务,因此涉及到一个管道,其中客户端发起请求,该请求被发送到服务,该服务初始化其处理程序,反序列化请求,将请求路由到适当的方法,执行该方法,序列化响应,并将响应返回给客户端(这是一个很大的简化..)。我见过的大多数框架都有一些钩子供您指定服务方法上的属性,这些属性在方法执行之前被检查并且可用于处理安全性(即,为 Web 服务返回 401 http 代码)。我相信他说他正在使用 WCF,虽然我已经有一段时间没有使用 WCF,但我知道这是可以做到的 - 请参阅http://msdn.microsoft。

因此,他可以从某个 WCF 安全属性派生出他的自定义安全属性,并基于某个令牌创建自己的身份验证逻辑,他很可能必须从请求的标头中获取这些令牌。ServiceStack 让这变得超级简单,我想使用 WCF 也不是那么难。很可能有人已经为 WCF 完成了这项工作,并且代码就在某个地方。

于 2013-07-18T03:34:17.407 回答
0

Given the additional information in comments, one solution to this problem is to create a small class to encapsulate methods which require authentication :

abstract class AuthenticateClass
{
    private bool AuthenticateUser(){
        return true;  // do your authentication
    }
    public int Perform(){
        if (!AuthenticateUser()){
            return -1;
        } else 
            return AuthenticatedMethod();
    }

    protected abstract int AuthenticatedMethod();
}

This gives you a class that performs the authentication and, if successful, performs your method. Implement it like :

class SomeAuthentMethod : AuthenticateClass 
{
    protected override int AuthenticatedMethod()
    {
        return 10; // whatever method...
    }
}

and use it like :

 SomeAuthentMethod myMethod = new SomeAuthentMethod();
 if (myMethod.Perform() = -1){
     //  unable to authenticate user, please log in, etc
 }

If the authentication passes this returns 10, otherwise it returns -1 (authentication failed). This lets you generate any number of methods which automatically include authentication.

Alternatively, you might use a static class to do the authentication -- for example :

static class Authenticate
{
    public delegate int MethodDelegate();

    private static bool AuthenticateUser(){
        return true;    // do your authentication
    }
    public static int Perform(MethodDelegate MyMethod){
        if (!AuthenticateUser())
        {
            return -1;
        }
        else return MyMethod();
    }
}

Where you could then have :

private int myMethod(){
        return 10;  //whatever method...
}

and then implement like :

if (Authenticate.Perform(myMethod) = -1){
     //  unable to authenticate user, please log in, etc
 }

Obviously you can extend both of these patterns to handle whatver "not logged in" or "not authenticated" action within the abstract or static class itself. This should, at least, provide a few ideas of how to approach the problem.

于 2013-07-18T02:51:54.120 回答
0

这可能不是您正在寻找的内容,但是当访问分数时,我会将“CheckScore”与属性的 getter 相关联。这样,当使用该属性时,感觉就像您没有写出很多 CheckScore,而且您没有在每次在应用程序中调用任何旧方法时都调用 CheckScore 函数。

    private int _score;

    public int Score
    {
        get
        {
            CheckScore();
            return _score;
        }
    }

    public void DoWork1()
    {
        if (Score > 10) { 
           // Case 1
        }
    }

    public void DoWork2()
    {
        if (Score < 20) { 
          // Case 2
        }
    }
于 2013-07-17T23:41:31.757 回答
0

将 CheckScore 放在一个属性中仍然会导致它被大量调用。

您可以使用私有只读字段并将其设置在构造函数中。这将最大限度地减少对 CheckScore 的调用次数。

public class MyClass
{
    private readonly int _score;

    public MyClass()
    {
        _score = CheckScore();
    }

    public int Score
    {
        get
        {
            return _score;
        }
    }

    public void DoWork1()
    {
        if (Score > 10) { 
           // Case 1
        }
    }

    public void DoWork2()
    {
        if (Score < 20) { 
          // Case 2
        }
    }
}
于 2013-07-18T03:13:09.703 回答