月度优秀员工推荐知识文档共享 技术开发部TRD
石林:WCF开发技术及VS2008新特性
第一章WCF开发技术
1、 概述
在嘉定(微软合作)项目中经常使用或推荐使用WCF技术来进行数据通讯及
分布式应用,WCF整合了MS历来最优秀的分布式系统开发技术,取其精华,弃其糟粕,是分布式应用程开发技术的集大成者,相比之前流行的Web Service,WCF可能会引领分布式开发技术的一个新潮流。
2、 WCF的概念及意义
· WCF是什么:WCF(原代号为Indigo)是一个用于创建和运行分布式系统的技术集合,使用它能创建安全的(Secure)、可靠的(Reliable)、跨平台的(transacted messaging along with interoperability)的分布式解决
方案
气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载
。它的面向服务的编程模型整合了.Net平台下以往全部的分布式开发技术,例如.Net Remoting,Asp.Net Xml Web Service,MSMQ,WSE,和Enterprise Service等,它可以支持跨应用程序域(AppDomain),进程(Process),网络(NetWork)的进行数据通讯,而且能寄宿在诸如IIS,Windows Service,Console,Windows Application等多种宿主(Host)中。它适用于Vista,Xp和Windows 2003等操作系统。
· WCF能做什么:在win32中,应用程序是运行在进程(Process)的线程(Thread)中的,.Net平台出现之后,出现了AppDomain,其实就相当于在进程和线程之间又有了一层包装,类似于子进程的概念,在一个进程(或者应用程序域)中的对象能进行直接的访问和控制,但超出这个范围,便不能进行直接的访问和控制了,所以说进程(或者应用程序域)有一定的隔离作用,如果是分布在不同网络,不同操作系统上的不同进程,他们进行通讯的难度就更大,而分布式应用程序要求的就是将原本被隔离的作用域通过一定的契约联系起来,从而达成多个系统的沟通协作。当然能实现这种目的的方式远不止WCF一个,比如在win32时代,经常使用映射内存文件来实现进程之间的互操作问题,还有在windows程序中,用windows消息wm也能实现不同进程之间的通讯问题,但这些都有局限性,因为他们不能很好的解决跨平台,跨网络问题,而WCF可以。
· WCF的架构图:
· WCF与其他分布式技术功能对比
Xml Web Service
.Net Remoting
Enterprice Service
WSE
MSMQ
WCF
跨平台
√
√
.Net与.Net通讯
√
√
分布式事务
√
√
安全可靠性
√
√
消息队列
√
√
从表格中我们可以看出,WCF似乎等于前面几项技术之和,但事实并非如此,它既整合了原来的多项技术,而且拥有着自己得天独厚的优点,如下:1.统一性(Integration)2.互操作性 3.安全可靠(Secure and Reliable)4.兼容性
3、 WCF的使用及注意事项
· WCF的使用:
WCF不仅仅在功能上集成了以往的分布式开发技术,而且在编程模型中充分
吸取原来技术的优点,如xml web service的声明性编程(declareable),和.net remoting中的配置(configuration)和wse中的安全策略声明性配置
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
,这样wcf虽然功能强大,而且学习简单,便于推广。在vs2008中还集成了WCF Test Client,开发服务的时候,甚至不需要再开发测试客户端就能用WCF Test Client来进行调用,简单之极。我在使用WCF过程中感觉有几个WCF的概念还是蛮重要的。
a. 地址:WCF的每个服务都需要有一个地址的,而且只能有一个,WCF支持多种传输:1.HTTP 2.TCP 3.对等网 4.内部进程通信 5.MSMQ
通常的地址包括两个方面:1.服务位置、2.传输的
协议
离婚协议模板下载合伙人协议 下载渠道分销协议免费下载敬业协议下载授课协议下载
。如基于tcp的地址:net.tcp://localhost:8800/Henllyee.Service,在这里net.tcp就是传输的协议,而后面就是告诉服务的位置。
b. 契约:WCF所有的服务都是公开为契约,当你使用这个服务是就比约遵循一定的契约。契约的表示就想webservice里的表示,也是通过属性标签来标识的。WCF定义了四种契约类型:1.服务契约(Service Contract):定义客户端能够执行的服务操作。2.数据契约(Data Contract):定义于服务交互的数据类型。3.错误契约(Fault Contract):定义抛出的错误。4.消息契约(Message Contract):定义直接与服务交互的消息。服务契约是要广泛使用的,定义个服务契约是很简单的,只是在一些服务接口上进行标识即可。
c. 例子:(服务端)
namespace JiaDing.Application.TaskCenter.WCFService.WCFRssService
{
// NOTE: If you change the interface name "IOpenRssService" here, you must also update the reference to "IOpenRssService" in App.config.
[ServiceContract(Namespace = "http://JiaDing.Application.TaskCenter.WCFService.WCFRssService")]
[ServiceKnownType(typeof(TaskEntity))]
public interface IOpenRssService
{
[OperationContract]
IList
GetMyTasks(string userCode,DateTime time);
[OperationContract]
IList GetMyTasksByTaskCategoryCode(string userCode, string TaskCategoryCode, DateTime time);
}
}
namespace JiaDing.Application.TaskCenter.Model.Entity
{
[DataContract]
[Table(Name = "dbo.TC_Task")]
public class TaskEntity
{
///
/// 任务标识
///
[DataMember]
[Column(DbType = "VarChar(50) NOT NULL", CanBeNull = false, IsPrimaryKey = true)]
public string TaskId
{
get;
set;
}
///
/// 任务标题
///
[DataMember]
[Column(DbType = "VarChar(500)")]
public string TaskTitle
{
get;
set;
}
配置文件:
该服务通过寄宿在WindowsService上供外部访问:
/// 服务开始
///
public void Start()
{
try
{ WriteLog("开始启动RssService服务");
if (serviceHost != null)
serviceHost.Close();
serviceHost = new ServiceHost(typeof(OpenRssService));
serviceHost.Open();
WriteLog("已启动RssService服务");
}
catch (Exception ex)
{
WriteLog(ex.Message);
}
}
WCF(客户端调用)
namespace ServiceTest
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
OpenRssServiceClient client = new OpenRssServiceClient();
IList list = client.GetMyTasksByTaskCategoryCode("xwang", "CS12055", DateTime.Parse("1999-10-15 10:31:49"));
}
}
}
配置文件:
· WCF注意事项
a.这里我们需要注意的是WCF客户端配置文件中 节点中 maxReceivedMessageSize=“655360”属性,这个属性定义了从服务端传递过来的数据大小,默认是6k,如果我们要接收的数据量很大的话,需要更改这个数值。
b.跨网域的问题:所谓跨网域就是包含Port号不同。如::http://localhost/ 存取 http://localhost:1619/ 如果没有加入clientaccesspolicy.xml 时会出现跨网域被拒错误讯息。 一个权限最宽松的 Silverlight 2.0 clientaccesspolicy.xml 如下,请根据需要调整权限
c.随着客户端越来越多,造成了客户端运行异常,服务变慢。这种现象主要是因为:WCF为了改善性能,是有限流(Throttling)
措施
《全国民用建筑工程设计技术措施》规划•建筑•景观全国民用建筑工程设计技术措施》规划•建筑•景观软件质量保证措施下载工地伤害及预防措施下载关于贯彻落实的具体措施
的。主要包括三种 maxConcurrentCalls :最大并发数,默认为16 maxConcurrentSessions :最大的会话数,主要针对于PerSession的情况,默认为10 maxConcurrentInstances:最大实例数,默认为Int.MaxValue默认的设置比较保守,最大并发数仅为16,非常容易造成排队或者超时现象。修改或者添加限流也非常简单,只需要在服务的配置中修改或者增加ServiceBehavior中的
d. WCF的调试:当你的服务端和客户端开发在同一个解决方案里,最简单的可以将服务寄宿在Console上进行调试。
e. 选择正确的Binding:Binding是可以自定义实现的,可WCF框架已经为我们实现了足够多的Binding,供我们来选择,如下表所示:
下面的图给出了我们选择Binding的方式
第二章VS2008新特性
· 概述
VS2008和VS2005都具有相同的架构和编辑界面,同时也包括赋予一个新的品牌:VS2008的外衣;VS2008是一个强大Vista的客户端,具有良好的外观
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
和很多的新的可用的功能,当然也包括增强了多线程调试功能;VS2008有一个新的简单而强大的功能: multitargeting –-一种针对不同的。Net框架版本(2.0,3.0和3.5)创建项目的能力。这就意味着即使vs2008可以与vs2005同时安装,你也不再需要vs2005了,因为vs2008提供的功能更强大。
· 新特性之简单介绍:
a. 把Ajax extension集成到了Visual studio2008中;
b. JS 智能感知;
如在编辑页面加入如下语句,则编辑器就支持JQuery智能提示
<%if(false)
{ %> <%} %>
c. LINQ(Language Integrated Query);
体会:在操作Objects,Sql,Xml,Entities,DateSets时,使用Linq是非常方便的;部分代码如下:
string[] array = {"wis","dd","aa","ad" };
IEnumerable res = from s in array where s.StartsWith("a") orderby s select s;
foreach(string r in res)
{
Console.WriteLine(r);
}
d. Var 隐式类型;
注:隐式本地变量的声明必须同时包含一个初始化器。
e. 自动的属性,可以在编译的时候,生成private data field;
f. 扩展方法:可以为编译好的程序集动态的添加方法;
体会:必须是static类+static方法;只有且有第一个参数必须用this。
以下是一个Json对象转换的类:
namespace LSHI.JsonHelper
{
public static class OperatorJson
{
public static string ToJSON(this object obj)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
return Encoding.Default.GetString(ms.ToArray());
}
}
public static T ParseJSON(this string str)
{
T obj = Activator.CreateInstance();
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(str)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
return (T)serializer.ReadObject(ms);
}
}
}
}
使用如下:
IList listUser = new List
{
new User{UserID="1001",UserName="shilin1",UserAge=10},
new User{UserID="1002",UserName="shilin2",UserAge=20},
new User{UserID="1003",UserName="shilin3",UserAge=30}
};
string str = listUser.ToJSON();
IList obj = str.ParseJSON>();
g. 扩展接口;
项目中有些对象经常需要重置部分或全部属性到初始状态,想给这些类全部都加上个Reset()方法,又显得太冗余,如果利用扩展接口就显得很容易。代码如下:
先定义一个接口:
public interface IResetable { }
扩展这个接口:
public static class ResetableImpl
{
public static void Reset(this IResetable obj)
{
var ctor = obj.GetType().GetConstructor(BindingFlags.Instance | BindingFlags.Public,
null, new Type[0], null);
ctor.Invoke(obj, null);
}
}
定义一个使用该接口的类:
class Mail : IResetable
{ public string Subject { get; set; }
public string Body { get; set; }
public MailAddress From { get; set; }
public MailAddress To { get; set; }
public Mail()
{ this.Subject = "";
this.Body = "";
this.From = null;
this.To = null;
}
}
具体使用就很简单:
public class Program
{ static void Main(string[] args)
{
Mail mail = new Mail();
mail.From = new MailAddress("wuchangx@qq.com");
mail.To = new MailAddress("friend@anywhere.com");
mail.Subject = "hi friend";
mail.Body = "mail content.";
Console.WriteLine("1\nFrom={0},To={1},\nSubject={2},Body={3}",
mail.From, mail.To, mail.Subject, mail.Body);
mail.Reset();
Console.WriteLine("2\nFrom={0},To={1},\nSubject={2},Body={3}",
mail.From, mail.To, mail.Subject, mail.Body);
Console.ReadKey();
}
}
h. 局部方法 局部类型;
i. 初始化;
IList listUser = new List
{
new User{UserID="1001",UserName="shilin1",UserAge=10},
new User{UserID="1002",UserName="shilin2",UserAge=20},
new User{UserID="1003",UserName="shilin3",UserAge=30}
};
j. 匿名类型;
var q = DataSession.Objects.Where
(c => c.ReceiverName == receiverName && c.ProcessType == 0 && c.Deleted == 0
&& c.Archived == 0 && c.IsDraft == 0 && c.ReceiverArchived == 0).OrderByDescending(c => c.ReceiveDate);
k. Lambda表达式;
public IList SelectInformationView(string receiverName)
{
var q = DataSession.Objects.Where
(c => c.ReceiverName == receiverName && c.ProcessType == 0 && c.Deleted == 0
&& c.Archived == 0 && c.IsDraft == 0 && c.ReceiverArchived == 0).OrderByDescending(c => c.ReceiveDate);
IList list = q.Take(topCount).ToList();
if (0 < list.Count)
return list;
return null;
}
定义接收消息最大值,注意在获取大数量数据时,需要改该值。默认:6k;
这个地址就是供客户端访问的地址。
只有标识了DataMember的字段和属性,才能被远程调用解析。
通过DataContract,定义远程调用解析的类。
通过OperationContract,定义远程调用的方法。注意的是WCF定义3种数据交换模式:One-Way Calls,Request/Reply,Duplex,默认Request/Reply:客户请求服务响应模式
通过ServiceKnownType,将TaskEntity这一实体数据类型开放给远程,以供调用解析。
这是ServiceContract,通过这步将接口及其实现类开放给远程
©上海互联网软件有限公司
第1页 共12页