zoukankan      html  css  js  c++  java
  • webservice今日遇到的二个问题:DataTable + Namespace

    自从ms推出wcf以后,几乎没在web项目中用过webservice了,基本上都是以wcf host在iis中替代的。今天利用公司以前的web框架做一个新项目,里面大量使用了asmx,在开发过程中遇到了二个很少见的问题,记录如此,可能会帮助到遇到类似问题的同学们:
    一、在WebService中避免用DataTable做为参数类型,强烈推荐用DataSet来替换DataTable,否则会死得很惨
    场景如下:
    一个解决方案分三层:一层是Model,一层是WebService,一层是WebSite
    WebService层中提供基本的查询方法,但是调用方法时,必须提供登录后的验证票据信息.
    Model层中定义了验证票据Ticket类
    WebSite调用WebService层
    结构图如下:
    Model层中的Ticket类如下:
    namespace Model
    {
        public class Ticket
        {
            public int UserID { set; get; }
            public string UserName { set; get; }
            public string Role { set; get; }
    
            public Ticket()         
            {
                this.UserID = -1;
                this.UserName = "";
                this.Role = "";
            }
        }
    }
    
    WebService中的MyService.cs如下:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data;
    using System.Web.Services;
    using Model;
    
    /// <summary>
    /// Summary description for MyService
    /// </summary>
    [WebService(Namespace = "http://yjmyzz.cnblogs.com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class MyService : System.Web.Services.WebService
    {
    
        public MyService()
        {
    
            //Uncomment the following line if using designed components 
            //InitializeComponent(); 
        }
    
        [WebMethod(Description = "根据用户验证票据获取指定信息")]
        public int Query(ref DataTable dt, ref Ticket t)
        {
    
            //string sql = "select * from Table where id =" + t.UserID;
            //根据验证票据查询相关信息,如果有数据,将放到参数dt中
    
            return 1;//假定成功且有数据返回1,失败返回-1,成功但无数据返回0
        }
    
    }
    
    WebSite中的调用代码如下:
    using System;
    using System.Data;
    using YJM;
    
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            MyService ws = new MyService();
            //这里简化起见,直接生成一个票据
            Ticket t = new Ticket() { Role = "普通会员", UserID = 1, UserName = "杨俊明" };
            DataTable dt = new DataTable("myTableName");
            ws.Query(ref dt, ref t);
        }
    }
    
    然后好玩的事情发生了,Website层中的Ticket实例,在传递到WebServie层中时,信息丢失了,变成了null ,有图有真相:
    调用前的截图
     进入WebService层的截图:
    这个问题在编译期是发现不了的,只能运行后,才能知道,比较隐蔽。将DataTable换成DataSet类型后解决,以前只知道DataTable在做为参数类型在WebService中可能会遇到无法正常序列化的问题,但是今天遇到的问题还是第一回。

    后记:如果把WebService(.asmx),换成WCF(.svc)后,居然这个问题就不存在了!又给"强烈推荐用WCF替换WebService"找到了一个借口。

    以上问题的重现见示例源代码:https://files.cnblogs.com/yjmyzz/WS_DataTable.7z

    二、如果多个WebService中使用了同一种自定义类型(比如Model层中的Ticket),多个WebService中的NameSpace必须统一
    比如,在WebService层中又创建了一个MyService2,但是忘记了把NameSpace修改成跟MyService一样,如下图:
    那么在Website层中,引用这个新服务后,将出现二个Ticket的定义,尽管它们的结构完全相同,如下图:
    当然,这里提到的这二个问题不算bug,只是使用webservice中需要注意的问题。 
     
    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    第三方支付架构设计之:商户回调通知系统的悲观和乐观策略
    Layui 2.0.0 正式发布:潜心之作,开箱即用的前端UI框架(确实很多内容)
    简历上的哪些内容才是 HR 眼中的干货?
    windows Hook 消息分类
    MQTT协议学习及实践(Linux服务端,Android客户端的例子)
    MQTT是IBM开发的一个即时通讯协议,构建于TCP/IP协议上,是物联网IoT的订阅协议,借助消息推送功能,可以更好地实现远程控制
    Docker Machine
    Oracle执行计划
    Spire.XLS
    Docker
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/2025897.html
Copyright © 2011-2022 走看看