如何根据构造函数中的逻辑中止 ASMX 请求?

发布于 2024-09-08 20:11:43 字数 1020 浏览 1 评论 0原文

我有一个公共基类,我的所有 ASMX Web 服务类都将从该基类继承。在构造函数中,我想做一些常见的身份验证检查;如果失败,我想立即停止处理(子类的代码不会被执行)并向调用者返回 401 状态代码响应。

然而,常见的类似 ASPX 的方法似乎不起作用:

  1. Context.Response.End();总是在 500 状态代码响应中向调用者返回 ThreadAborted 异常。即使我在调用 End() 之前显式设置 Context.Response.StatusCode = 401,它也会被忽略。结果仍然是 500 响应,并且消息始终是“线程中止异常”。
  2. MSDN 建议我使用 HttpContext.Current。相反,ApplicationInstance.CompleteRequest()。但是,这不会停止下游处理:我的子类的函数仍然执行,就好像构造函数什么也没做一样。 (有点违背了在构造函数中检查授权的目的。)
  3. 我可以抛出一个新的 HttpException。这更好一点,因为它确实阻止了下游处理,并且至少它使我能够控制返回给调用者的异常消息。然而,它并不完美,因为响应仍然始终是 500。
  4. 我可以定义一个 DoProcessing 实例 var,并在构造函数中将其设置为 true/false。然后让每个子类中的每个 WebMethod 将其功能包装在 if (DoProcessing) 块中...但让我们面对现实吧,这太可怕了!

是否有更好/更彻底的方法来实现此类功能,因此它对我的所有 ASMX 类都是通用的?

编辑:接受约翰的回答,因为这可能是最好的方法。然而,由于客户不愿意采用额外的第 3 方代码,以及对 AOP 的某种程度的 FUD,我们没有采取这种方法。我们最终选择了上面的选项#3,因为它似乎在实施速度和灵活性之间取得了最佳平衡,并且仍然满足要求。

I have a common base class from which all my ASMX webservice classes will inherit. In the constructor, I want to do some common authentication checks; if they fail, I would like to halt processing right away (subclass's code would not get executed) and return a 401-status-code response to the caller.

However, the common ASPX-like ways of doing this don't seem to work:

  1. Context.Response.End(); always kicks back a ThreadAborted exception to the caller, within a 500-status-code response. Even if I explicitly set Context.Response.StatusCode = 401 before calling End(), it is ignored. The result is still a 500-response, and the message is always "thread-aborted-exception".
  2. MSDN suggests I use HttpContext.Current.ApplicationInstance.CompleteRequest() instead. However, this does not stop downstream processing: my subclass's functions are still executed as if the constructor had done nothing. (Kind of defeats the purpose of checking authorization in the constructor.)
  3. I can throw a new HttpException. This is a little better in that it does prevent downstream processing, and at least it gives me control over the exception Message returned to the caller. However, it isn't perfect in that the response is still always a 500.
  4. I can define a DoProcessing instance var, and set it to true/false within the constructor. Then have every single WebMethod in every single subclass wrap its functionality within an if (DoProcessing) block... but let's face it, that's hideous!

Is there a better / more thorough way to implement this sort of functionality, so it is common to all my ASMX classes?

edit: Accepting John's answer, as it is probably the best approach. However, due to client reluctance to adopt additional 3rd-party code, and some degree of FUD with AOP, we didn't take that approach. We ended up going with option #3 above, as it seemed to strike the best balance between speed-of-implementation and flexibility, and still fulfill the requirements.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野の 2024-09-15 20:11:43

最好的方法是切换到 WCF,它明确支持这种情况。

如果您仍然必须使用 ASMX,那么最好的选择是从每个 Web 方法中调用基类方法。您可能想要使用像 PostSharp 这样的东西来“神奇地”使您的所有 Web 方法调用基类方法。

The best way to do it would be to switch to WCF, which has explicit support for such a scenario.

If you must still use ASMX, then your best bet is to call the base class methods from each web method. You might want to use something like PostSharp to "magically" cause all of your web methods to call the base class method.

弄潮 2024-09-15 20:11:43
 Context.Response.Write("My custom response message from constructor");
 Context.Response.StatusCode = (int)HttpStatusCode.Forbidden;       
 Context.Response.End();

该代码阻止在构造函数之后传入 Web 方法。

 Context.Response.Write("My custom response message from constructor");
 Context.Response.StatusCode = (int)HttpStatusCode.Forbidden;       
 Context.Response.End();

That code prevent to pass in web method after constructor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文