简体   繁体   English

如何知道在Datasnap REST服务上调用的方法

[英]How to know the method called on a Datasnap REST service

On a Datasnap REST Service (ISAPI module) I would like to be able to know the method called. 在Datasnap REST服务(ISAPI模块)上,我希望能够知道所调用的方法。 I'm going to use it on a generic routine to Write Logs on every Error/Exception that happens. 我将在通用例程上使用它,以在发生的每个错误/异常上写入日志。

procedure WriteLog(Error: string);
var Log, Service, LogFile: string;
begin
  Service := ExtractFileName(GetModuleName(HInstance));
  Service := Copy(Service, 1, Service.Length - 4);
  if not TDirectory.Exists('C:\Logs') then TDirectory.CreateDirectory('C:\Logs');
  if not TDirectory.Exists('C:\Logs\' + Service) then TDirectory.CreateDirectory('C:\Logs\' + Service);
  LogFile := 'C:\Logs\' + Service + '\' + FormatDateTime('yyyy-mm-dd_hh-nn-zzz', Now) + '.txt';

  Log := 'Call : ' + XXXXXX + sLineBreak;
  Log := Log + 'User : ' + TDSSessionManager.GetThreadSession.GetData('User') + sLineBreak;
  Log := Log + 'IP : ' + TDSSessionManager.GetThreadSession.GetData('RemoteIP') + sLineBreak;
  Log := Log + 'Error : ' + sLineBreak + Error;
  TFile.WriteAllText(LogFile, Log);
end;

I need to substitute XXXXXX with the name of the method called. 我需要用所调用方法的名称替换XXXXXX。

This information is available on the WebModule of the service, at the Request param of the WebModuleBeforeDispatch event. 该信息在服务的WebModule上的WebModuleBeforeDispatch事件的Request参数中可用。

But I can't set that value in the Session Data (so it would be accessible for my WriteLog routine) because at that moment there is no session yet. 但是我无法在会话数据中设置该值(因此我的WriteLog例程可以访问该值),因为那时还没有会话。

This code raises an AV: 这段代码引发了一个AV:

procedure TWebModule1.WebModuleBeforeDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
  Response.SetCustomHeader('Access-Control-Allow-Origin','*'); 

  if Trim(Request.GetFieldByName('Access-Control-Request-Headers')) <> '' then begin
    Response.SetCustomHeader('Access-Control-Allow-Headers', Request.GetFieldByName('Access-Control-Request-Headers'));  
    Handled := True;  // I answer to CORS calls
  end;

  TDSSessionManager.GetThreadSession.PutData('MethodCalled', Request.PathInfo);

  if FServerFunctionInvokerAction <> nil then
    FServerFunctionInvokerAction.Enabled := AllowServerFunctionInvoker;
end;

At the moment I have set a threadvar variable on the WebModule to hold this value, so it can be accessible for the WriteLog routine. 目前,我已经在WebModule上设置了一个threadvar变量来保存此值,以便WriteLog例程可以访问它。

It works but a global variable is a very ugly solution, and more importantly, it causes an small memory leak after every call. 它可以工作,但是全局变量是一个非常丑陋的解决方案,更重要的是,它在每次调用后都会引起较小的内存泄漏。

Where do you think that I could save that value so I can read it when I need it ?. 您认为我可以在哪里保存该值,以便在需要时可以读取它?

Thank you. 谢谢。

我认为可以从DSAuthenticationManagerUserAuthorize事件中的EventObject.MethodAlias访问它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM