本文主要讲述如何在.Net CF中发送自定义的SOAP消息来调用WebService。可能大家对如何实现自定义的SOAP有一定的了解。但是在.Net CF中,有一些地方值得大家注意。

为何要实现自定义的SOAP呢?以及SOAP的好处在于?
一般调用WebService时,我们可以发送Http信息,也可以发送SOAP1.1/1.2信息。如果我们希望在调用某些方法时只针对于特定的用户时。那通常做法,在调用函数中加入一些判断参数,然后来判断是否是被授权的用户。使用自定义SOAP消息不但可以减少传入参数,可以在该方法调用前,就过滤掉,通知客户端,没有足够的权限。通常,我们可以将这些信息放到SOAP的header部分,传递到服务器端时,解析时,可以验证header部分的信息是否符合。

概念讲述那么多。通过代码来说明吧。

首先定义一个WebService。

 1[WebService(Namespace = "http://tempuri.org/")]
 2[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
 3public class Service : System.Web.Services.WebService
 4{
 5    public MySoapHeader myHeader;
 6
 7    public Service () {
 8    }
 9
10    [WebMethod]
11    public string HelloWorld() {
12        return "Hello World";
13    }
14
15    [WebMethod, SoapHeader("myHeader")]
16    public string GetInfo(string userName)
17    {
18        return string.Format("Hello, {0}", userName);
19    }
20}

该Service中声明了2个方法,其中GetInfo就是验证SOAP的方法。在该Service中提供了一个MySoapHeader,这个是自定义的SOAP头,用于定义一些验证信息。为何这样定义,等下文中叙述。

实现完WebService后,该实现扩展的SOAP信息了。

 1        public override void ProcessMessage(SoapMessage message)
 2        {
 3            switch (message.Stage)
 4            {
 5                case SoapMessageStage.AfterDeserialize:
 6                    break;
 7                case SoapMessageStage.AfterSerialize:
 8                    break;
 9                case SoapMessageStage.BeforeDeserialize:
10                    Check(message);
11                    break;
12                case SoapMessageStage.BeforeSerialize:
13                    break;
14                default:
15                    break;
16            }
17        }
18
19        private void Check(SoapMessage message)
20        {
21            if (message is SoapServerMessage)
22            {
23                MemoryStream ms = new MemoryStream();
24                System.IO.StreamWriter sw = new StreamWriter(ms);
25                StreamReader sr = new StreamReader(message.Stream);
26                char[] buffer = new char[(int)message.Stream.Length];
27                sr.Read(buffer, 0, (int)message.Stream.Length);
28
29                sw.Write(buffer, 0, buffer.Length);
30                sw.Flush();
31                message.Stream.Position = 0;
32                string sb = System.Text.Encoding.ASCII.GetString(ms.ToArray());
33
34                Debug.WriteLine(sb);
35
36                XDocument doc = XDocument.Parse(sb);
37                XNamespace name = "urn:com-appleseeker";
38                XNamespace soapheader = "http://schemas.xmlsoap.org/soap/envelope/";
39                MySoapHeader header = new MySoapHeader();
40
41                if (doc.Descendants(soapheader + "Header").Descendants().Elements(name + "userid").First() == null)
42                {
43                    throw new Exception("");
44                }
45                header.userid = doc.Descendants(soapheader + "Header").Descendants().Elements(name + "userid").First().Value;
46
47                string[] temp = message.Action.ToString().Split('/');
48                string methodName = temp[temp.Length - 1];
49
50                if (header.userid == "0345")
51                {
52                }
53                else
54                {
55                    throw new Exception("No Access");
56                }
57            }
58        }

这是服务器端的扩展的SOAP处理,必须重写一些方法,其中ProcessMessage中,在做BeforeDeserialize这一步操作时,解析接受到的SOAP消息。通常SOAP会有4部分操作。可以参考代码说列。
在验证消息时,从SOAP消息中取到内容,就是流中的内容,该流只读,可以通过复制到内存中来取得。当然,取道流的内容后,肯定是一个XML格式,通过对XML格式的文件解析方式,取到SOAP头部说含内容。这里我只验证userid=0345时,才能调用。否则则返回一个异常。

客户端部份相对简单。

 1        public override void ProcessMessage(SoapMessage message)
 2        {
 3            switch (message.Stage)
 4            {
 5                case SoapMessageStage.AfterDeserialize:
 6                    break;
 7                case SoapMessageStage.AfterSerialize:
 8                    break;
 9                case SoapMessageStage.BeforeDeserialize:
10                    break;
11                case SoapMessageStage.BeforeSerialize:
12                    message.Headers.Add(new MySoapHeader() { userid = "0345" });
13                    break;
14                default:
15                    break;
16            }
17        }

只是在ProcessMessage的BeforeSerialize前加入头文件的内容。

自定义的SOAPHeader

1    [XmlRoot("MyHeader", Namespace = "urn:com-appleseeker")]
2    public class MySoapHeader: SoapHeader
3    {
4        public string userid;
5        public string username;
6        public string department;
7    }

Namespace约定了在header部分的tag,通过定义,我们可以用它来解析。

我们做完了代码上的大部分活,接下来就是配置了,如何让WebService在接收到SOAP消息后,自动来解析呢,只需要在web.config中加入下面配置即可

1<webServices>
2    <soapExtensionTypes>
3        <add type="ExtensionLib.MyServerSoapExtension, ExtensionLib"/>
4    </soapExtensionTypes>
5</webServices>

在add type中,第一个是自定义的扩展SOAP类名,需加命名空间,后面一个是程序集名

服务器端配置完成了。接下来就是客户端部分。
这里介绍下非Mobile程序如何使用,我创建一个控制台程序简单说明下,在客户端部分,有2种方式使用扩展SOAP。
1.可以像服务器端那样,自定义一个SOAP类,然后加入相应信息,再在app.config中加入相应配置即可。
2.在服务器的WebService的方法的Attribute中加入SoapHeader参数,表明可以使用的自定义SOAP头文件内容。
并在WebService中提供一个Public的自定义的头属性。在客户端只需要在调用时对自定义的头属性赋值即可。

在WM中,只能使用第2种方法来实现,不支持第1种方式。

1private void menuItem1_Click(object sender, EventArgs e)
2{
3     localhost.Service service = new SmartDeviceProject1.localhost.Service();
4     service.Url = service.Url.Replace("localhost", "192.168.0.157");
5     localhost.MySoapHeader myHeader = new SmartDeviceProject1.localhost.MySoapHeader();
6     myHeader.userid = "0345";
7     service.MyHeader = myHeader;
8     MessageBox.Show(service.GetInfo("Gordon"));
9}

以上在WM中就能使用自定义的SOAP消息了。各位在实际应用中如果遇到什么问题,可以参考我下面提供的代码。我在做Demo的过程中也或多或少遇到一些问题,大家可以相互探讨交流。

这篇文章的主旨在于,如何在WebService中验证用户信息。
在下一篇文章中,我可能会讲述如何在WCF中实现用户的验证。同样会基于.Net CF,希望大家能够留意。

很长时间我的Blog没有更新了,一方面个人确实比较忙,今年个人的私事比较多。所以,对Blog的更新就耽搁了。
我一致要求自己写出高质量的文章,给大家一些在开发上的经验,希望有更多的人来和我一起分享、一起交流、一起在WM这个平台上有所成就。谢谢大家对我的支持。非常感谢~

代码下载:SOAPExtensionDemo.rar

Author:AppleSeeker
Date:2008-06-28

转载于:https://www.cnblogs.com/appleseeker/archive/2008/06/28/1231761.html

.Net Compact Framework 高级篇(2)-- 扩展SOAP应用相关推荐

  1. .Net Compact Framework 基础篇(10)--多语言程序的定制

    很多时候,一款软件不仅仅只是一套语言环境,如果针对不同国家的人,各写一套软件来发布,明显不现实. 如何实现多语言呢?我相信看完这篇文章后,一定会对你有所帮助. 全球化过程力图确保您的应用程序可以处理来 ...

  2. c#扩展方法奇思妙用高级篇七:“树”通用遍历器

    我的上一篇随笔<c#扩展方法奇思妙用高级篇六:WinForm 控件选择器>中给出了一个WinForm的选择器,其实质就是一个"树"的遍历器,但这个遍历局限于WinFor ...

  3. CCNP-第二篇-SLA扩展+EIGRP高级版(上)

    CCNP-第二篇-SLA扩展+EIGRP高级版 还是这个环境的SLA 我们想一个问题哈,如果会有抖动呢? 比如左边是主线路,右边是备用的,那如果左边的时候只是偶尔断了一个包,然后他就跳到备用了,然后b ...

  4. 《Unity Shader入门精要》笔记:高级篇(3)以及扩展

    本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载. 本篇博客会补充一些扩展内容(例如其他博客链接). 本篇博客还会提供一些边读边做的效果截图.文章内所有数学 ...

  5. Microsoft .NET Compact Framework 开发常见问题解答

    这个 FAQ 有部分是通过编辑公共 .NET Compact Framework 新闻组 (microsoft.public.dotnet.framework.compactframework) 贴出 ...

  6. Microsoft .NET Compact Framework 开发常见问题解答 - 专注.NET技术及其相关应用开发! - 博客园...

    Microsoft .NET Compact Framework 开发常见问题解答 发布日期: 3/30/2005 | 更新日期: 3/30/2005 Microsoft .NET Compact F ...

  7. 【建议收藏】2020年中高级Android大厂面试秘籍,为你保驾护航金三银四,直通大厂(Android高级篇上)...

    前言 成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~. A awesome android expert interview questions a ...

  8. C#【高级篇】 C# 多线程

    C#学习汇总 - 总目录 C#[高级篇] C# 多线程 前言 一.线程生命周期 二.主线程 三.创建线程 特别说明: 四.管理线程[Thread.Sleep(1000) 线程暂停1s] 五.销毁线程[ ...

  9. .NET Compact Framework下SQL CE的使用

    在Wince和Windows Mobile下最常用的数据库为SQL CE,SQL CE也曾经叫做SQL Server for Windows CE和SQL Server Mobile Edition, ...

  10. .NET Compact Framework下的蓝牙开发

    蓝牙的应用十分广泛,基于Bluetooth的通信程序开发主要有以下几个步骤: 服务端 * 设置本设备为可发现. * 公开服务给其他Bluetooth设备访问. * 接受其他Bluetooth设备的链接 ...

最新文章

  1. 一文搞懂RNN(循环神经网络)
  2. ios系统web(微信公众号)开发遇到的问题及解决方案
  3. 聊聊高并发系统之队列术
  4. BitNami Redmine Stack
  5. Linux 的发行版 Ubuntu 的发展简史
  6. our happy ending(状压dp)
  7. 第7期 Datawhale 组队学习计划
  8. Tableau可视化学习笔记:day13-14
  9. 通过bocker把项目部署到容器后,也启动了镜像,但是浏览器报错网址连接不安全,建立安全连接失败,SSL接收到了一个超出最大准许长度的记录
  10. Sql Server之旅——第十三站 对锁的初步认识
  11. 七款非常好用的电脑数据恢复软件推荐
  12. 计算机基础应用软件,全国一级计算机考试软件
  13. Xamarin自学教程(Android)之一
  14. Python获取实时的时间
  15. F28335的SCI模块
  16. 前端开发面试问题及答案整理
  17. 刘文智《产品经理深入浅出》培训课程笔记
  18. iOS端如何实现带UI截屏分享
  19. php:获取字符串的长度
  20. 无力吐槽的废酱的几个问题

热门文章

  1. Spring 双层事务,我抛出的异常去哪了?
  2. Linux!为何他一人就写出这么强的系统,中国却做不出来?
  3. 系统架构设计理论与原则、负载均衡及高可用系统设计速记
  4. redis cluster节点挂掉后_深入浅出—Redis集群的相关详解
  5. mysql基础之数据库备份和恢复实操
  6. Linux服务之DNS服务篇
  7. 电子书下载:MySQL5权威指南(第3版)
  8. 投入工作与生活幸福,并非简单对立
  9. jquery知识点总结(转载)
  10. Mac Xdebug安装时遇到了Zend Engine API 不一致的问题