做了一个简单的SilverLight WebPart,但第一次做起来并不轻松,除了各种各样的Issue,譬如OnRequestSucceeded没有被触发是因为没有注册OnRequestFailed而执行Fail的原因,但是在OnRequestFailed里面的代码(简单的弹出消息)失败的原因应该与线程有关,总结了各种经验:
第一,当我们使用context.ExecuteQueryAsync(new ClientRequestSucceededEventHandler(OnRequestSucceeded), new ClientRequestFailedEventHandler(OnRequestFailed));来注册事件的时候,不要在OnRequestSucceeded或者OnRequestFailed事件里直接写代码,这个会报线程冲突的错误。应该使用代理。
Dispatcher.BeginInvoke(delegate()
{
MessageBox.Show("inside OnRequestSucceeded Method" + args.StackTrace.ToString() + args.ErrorDetails);
});
第二个,context的参数指定一定要使用ApplicationContext.Current.Url,否则在运行的时候会报Security的错误(太搞了,我直接使用ClientContext(“http://localhost”)一直报这个错误,SharePoint的设计也太次了,难道是因为不确认是否在本站运行?有些网站里面提到要部署ClientAccessPolicy.xml在IIS根站点目录下,至少对SilverLight WebPart是没有意义的。)
ClientContext context = new ClientContext(ApplicationContext.Current.Url);
第三个,总结学到的SilverLight里两种异步执行的方式
1)clientContext.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed),注册成功执行后的时间以及失败后的事件
2)通过多线程调用System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(ThreadCallback), context);
一个小技巧点:
Silverlight重新部署后不需要重启IIS或者重置Application Pool,删除IE的客户端缓存就可以。
源码:
001 | public partial class MainPage : UserControl |
011 | public DateTime DueDate |
017 | public string Description |
023 | private ListItemCollection _projects; |
027 | InitializeComponent(); |
028 | ClientContext context = new ClientContext(ApplicationContext.Current.Url); |
033 | context.Load(context.Web); |
035 | List Projects = context.Web.Lists.GetByTitle( "Tasks" ); |
036 | context.Load(Projects); |
038 | CamlQuery query = new Microsoft.SharePoint.Client.CamlQuery(); |
039 | string camlQueryXml = "<View><Query><Where><Gt>" + |
040 | "<FieldRef Name='DueDate' />" + |
041 | "<Value Type='DateTime'>2008-01-1T00:00:00Z</Value>" + |
042 | "</Gt></Where></Query><ViewFields>" + |
043 | "<FieldRef Name=/"Title/" /><FieldRef Name=/"Body/" />" + |
044 | "<FieldRef Name=/"DueDate/" />" + |
045 | "</ViewFields></View>" ; |
047 | query.ViewXml = camlQueryXml; |
048 | _projects = Projects.GetItems(query); |
049 | context.Load(_projects); |
053 | context.ExecuteQueryAsync( new ClientRequestSucceededEventHandler(OnRequestSucceeded), new ClientRequestFailedEventHandler(OnRequestFailed)); |
064 | private void OnRequestFailed(Object sender, ClientRequestFailedEventArgs args) |
068 | this .Dispatcher.BeginInvoke( delegate () |
070 | MessageBox.Show( "inside OnRequestSucceeded Method" + args.StackTrace.ToString() + args.ErrorDetails); |
076 | private void OnRequestSucceeded(Object sender, ClientRequestSucceededEventArgs args) |
080 | this .Dispatcher.BeginInvoke(BindData); |
083 | private void Failed(ClientRequestFailedEventArgs args) |
085 | MessageBox.Show( "inside OnRequestFailed Method" + args); |
088 | private void BindData() |
090 | List<Project> projects = new List<Project>(); |
091 | foreach (ListItem li in _projects) |
093 | projects.Add( new Project() |
095 | Title = li[ "Title" ].ToString(), |
096 | DueDate = Convert.ToDateTime(li[ "DueDate" ].ToString()), |
097 | Description = li[ "Body" ].ToString() |
100 | dataGrid1.ItemsSource = projects; |