博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Remoting中向服务器传送新对象时应注意的问题

Posted on 2009-03-16 20:20  faib  阅读(818)  评论(0编辑  收藏  举报

背景:

本人将Remoting部署在服务器了的Windows Service中,代码如下

BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
                serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
                BinaryClientFormatterSinkProvider clientProv = new BinaryClientFormatterSinkProvider();
                IDictionary props = new Hashtable();
                props["port"] = 11982;
                TcpChannel channel = new TcpChannel(props, clientProv, serverProv); 

                ChannelServices.RegisterChannel(channel, false);
                RemotingConfiguration.ApplicationName = "ChanceService";
                RemotingConfiguration.RegisterActivatedServiceType(typeof(ATMemberType));


 

ATMemberType类是一个继承自

    /// <summary>
    /// 数据访问基类。
    /// </summary>
    /// <typeparam name="E">实体类。</typeparam>
    /// <typeparam name="C">实体集合类。</typeparam>
    public abstract class BaseDataAccess<E, C> : MarshalByRefObject


其中提供了创建实体Create(E entity),更新实体Update(E entity)等方法

        /// <summary>
        /// 创建实体。
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        public bool Create(E entity)
        {
            bool ret = false;
            ParameterCollection pars = data.CreateParameters();
            pars = pars.FromDataModel(entity, null, data.ParameterPrefix);
            if (data is Oracle)
            {
                entity.SetValue(primaryKey, ((Oracle)data).GetSequence("SQ_" + entity.TableName).NextVal);
                ret = data.ExecuteNonQuery(pars.Format("INSERT INTO " + entity.TableName + "({0}) VALUES({1})"), pars) > 0;
            }
            else if (data is SqlServer)
            {
                int id = int.Parse(data.ExecuteScalar(pars.Format("INSERT INTO " + entity.TableName + "({0}) VALUES({1});select scope_identity() as 'id'"), pars).ToString());
                entity.SetValue(primaryKey, id);
                ret = id != 0;
            }
            return ret;
        }

在客户端中,通过DA的Type激活创建了DA对象

        public static object CreateDA(Type type, object[] param)
        {
            //根据配置文件创建不同的DA类
            object Instance = null;
            string serverStr = "tcp://" + ConfigurationManager.AppSettings["Server"] + "/ChanceService";
            object[] attrs = { new UrlAttribute(serverStr) };
            Instance = Activator.CreateInstance(type, param, attrs);
            if (Instance != null)
                return Instance;
            else throw new Exception("无法创建数据库DA对象");

         }
 

调用处:

            ATMemberType da = (ATMemberType)DAFactory.CreateDA(typeof(ATMemberType));
            TMemberType info = new TMemberType;
            SetInfo(info);
            da.Create(info)

Create时在这里出错,出错信息为 此远程处理代理没有信道接收,这意味着服务器没有正在侦听的已注册服务器信道,或者此应用程序没有用来与服务器对话的适当客户端信道。

就因为这问题折磨了我一天晚上,找尽了所有可用资源,还是没有解决。今天下午试着写一个日志,看看到底出错在哪,结果发现,问题应该就出在E的实例化处。于是,在BaseDataAccess 中新加一个属性


        public E NewEntity
        {
            get { return new E(); }
        }

客户端稍稍改动一下

            ATMemberType da = (ATMemberType)DAFactory.CreateDA(typeof(ATMemberType));
            TMemberType info = da.NewEntity;
            SetInfo(info);
            da.Create(info);

OK问题解决了,我不知道该佩服自己还是要检讨自己,这么一个小小的错误竟让自己郁闷了一天晚上。