您的位置:首页 > 编程语言 > C#

c#如何使用webservice、存储过程及存储过程的创建(简单模仿类似QQ统计用户在线时间为例)

2011-11-18 17:15 856 查看
在这个小应用中,要用到webservice,因此简单介绍一下webservice。在实际应用中从客户端传送信息至服务端,使用webservice是一个不错的方法,它是一种构建应用程序的普遍模型,可以在任何支持网络通信的操作系统中实施运行。NET平台内也建立了对Web Service的支持,包括Web Service的构建和使用。NET Framework本身就全面支持Web Service,包括服务器端的请求处理器和对客户端发送和接受SOAP消息的支持。因此不需要其他的工具或者SDK就可以完成Web
Service的开发了。

那么下面我们看看如何在服务器统计用户的在线时间。

环境:visual studio 2008;.net framework 2.0;Oracle 10g

功能实现:有两个表usertable a,userinfotable b, a存放用户基本固有信息,b表存放用户使详细信息及时间。当用户上线时程序中的webservice上传一次用户启动时间,当用户下线程序中webservice再次发送用户停止使用时间,进行保存,记录了一次用户使用时间,方便进行后续处理。

设计过程如下:

一、数据库设计

1、设计数据表

usertable

字段类型说明
idinteger表id,自增序列,主键
usersequencevarchar2(100)用户QQ号码,非空,唯一
uipvarcha2r(50)用户ip地址,从客户端获取
uaddressvarchar2(100)用户所在地址,从客户端根据ip获取
usystemvarcar2(32)用户使用的操作系统的位数,从客户端获取
useraddtimedate用户注册时间,也就是第一次插入数据的时间
userinfotable

字段类型说明
id integer表id,自增序列,主键
consumeridinteger用户id,外键,usertable表userid关联
ustarttimedate用户本次启动软件时间
uendtimedate用户本次关闭软件时间
usertotaltimesinteger用户使用累计时间
useraddtimedate用户最后一次使用时间
2、详细SQL

(1)、创建表,序列

create table usertable
(
  id       INTEGER not null,
  usersequence      varchar2(100),
  uip       varchar2(50),
  uaddress VARCHAR2(100),
  usystem VARCHAR2(32),
  useraddtime date
)
create table userinfotable
(
  id  INTEGER not null,
  consumerid INTEGER,
  ustarttime   date,
  uendtime date,
  usertotaltimes number(30),
  useraddtime date
)
CREATE SEQUENCE  USERTABLE_SEQUENCES 
    INCREMENT BY 1
  START WITH 1 
  MAXVALUE   9999999999999999999
CREATE SEQUENCE USERINFOTABLE_SEQUENCES 
    INCREMENT BY 1
  START WITH 1 
  MAXVALUE   9999999999999999999

(2)、存储过程

开启qq时发送信息的存储过程

create or replace procedure startqqprocedure
(qq in varchar2,ip in varchar2,address in varchar2,systemname in varchar2)
 as
  userid  number; 
  infoid  number;
  begin
    select count(a.id) into userid from usertable a where a.usersequence=qq;
     if userid >0
      then
       update usertable a set a.uip =ip,a.uaddress=address,a.usystem=systemname where a.usersequence = qq;
      else
       select usertable_sequences.nextval into userid from dual;
       insert into usertable (id,usersequence,uip,uaddress,usystem,useraddtime) 
       values(userid,qq,ip,address,systemname,sysdate);
     end if;
       insert into userinfotable(id,consumerid,ustarttime,uendtime,usertotaltimes,useraddtime)
       values(userinfotable_sequences.nextval,userid,sysdate,sysdate,0,sysdate);
commit; 
exception
when others then
rollback;
end startqqprocedure;

关闭qq时发送信息的存储过程

create or replace procedure closeqqprocedure
(qq in varchar2,ip in varchar2,address in varchar2,systemname in varchar2)
  as
  userid   number;
  begin
   select count(a.id) into userid  from usertable a where a.usersequence=qq;
   if userid >0
     then
        update usertable a set a.uip =ip,a.uaddress=address,a.usystem=systemname where a.usersequence = qq;
   else
       select usertable_sequences.nextval into userid from dual;
       insert into usertable (id,usersequence,uip,uaddress,usystem,useraddtime) 
       values(userid,qq,ip,address,systemname,sysdate);
  
        insert into userinfotable(id,consumerid,ustarttime,uendtime,usertotaltimes,useraddtime)
     values(userinfotable_sequences.nextval,userid,sysdate,sysdate,0,sysdate);
     end if;
     
     update userinfotable c set c.uendtime=sysdate,c.usertotaltimes= round(c.usertotaltimes)+
     round(to_number(sysdate-c.ustarttime)*1440)where c.consumerid = userid;
 commit; 
exception
when others then
rollback;
end closeqqprocedure;

二、代码实现

1、服务器端webservice实现。

数据库部分已完成,下面来进行程序实现,使用MVC设计模式,初步订三个类,webservice,DAO层QQWebServiceDao,执行sql语句SDProvider,实现各功能分离。

看看webservice如何写。

using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using QQWebApp.WebWork.Dao;

namespace QQWebApp.Service
{
    /// <summary>
    /// LMWebService 的摘要说明
    /// </summary>
    [WebService(Namespace = "QQWebservice")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class QQWebservice: System.Web.Services.WebService
    {
        [WebMethod]
        //启动软件后
        public bool FirstStart(string qq, string ip, string address,string systemname)
        {
            bool result = false;

            result = QQWebServiceDao.UploadStartCloseSoftInfo(qq, ip, address, systemname,true);

            return result;
        }
        [WebMethod]
        //关闭软件
        public bool EndStop(string qq, string ip, string address,string systemname)
        {
            bool result = false;

            result = QQWebServiceDao.UploadStartCloseSoftInfo(qq, ip, address, systemname,false);

            return result;
        }
}

那么c#如何执行存储过程呢?写数据库执行类,包括数据库连接,执行sql。

using System.Data;
using System.Configuration;

using System.Collections.Generic;
using System.Data.OracleClient;
using System.Diagnostics;
using System;

namespace QQWebApp.WebWork.Data
{
    public class SDProvider
    {
        public static string GetConnectionString()
        {
            string conStr = "User ID=qqsoft;data source=orcl;password=sys";
            return conStr ;
        }
        
       public static int RunProcedure(string storedProcName, IDataParameter[] parameters)
        {
            int result = 0;

            try
            {
                using (OracleConnection connection = new OracleConnection(GetConnectionString()))
                {
                    connection.Open();

                    OracleCommand command = BuildQueryCommand(connection, storedProcName, parameters);

                    result = command.ExecuteNonQuery();//返回受影响的行数
                }
            }
            catch (Exception e)
            {
                Debug.Assert(false, e.Message);
            }

            return result;
        }
        private static OracleCommand BuildQueryCommand(OracleConnection connection, string storedProcName,
            IDataParameter[] parameters)
        {
            OracleCommand command = new OracleCommand(storedProcName, connection);

            command.CommandType = CommandType.StoredProcedure;

            foreach (OracleParameter parameter in parameters)
            {
                command.Parameters.Add(parameter);
            }
            return command;
        }
}

这个类完成了存储过程的执行,参数的传递。

下面可以开始写DAO层,该层负责参数的处理,并调用SDProvider执行存储过程。

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using QQWebApp.WebWork.Data;
using System.Data.OracleClient;

namespace QQWebApp.WebWork.Dao 
 public class QQWebServiceDao
 {
  public static bool UploadStartCloseSoftInfo(string qq, string ip,string address,string systemname,bool flag)
   { 
        int result = 0;            
        OracleParameter qqParameter = new OracleParameter("qq", OracleType.VarChar, 100);
        
        qqParameter.Value = qq;            
        OracleParameter ipParameter = new OracleParameter("ip", OracleType.VarChar, 100);
        
        ipParameter.Value = ip;             
        OracleParameter addressParameter = new OracleParameter("address", OracleType.VarChar, 100);
        
        addressParameter.Value = address;             
        OracleParameter systemnameParameter = new OracleParameter("systemname", OracleType.VarChar, 100);
        
        systemnameParameter.Value = systemname;             
        OracleParameter[] parameter = { qqParameter, ipParameter, addressParameter, systemnameParameter };             
        if (flag)
        {
          result = SDProvider.RunProcedure("startqqprocedure", parameter);
        }
        else
        {
        result = SDProvider.RunProcedure("closeqqprocedure", parameter);
        }             
        return result > 0 ? true : false;    
        }
    }
}

这样就完成了服务端的程序。webservice、存储过程实现了融合使用。在这部分有几点注意的地方。

(1)、写存储过程中,定义的参数是不需要定义长度的。在存储过程中声明的变量不用加in|out。

(2)、DAO层中GetConnectionString()获取数据库的连接,这个连接字符串可以通过加密存放在Web.config中,更安全一些。

2、客户端调用

这样客户端的调用就很简单,首先要添加刚才写好的webservice,webservice写好发布之后有一个地址,假设是:http://testQQ.WebService/QQWebService.asmx,在本地添加引用。

声明并实例化,

TestQQ.QQWebService service = new TestQQ.QQWebService ();

就可以调用service.看到FirstStart和endstop方法。不过在客户端还有一个任务,就是获取客户端的ip,省市地址和所使用的系统。获取ip参见/article/1419621.html,获取省市参见/article/1419634.html,获取使用的系统是32还是64位如下:

public class OSDetectQuery
 {
        public static string QueryOSVersion()
        {
            try
            {
                ConnectionOptions oConn = new ConnectionOptions();
                System.Management.ManagementScope oMs = new System.Management.ManagementScope("\\\\localhost", oConn);
                System.Management.ObjectQuery oQuery = new System.Management.ObjectQuery("select AddressWidth from Win32_Processor");
                ManagementObjectSearcher oSearcher = new ManagementObjectSearcher(oMs, oQuery);
                ManagementObjectCollection oReturnCollection = null;
                try
                {
                    oReturnCollection = oSearcher.Get();
                }
                catch (System.Exception ex)
                {
                }

                string addressWidth = null;
                foreach (ManagementObject oReturn in oReturnCollection)
                {
                    addressWidth = oReturn["AddressWidth"].ToString();
                }
                return addressWidth;
            }
            catch (System.Exception ex)
            {
                return "32";
            }

        }

       public static string OsVersion()
        {
            string queryos = QueryOSVersion();

            string osVersion = Environment.OSVersion.ToString();
            if (osVersion.Equals("Microsoft Windows NT 6.1.7600.0"))
            {
                if (queryos.Equals("64"))
                {
                    return "Win7-64";
                }

                if (queryos .Equals("32"))
                {
                    return "Win7-32";
                }

                return "Win7";
            }
            else if (osVersion.Equals("Microsoft Windows NT 6.1.7600.0"))
            {
                if (queryos.Equals("64"))
                {
                    return "Win7-64";
                }

                if (queryos.Equals("32"))
                {
                    return "Win7-32";
                }

                return "Win7";
            }
            return "WinXP";

        }
    }

那么需要上传的客户端信息以获取完毕,直接调用service方法上传就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐