尝试RemotingSqlHelper的若干问题
Some issues in RemotingSqlHelper class
本来准备以Microsoft提供的SqlHelper Class为基础,改写成基于.Net Remoting版本的数据访问类RemotingSqlHelper。整个过程出现了不少异常,也了解到使用.Net Remoting过程中需要注意的若干问题。
BTW,如果对上述议题不清楚,可以参考下面的链接Reference 1:《将SqlHelper Class部署为Remote Object可行吗?》
下面按照整个过程的步骤,针对这些问题进行简要分析:
(1)改写SqlHelper和SqlHelperParameterCache类,删除static关键字,然后相应修改内部的方法,这步比较简单。并创建web.config配置文件,进一步测试RemotingSqlHelper成功部署在IIS中(可以参考《如何检测Remote Objects是否部署成功》)。
(2)使用SoapSuds生成RemotingSqlHelper类的元数据(Metadata),这里发现了一个问题:RemotingSqlHelper class中带有params参数的方法在SoapSuds产生的元数据中丢失了params关键字。
如下RemotingSqlHelper方法:
public int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
在生成的元数据中变为(丢失了params):
public int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, SqlParameter[] commandParameters)
只好通过SoapSuds的-gc选项生成source code,然后手工编辑产生的文件。OK,这个问题就这样解决了。
(3)修改Client端Application,这步也比较简单。
先建立Client端configuration配置文件,然后在Client端引用Remote Objects。
(4)开始正式调试Client端Application,各种异常及其分析登场了。
(I)An unhandled exception of type 'System.Runtime.Remoting.RemotingException' occurred in mscorlib.dll
Additional information: This remoting proxy has no channel sink which means either the server has no registered server channels that are listening, or this application has no suitable client channel to talk to the server.
第一个异常信息显示remoting proxy没有通道接收器(channel sink),或者Server端没有注册监听的Server通道,或者Client端Application没有合适的通道与Server通话。其实,就是Server端回调Client,没有Client端的通道信息。只要在Client端configuration文件进行如下设置:
<channel ref="http" port="0">
上述异常就不出现了。
(II)An unhandled exception of type 'System.Runtime.Remoting.RemotingException' occurred in mscorlib.dll
Additional information: Permission denied: cannot call non-public or static methods remotely.
马上第二个异常信息出现了,显示拒绝访问:不能远程调用非pulic或static方法。
为什么会出现这个问题呢?看看下面这个方法:
public int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
Client端在调用上述Remote Method时,需要传入SqlConnection和SqlParameter对象,SqlConnection和SqlParameter都是MarshalByRefObject对象,这样仅仅只有Client端对象引用(a reference to the client object)传递到Server端,而不是实际的对象。因此,在Server端执行上述Remote Method时,需要回调Client的上述对象(现在知道为什么异常1会出现了吧!),而Server没有权限调用Client端的对象,就抛出Exception了。
以SqlHelper Class中ExecuteNonQuery()方法为例,ExecuteNonQuery()方法共有9个重载,适合client端以Remoting方法调用的,仅仅只有一个:
ExecuteNonQuery(string connectionString, CommandType commandType, string commandText)
SqlHelper class中令人向往的调用stored procedure,并传入SqlParameter参数的方法在这里就无法使用了,这一点比较遗憾。不过,仍可以通过在Business Rules层拼接SQL Script指令调用stored procedure并调用上述方法来完成,显然代码的可读性及维护性就比较差了。
以上是个人的一些观点,如果你有不同的意见或者更好的办法来实现基于.Net Remoting的数据访问类,或者有什么疑问,请留言并参与讨论。谢谢。
Reference:
1, Rickie, 《将SqlHelper Class部署为Remote Object可行吗?》
2, Rickie, 《如何检测Remote Objects是否部署成功》
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?