1 说清楚需求
2 SL中的数据交互的方法
3 RIA纵横谈
1说清楚需求
=======================
说段废话:暑假的时候花了大概一个月时间大概把MSDN中文文档翻了个底朝天。越发觉得对Silverlight了解不够,很多东西学的肤浅,越是觉得需要深度的学习也需要广度的学习。于是就拿Silverlight Business Applications 练手。主要是有那么一两本书写的不错,《ProBusiness Applications with Silverlight 4》和 《Silverlight in action 4》,于是就开始看,也顺便把以前就想写的 Silverlight CMS 开工了!
Welcome 2 My First OpenSource Project aqqcms! aqqcms.codeplex.com
=======================
上一篇中我记笔记式的写了一些关于Silverlight中的导航的东西。
但导航的数据是伪的,做网站的都知道需要从获取数据。因为RIA是在本地运行需要远程获取,
类似Ajax,所以我只说从Silverlight 程序外部的数据源获取数据的问题,不管他是如何与数据库交互的。
OK。。。。不习惯写这些技术无关的废话。。。
2 Silverlight中如何进行数据交互?
不太严谨的依靠传输介质分类
@1 WCF (或其他基于SOAP的)
@2 HTTP(TEXT)
@3 REST (JSON/XML...)
@4 socket (二进制)
#1 Silverlight中支持的WCF绑定
绑定名称 | 网络协议 | 编码 | 科教互相 | 备注 |
basicHttpBinding | HTTP/HTTPS | TEXT,MTOM | 可交互性 | 基于SOAP1.1 |
netTcpBinding | TCP | 二进制编码 | 不可交互 |
|
pollingDuplexHttpBinding | HTTP/?? | TEXT/?? | 可交互 | 不太清楚 |
customBinding自定义的绑定 |
|
|
|
|
#2再说WCF 中具体的
1WCF Data Service 简称 Data Service
2WCF RIA Service 简称 RIA Service
WCF RIA Service 是基于 WCF Data Service 的。
而在我们用的WCF Data Service ,已经包含了 RESTFul 的json 和 ATOM的东西。
#3如何对这两个进行选择?
RIA Service是在Data Service之上再进行扩展而成。设计被特别针对Silverlight 程序。
内置强大的功能(CURD,安全等)。 自然兼容非MS就不太好了。
Data Service 更适合广泛的被客户端(非MS)接收和操作,包括JS Ajax,silverlight,rss阅读器等等。
资源的格式是json,xml,atom等的RESTFUL的东西。
PS:RIA Service支持 SOAP,JSON,ODATA 三种格式格式的数据开放形式。更多等下会细说。
@3
主要是指web service ,以前的ASP.NET 的web service 和json 等。
当然其中的XML 有些重复, SOAP 就是 基于XML的。
http://www.w3school.com.cn/soap/soap_intro.asp
@4对于SOCKET
一并和netTcpBinding说一下,由于不是适用HTTP协议,所以领占端口,虽然他们的效率高,
但是容易被公司的防火墙墙了。更适宜于做局域网的应用。不太适用于更广泛的应用。
3 RIA Service纵横谈
纵向整合 :
左边数据库+WCF RIA SERVICE+右边Silverlight程序(逻辑层+表现层)
#1 开始创建一个Domain Service
第一个箭头必选是允许客户端进入。
第二个箭头是是否暴露ODATA数据
第三个箭头是生成关联的metadata。
ODATA?什么东东?
允许 使用ODATA 协议。ODATA 是一系列 ATOM 协议的扩展,他允许 序列化 提供 HTTP-BASED 数据服务。
类似于 REST ,但是还提供了CURD 等操作。作为ODATA 一个MS出的新的协议。他提供了更多的整合MS的产品,
比如 SharePoint and PowerPivot。
除了可以暴露OData格式外还有暴露 soap 和 json 的数据。具体做法是在webconfig中
在ODATA旁边添加:
<add name="Json" type="Microsoft.ServiceModel.DomainServices.Hosting.JsonEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<!-- 加即VS自动退出 <add name="SOAP" type="Microsoft.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
-->
<add name="OData" type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35" />
</endpoints>
</domainServices>
那么如何验证呢?如何访问?
通过类似如下地址:
http://localhost:2575/Services/RIAServiceLib-Web-Model-ChannelDS.svc/JSON/GetKF_Articles
可以返回JSON数据。前提是你的方法确实能得到值。
中间那段XXX.SVC 你可以通过 F12 进 ChannelDS 查看。
传说还可以通过
http://localhost:2575/Services/RIAServiceLib-Web-Model-ChannelDS.svc/OData
和
http://localhost:2575/Services/RIAServiceLib-Web-Model-ChannelDS.svc/OData/$metadata
查看。。。但是不懂为什么,我这里实验不行。对于SOAP的那段一添加VS就退出。。。
OK下面说第三个箭头产生了什么。
[MetadataTypeAttribute(typeof(KF_Channel.KF_ChannelMetadata))]
public partial class KF_Channel {
public int ChannelID { get; set; } 等等.....
}
这个到底是干啥用的?玩过ASP.NET 的 MVC 对于这些应该有些熟悉了。
恩,你懂的,不懂就去园子里找下。这个很强大。通过一大堆属性(Attribute),你可以做一大堆功能。
回忆一下以前做网站的对数据的通用需求。
1从数据库操作数据。
1.1增删查改列
1.2并发锁
1.3事务
1.4 对关联表的操作。
2数据验证。
其他.....
========================================
1.1
我们这里使用兼容 DLinq的AEF 自动生成了增删查改列。要是自己写也不太难。
这里RIA Service 使用了一个 函数名转换 的一个东西。服务器方法签名在客户端被转换(不会翻译)
Insert, Add, Create 开头的函数或者 标记了 [Insert()] 将被识别为
插入操作。
其他类似。。。[Invoke()] 等 取消使用 [igroe](查阅相关文档书籍可以知道更多)
1.2
这里我也没有很好的理解。给出相关的代码
[ConcurrencyCheck]
public DateTime ModifiedDate { get; set; }
-----------------------------------------------------
ProductPM originalProduct = ChangeSet.GetOriginal<ProductPM>(currentProduct);
ProductPM storedProduct = GetProduct(currentProduct.ProductID);
if (storedProduct.ModifiedDate != originalProduct.ModifiedDate) {
ChangeSetEntry entry = ChangeSet.ChangeSetEntries.Single(p => p.Entity == currentProduct);
List<string> conflicts = new List<string>();
conflicts.Add("ModifiedDate");
entry.ConflictMembers = conflicts;
entry.IsDeleteConflict = false;
entry.StoreEntity = storedProduct; }
else {
// Save ProductPM...
}
1.3 事务
public override bool Submit(ChangeSet changeSet) {bool result = false ;
TransactionOptions transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required, transactionOptions)) {result = base.Submit(changeSet);transaction.Complete();
}
return result; }
1.4关联表的操作
[Include]//包含外键
public EntityCollection<KF_Articles> KF_Articles { get; set; }
//操作
public KF_Channel GetFirst( int ChannelID){ return this .ObjectContext.KF_Channel.Include( "KF_Articles").Where(_ => _.ChannelID == ChannelID).FirstOrDefault(); }2 数据验证
[Required]
[StringLength(50)]
[RegularExpression(@"(?<user>[^@]+)@(?<host>.+)")]
1 Required 指定需要满足某些条件
2 Range 范围 --数字
3 StringLength 长度 ---字符串
4 RegularExpression 正则表达式
5 自定义的
===========================================================================
创建了一个dominservice 对这个东西大概都有了了解。那么在客户端怎么调用?
void GetArticles() {
channelDs = new ChannelDS();
var r1 = channelDs.GetFirstQuery(SectionID);
var r2 = channelDs.Load(r1);
r2.Completed += (S, E2) => {
var r3 = r2;
var articles = r3.Entities.FirstOrDefault().KF_Articles;
button1.Content = " 共有 " + articles.Count().ToString();
dataGrid1.ItemsSource = articles;
};
}
我们在dataGrid1对数据修改后,由于双向绑定。
我们只需要保存就OK了
void button1_Click(object sender, RoutedEventArgs e) {
channelDs.SubmitChanges();
}
整个流程还是比较顺畅,RIA Service 在我们一个简单操作后面真的做了好多事情。
比如说C/S代码共享,还有其他很多机制。。我虽然知道的不多也觉得很多了。。无从说起。。
简单的大家都知道。。。难的我也不知道。
有了这些基本的东西都能操作了。
这里没有谈安全那些下次再说了。打了好久字了。。。相当于自我总结和自我教学相长吧。