Web Services and C# Enums -摘自网络
Web Service Transparency
.NET support for web services is excellent in creating illusion of transparency. General process is quite straightforward:
- On the server we create a web service, decorating publicly visible methods with [WebMethod] attribute.
- On the client we add a web reference to the service, and proxy code is automatically generated for us by VIsual Studio. We can then call web service methods almost as if they were local methods.
All arguments and return values get magically XML-serialized, transmitted to the peer, and de-serialized to something very close to the original form. Ideally, this whole process should be automatic and seamless.
Imperfect Transparency of Enums
It turns out that enums are not as transparent as we'd like them to be. There are three sticky issues:
- If server-side code declares an enum and assigns specific numeric values to its members, these values will not be visible to the client.
- If server-side code declares a [Flags] enum with "compound" mask values (as in White = Red|Green|Blue), it is not properly reflected on the client side.
- If server or client transmits an "illegal" value which is outside of the scope of the enum, it causes an exception in XML de-serializer on the other side.
Numeric Values Are Not Preserved
If we have server-side definition like this:
enum StatusCode
{
Success = 200,
NotFound = 404,
Denied = 401
}
it is translated to client-side definition like this:
enum StatusCode
{
Success = 1,
NotFound = 2
Denied = 3
}
Corresponding WSDL looks as follows:
<s:simpleType name="StatusCode">
<s:restriction base="s:string">
<s:enumeration value="Success"/>
<s:enumeration value="NotFound"/>
<s:enumeration value="Denied"/>
</s:restriction>
</s:simpleType>
As one can see, there is no mension of numeric values in the WSDL. Proxy code generator on the client side does not have access to anything but WSDL. Therefore, it does not have a chance to get numeric values of enum members.
An important side effect of this phenomenon is that the relative order of enum members may not be preserved. For instance, in the example above, expression (StatusCode.NotFound > StatusCode.Denied) is true on the server, and false on the client.
Relationships Between [Flags] Masks May Be Broken
Server-side declaration:
[Flags]
enum UserRights
{
Read = 16,
Write = 256,
Delete = 1024,
AllAccess = Read | Write | Delete
}
Client-side declaration (some insignificant decorations removed):
[Flags]
enum UserRights
{
Read = 1,
Write = 2,
Delete = 4,
AllAccess = 8
}
Corresponding WSDL:
<s:simpleType name="UserRights">
<s:restriction base="s:string">
<s:enumeration value="Read"/>
<s:enumeration value="Write"/>
<s:enumeration value="Delete"/>
<s:enumeration value="AllAccess"/>
</s:restriction>
</s:simpleType>
Therefore, on the client UserRights.AllAccess lost its relationship to other user right values. On the server expression (UserRights.AllAccess & UserRights.Read) != 0 is true, while on the client it is false.
This can lead to disastrous consequences.
Out-Of-Range Values Cause Exception on Receiving End
The following server-side code:
enum Test
{
SomeValue = 1
}
[WebMethod]
public Test GetValue()
{
return (Test)512;
}
will cause "invalid XML document" exception on the client side when reading GetValue() response. This exception is related to how XML serializer works with enums. "Legal" values are transmitted as text. E.g. value of 1 would be transmitted as <Test>SomeValue</Test>. For [Flags] enums multiple text strings are transmitted to indicate concatenation of several masks, e.g. <UserRights>Read Write</UserRights>. However, out-of-range values are transmitted as stringified integers, e.g. <Test>512</Test>. These integers are not understood at the receiving end and cause exception.
Controlling Generated XML
It seems that .NET framework does not give you much leeway in controlling XML generated for enums. In particular, constructs like :
[XmlElement(typeof(int))]
enum MyEnum
{
...
}
or
[XmlElement(DataType="integer")]
enum MyEnum
{
...
}
do compile, but fail miserably at run-time.
One useful attribute is [XmlEnum], which allows to change names of enum members. As we mentioned before, enum members are transmitted as literal strings. Therefore, if one has flags enum like this:
[Flags]
enum MyMask
{
VeryVeryLongFlagNameWillBeTransmittedToClient,
AnotherQuiteLongFlagNameAlongTheFirstOne,
EtCeteraEtCetera
}
generated XML can get quite verbose. To prevent this, transmitted literal strings may be changed using [XmlEnum]:
[Flags]
enum MyMask
{
[XmlEnum("VeryLong")] VeryVeryLongFlagNameWillBeTransmittedToClient,
[XmlEnum("Another")] AnotherQuiteLongFlagNameAlongTheFirstOne,
[XmlEnum("EtCetera")] EtCeteraEtCetera
}
Conclusion
Extra caution must be excercised when transmitting enums over web service boundary. Behavior of XML serializer is not always straightforward for enums, and sometimes can cause serious incompatibilities between client and server. To ensure correct operation of software, one must keep in mind its limitations. If numeric values need to be preserved across the wire, they must be transferred as integers, not enums. In this case, however, client must have ad-hoc knowledge regarding what value means what.
.NET framework provides limited means of manipulating XML generated for enums. In particular, we were unable to find an attribute that would allow to automatically transmit enum as int.
Web Services and C# Enums -摘自网络的更多相关文章
- Web Services and C# Enums
Web Service Transparency .NET support for web services is excellent in creating illusion of transpar ...
- Google Maps API Web Services
原文:Google Maps API Web Services 摘自:https://developers.google.com/maps/documentation/webservices/ Goo ...
- RESTful Web Services初探
RESTful Web Services初探 作者:杜刚 近几年,RESTful Web Services渐渐开始流行,大量用于解决异构系统间的通信问题.很多网站和应用提供的API,都是基于RESTf ...
- (转) Web 建站技术中,HTML、HTML5、XHTML、CSS、SQL、JavaScript、PHP、ASP.NET、Web Services 是什么?
Web 建站技术中,HTML.HTML5.XHTML.CSS.SQL.JavaScript.PHP.ASP.NET.Web Services 是什么? 建站有很多技术,如 HTML.HTML5.XHT ...
- Web Services 中XML、SOAP和WSDL的一些必要知识
Web Services 是由xml来定义数据格式的,通过SOAP协议在各个系统平台中传输,那么接下来讨论下SOAP和WSDL的各自作用. SOAP和WSDL对Web Service.WCF进行深入了 ...
- 跟我一起学WCF(3)——利用Web Services开发分布式应用
一.引言 在前面文章中分别介绍了MSMQ和.NET Remoting技术,今天继续分享.NET 平台下另一种分布式技术——Web Services 二.Web Services 详细介绍 2.1 We ...
- 【转】RESTful Web Services初探
近几年,RESTful Web Services渐渐开始流行,大量用于解决异构系统间的通信问题.很多网站和应用提供的API,都是基于RESTful风格的Web Services,比较著名的包括Twit ...
- Android:控件WebView显示网页 -摘自网络
WebView可以使得网页轻松的内嵌到app里,还可以直接跟js相互调用. webview有两个方法:setWebChromeClient 和 setWebClient setWebClient:主要 ...
- 基于Spring设计并实现RESTful Web Services(转)
基于Spring设计并实现RESTful Web Services 在本教程中,你将会使用Spring来创建一个具有生产力的RESTful网络服务. 为什么用RESTful网络服务? 从和Amazon ...
随机推荐
- [Linux/Ubuntu] vi/vim 使用方法讲解(转载)
转自:http://www.cnblogs.com/emanlee/archive/2011/11/10/2243930.html vi/vim 基本使用方法 vi编辑器是所有Unix及Linux系统 ...
- OAuth在WebApi中的使用,前后台分离的调用方式
前段时间由于公司架构服务层向WebApi转换,就研究了OAuth在WebApi中的使用,这中间遇到了很多坑,在此记录一下OAuth的正确使用方式. 1. OAuth是做什么的? 在网上浏览时,大家都 ...
- ASP.NET MVC Spring.NET 整合
请注明转载地址:http://www.cnblogs.com/arhat 在整合这三个技术之前,首先得说明一下整合的步骤,俗话说汗要一口一口吃,事要一件一件做.同理这个三个技术也是.那么在整合之前,需 ...
- xml & 符号表示方法,xml转义字符
HTML,xml 中<, >,&等有特别含义,(前两个字符用于链接签,&用于转义),不能直接使用.使用这三个字符时,应使用他们的转义序列,如下所示: & 或 &am ...
- 1006: [HNOI2008]神奇的国度
图上的最小的染色方案: 学习了陈丹绮的论文: MCS算法 #include<cstdio> #define maxn 10005 #define maxm 2000005 using na ...
- 安装,卸载或重装Vmware Workstation时失败的官方解决方案
最近VMware Workstation又放出更新,遂更新之.安装时提示先卸载旧版本.控制面板和其他软件管理器都不能正常卸载,提示" The MSI '' failed",索性直接 ...
- node.js + gulp用JENKINS作CI编译
这里还是有点坑,要注意. 安装NODE.JS不说,GULP绿色化也不说. 但要让JENKINS识别环境变量. /etc/profile.... export NODE_HOME=/usr/local/ ...
- DHTMLX 前端框架 建立你的一个应用程序 教程(五)--添加一个表格Grid
表格例子 样本如下: 我们这篇介绍的是dhtmlxGrid 组件. 它支持4种数据格式:XML, JSON, CSV, JSArray. 添加表格到布局的单元格中去: 1.使用attachGrid( ...
- ANDROID_MARS学习笔记_S01原始版_013_广播机制二
一.代码1.xml(1)main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayo ...
- 坚持Delphi的厂商与产品
能记一个算一个吧... 招商银行的企业网银是用Delphi开发的,听说招商有不少软件都是用Delphi开发的. 广州酷狗音乐招Delphi开发 对程序员来说,Delphi写的比较有名的软件莫过于Dev ...