Mar 25, 2010

Host WCF Services in SharePoint 2010

As a completion of my post, how to Host WCF Data Service in SharePoint 2010  I am here to show how to host WCF services and WCF RESTful services inside SharePonit 2010.

Create a empty SharePoint project and add an ISAPI mapped folder

Add "new item" and select "WCF Service"
when creating WCF service inside a SharePoint Project, you won't get .svc file, only one interface and one class file:
  • Add this attribute to implemntation class:
    • [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
  • specify Namespace in the interface, otherwise your proxy script class will get a namespace like org.ui
    • [ServiceContract(Namespace="")]
Create a service.svc file under ISAPI folder
  • As it is hosted in SharePoint, we have to use non-configuation approach (Factory) to define endpoint (see here for details). In other word, no web.config modification, in stead use Factory in .svc file as follows:
  • <%@ServiceHost Language="C#" Debug="true" Service="SharePointHostWCF.WCFService, SharePointHostWCF, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d82e2e229c90dd3e" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"% >
  • WebScriptServiceHostFactory will define a endpoint callable from Javascript.
create a sharepoint ajax enabled application page to test your WCF service
  • see my other post on how to make ajax enabled sharepoint page;
  • use asp:servicereference to load a service proxy class in runtime;
  • in javascript,you should be able to get a IWCFService object and use it to call service methods;
  • you can't call it from another iis web application, since it is treated as a cross site scripting (CSS);

What if you want to implement a RESTful Service?
  • add this attribute to interface method:
    • [WebGet(UriTemplate = "Hello", ResponseFormat = WebMessageFormat.Xml)]
  • change Factory in service.svc to WebServiceHostFactory. otherwise you get the following errors:
  •   Endpoints using 'UriTemplate' cannot be used with 'System.ServiceModel.Description.WebScriptEnablingBehavior'.
  • you can now test service from browser in a RESTful way;
  • if you choose Json for ResponseFormat instead, browser won;t be able to display, instead asking you to download. You should test it in Fiddler;
  • still want to consume this RESTful service from script, see my other post for detail;

Mar 24, 2010

Enable WCF services consumable for Ajax JavaScript

In the previous post, I show how to call ajax-enabled WCF from Javascript, and how to consume WCF RESTful service from Ajax JavaScript. What if you already created a WCF service using WCF Service template, and want it to be consumed in a JavaScript? It turns out the only change is in web.config:

When you create a WCF service in Visual Studio, its endpoint in web.config is defined as:

<endpoint address="" binding="wsHttpBinding" contract="AjaxWcFService.IWCFSoapService" >
<identity > <dns value="localhost" > </identity >
</endpoint >

replace it with the followings:

< endpoint address="" binding="webHttpBinding"
behaviorConfiguration="ScriptFriendly"
contract="AjaxWcFService.IWCFSoapService" >
< /endpoint >

and define endpoint behavior as follows:

<behavior name="ScriptFriendly" >
<enableWebScript / >
</behavior >

This WCF service now becomes ajax-enabled.

Call Ajax-enabled WCF Services from Ajax JavaScript

After Creating an Ajax-enabled WCF service in Visual Studio 2010, the following endpoint behavior is specified for this service:

<behavior name="AjaxWcFService.AjaxWCFSVCAspNetAjaxBehavior"><enableWebScript/>
</behavior >

which will allow ajax library (see here to register ajax library)  to inject a proxy at runtime for script client to use and call this service once it is referred in an ASP:Service:
<Services > <asp:ServiceReference Path="~/AjaxWCFSVC.svc" / >
</Services >



So the script can just make a call like the follwoings.
                  var svc = new AjaxWCFSVC();
                  svc.DoWork(onSuccess, onFail, null)

Related Post: Call WCF RESTful service from Ajax JavaScript
                     Call WCF service from Ajax JavaScript

Mar 23, 2010

Host WCF Data Service in SharePoint 2010

Creating a WCF data service based on Entity Framework is fairly easy in Visual Studio 2010 (see here for step by step), but two Major steps are:
  • Add Entity Framework Model:
  • Add WCF data service
A couple notices:
  • In web.config, the following connection string is added:
  • if you right click on .svc file in Visual Studio and View Markup, you will see something like the followings. The point is, it is not strongly named!
<%@ ServiceHost Language="C#" Factory="System.Data.Services.DataServiceHostFactory, System.Data.Services, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Service=" EntityDataService.AWDataService" %>


Now let's host this WCF data service in SharePoint _vti_bin folder, just like listdata.svc:
  • Sign this project:
  • Strong Name AWDataService.svc Markup:
<%@ ServiceHost Language="C#" Factory="System.Data.Services.DataServiceHostFactory, System.Data.Services, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Service=" EntityDataService.AWDataService, EntityDataService,Version=1.0.0.0,Culture=neutral,PublicKeyToken=d71e6a94584bc776" % >
  • Add an empty SharePoint project and add a sharepont mapping folder- ISAPI with following items:
    • an existing item: AWDataService.svc
    • a new item: web.config with the above connection string included
  • Add service dll into sharepoint package to be deployed into GAC:
  • Optimize by not including sharepoint project assembly in the package since it will be an empty dll otherwise
After deploy the sharepoint project, you should be able to browse this WCF dataservice as: http://yoursharePointserver/_vti_bin/DataServiceHost/AWDataService.svc

Mar 22, 2010

Consume SharePoint 2010 RESTful service from Ajax JavaScript

I ever post on how to Consume REST in SilverLight to bind SharePoint 2010 List Data. In this post, I will show how to consume SharePoint RESTful service in AJAX Javascript for databinding in a sharepoint application page (no authenticaion needed in this scenario).

First create an application page:

this should be easy to do by using Visual Studio 2010 sharepoint template, or you can simple manually creat one (see here).

Add AJAX library support into the application page:

This should be done simply by linking AJAX library from CDN. But as AJAX libray currently still in beta, you have to download MicrosoftAjax.js (this is needed only for dataview control used in the code) from here , add this file into your project file and then use ScriptManagerProxy to load it to the page (I think this should be a bug in beta). You can't use ScriptManger since sharepoint master page already has one.

The script should look like:


Invoke Ajax Call by using WebRequest, a traditional way

by default, RESTful service response with ATOM feed (XML formated). In order for AJAX to work, the request header should be specified as accepting application/json. This is important otherwise deserialization will fail.



In Callback, bind data with control:


with HTML makeup looks like this:


A even more elegant way, but not working yet... and it works!

In PDC 2009, a very elegant way was demoed by Stephen Walther to achieve this data binding with WCF service, but I can't make it work with listdata.svc. I think the fact that listdata.svc returns by default XML data rather than JSON might be the reason behind. I don;t know how to change it when create a dataview in the following code: Actually Ajax dataview Call use Json format as I discover this from Fiddler.



In fiddler, I can see listdata.svc get called, but it returns code 400, implying bad data format?
The problem was, url for fetchOperation in the code above ws illegal, and unfortunately this illegal url is tolerated in IE broswer.  Fiddle gave a misleading error code 400 due to whitespace.See Lessons learned from using Fiddler.

With this approach, http markup is clean without custom elements, and this is achieved by a custom item render as follow:









Related Posts:

Call Ajax-enabled WCF Service from Ajax JavaScript
Call WCF Service from Ajax JavaScript


Great Resources:

http://blogs.pointbridge.com/Blogs/monnette_jeff/Pages/Post.aspx?_ID=24

http://blogs.visoftinc.com/archive/2009/04/28/ASP.NET-4.0-AJAX-Preview-4-Client-Templates.aspx

Mar 19, 2010

Window Server, .Net Framwork and Visual Studio

Recently my coworker install Ajax Extension 1.0 on Window Server 2008 R2. As we know, Ajax 1.0 is an add-on only for .Net 2.0 framework, and Ajax support in .Net 3.5 is native. This installation doesn't make senses, however, the installation did fix issues for sharepoint content deployment. The story is, even though .Net Framework 3 is shipped, you still need to install it, otherwise, you only get .Net 2.0



As developer, most of us get .Net framework from the development tool we use: Visual Studio,


So it is important to know what .Net version on your deployment target server.

As a SharePoint developer, we know what .Net framework SharePoint is built on:

  • SharePoint 2010 .Net 3.5
  • SharePoint 2007 .Net 2.0
  • SharePoint 2003 .Net 1.0
If you want your sharepoint 2007 to run .Net 3.5 framework ( maybe  because you develop in VS 2008 and use some features such as LinQ), you need to modify the web.config as below:

<sharepoint >
  < system.web >
     <compilation >
        < assembly >
           < add assembly="System.Core, Version=3.5.0.0, Culture=neutral, publicKeyToken = B77A5C561934E089" >

 
Running SharePoint 2007 on a Window 2008 server doesn't mean SharePoint can run .Net 3.5 features such as SilverLight, Ajax and LinQ etc. see this article for more details.

Mar 11, 2010

lessons learned when debugging http traffic in Fiddler 2

When I debugged an ajax web service call to SharePoint listdata.svc, I often get a HTTP 400 error, which made me think something wrong with REST content format. It turns out it is because Fiddler Request Builder will not take white space!




Instead of typing in %20, a easy way is, first use IE browser and then in Fiddle Sessions window, copy its url to its Request Builder.








Secondly, if your web site makes another http call, the second http traffic will not be tracked if you run your web site from Fiddler. But they are tracked if run from browser.

Last, but not least, Fiddler 2 seems to work fine now with http://localhost/ , but is kind of tricks: if your website make a http call such as
request.set_url(http://localhost/_vti_bin/ListData.svc)
the traffic of this request will not be tracked in Fiddler

Mar 4, 2010

REST Service, Json and XML

REST support 2 native data formats: Json and XML. XML is default and is browser friendly with Atom feed. Json is programming friendly, particularly Ajax friendly because of its small dataload and easy deseralization. Either way, REST is very web friendly as it uses http like syntax which is easy for script to make call or for user to browse.

A common misconcept is Json is required for Ajax. Ajax can work with any format, but Json has significant advantage over XML. When making an Ajax call to a REST service, the request header can be specified with an "Accept:" format, but it is just a "wish", and will be granted only when the service has a capability for the requested format. So the following code will return error when the service doesn't response with Json data:


var data = response.get_responseData();
data = eval("(" + data + ")")

Also keep in mind, Visual Studio (2010 RC) doesn't provide java script intellisense for REST response data. In contrast, Ajax-enabled WCF service can emit a script proxy (via asp:serviceRefernce), so it has full intellisense support, and has built-in serialization/deserialization support with default Json format.

Create a WCF RESTful service in Visual Studio 2010

Visual Studio 2010 (RC) doesn't have a template specifically for RESTful service. The WCF service template will create a WCF SOAP service, but it can be converted into REST service as follow:



Edit web.config:



The web.config entities for REST is quite different from those for SOAP, but very similar to those for Ajax-enabled WCF Service, the only difference is, Ajax-enabled WCF has "enableWebScript":








Add WebGet attribute to all methods in contract interface, like:


[WebGet(UriTemplate = "Hello", ResponseFormat = WebMessageFormat.Json)]



Add this attribute for REST implementation class:


[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]


Test in Fiddler:

By now, it is a functioning WCF RESTful service, and response json format data. You can test it in Fiddler.


Great References:
http://www.ajaxlines.com/ajax/stuff/article/return_json_from_ajaxenabled_wcf_service.php
http://www.robbagby.com/rest/rest-in-wcf-blog-series-index/

Feb 26, 2010

ScriptManager & Scripts from CDN such as AJAX Library

With roll out of ASP .Net AJAX Library, adding ajax capabilities in scripts is nothing but a link to CDN:


<script src="http://ajax.microsoft.com/ajax/beta/0911/Start.debug.js" type="text/javascript" > </script >

It will load all scripts needed for ajax development regardless of .Net Framework. However if asp:ScriptManager is also used, it will load script from framework. That will cause some visioning problems, and it is the case for sharepoint pages(this seemingly only happens if usng dataview control). SharePoint 2010 master page has ScriptManager embedded and is used by both site pages and application pages . As currently in beta, the workaround is to locally include MicrosoftAjax.js (see here for details).

Another cool thing about ScriptManage or ScripManagerProxy is its asp:serviceReference, it will inject a proxy script class on fly to allow client script to call backend ajax enabled WCF service.


Feb 16, 2010

Modify SharePoint Solution Package (WSP) without rebuilding

Recently a SharePoint group memeber asked how to modify a text file inside a wsp without knowing source files's folder structure (i.e, it can't simply rebuilt by wspbuilder). Initially i thought it can be done just by unzip and zip again wsp file. It turns out even though wsp can be extracted by winzip, it can't be zipped back (the resulting wsp can't be added).

The right and simple way to do this is to use winzip extract and then use Cab SDK (download here) command such as:
cabarc -r -p -P winzip n bcs.wsp winzip\*.*

This works for both MOSS 2007 and SharePoint 2010 farm solution, but it doesn't work for SharePoint 2010 sandbox solution. I will update when I find a way to do it for sandbox solution as well (wait for 2010 RTM)

Feb 14, 2010

SharePoint BCS Entity Names Mapping

The high level of BCS structure consisits of one Entity Service, which is exposed public as External Content type wth CRUD methods:




and one in-memory object class which functionsas an interface between BCS and its backend datasource:



Those two are linked by object's type Name:



reference: http://www.screencast.com/users/jthake/folders/SharePointDevWiki.com%20Screencast/media/10d81c1f-2bbf-417f-a307-1e88933b2864
http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx
http://blogs.msdn.com/steve_fox/archive/2009/12/26/sharepoint-2010-development-using-bcs.aspx

Programming LINQ in VStudio 2010

  • LINQ to sql class
Programming LINQ to SQL in VStuido 2010 is as simple as step 1, 2, 3:
Step 1: launch VStudio 2010 to create an empty SharePoint Project:


Step 2: add a new item and choose LINQ to SQL Classes. Name it AWEmployee.dbml

Step 3: launch Server Explorer to drag Employee tables into design surface. In AWEmpolyee.designer.cs, you will find a class named as AWEmployeeDataContext.

  • LINQ to SharePoint
Just as SharePoint lists can now be displayed in VStudio 2010's Server Explorer, LINQ to SharePoint is another indication that MS start to treat SharePoint as a datasource. LINQ to SharePoint is not as mature as LINQ to SQL nevertheless. Currently it needs a manual process(as compared to the VS build-in entity framework for sql) , but fairly simple, to implement it:

Step 1 use SPMetal utility to generate a datacontext or entity class, for eaxmple: SPMETAL /web:http://sp2010/ /namespace:sp2010 /code: EntityClasses.cs

Step 2: the resulting source file defines a datacontext class which in turn defines an inner class for each individual SharePoint list (update 04/19/2010: or using parameters tag to define what you need to generate: /paramters:parameters.xml, see here for details) Add this file into VStudio project;

Step 3: Start query SharePoint List data by using LINQ query such as:
var query= from c in EntityClassesDataContext.Contacts where !c.ListName.Equal(""); orderby c.FirstName select c;
The advantage of using LINQ is, they are all strongly typed, and you get all intellisense.

Reference:
http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx

Feb 11, 2010

Colon a SharePoint web application

I was asked to colon a web application, essentially this is just to backup/restore content db. sounds very simple? but a couple very costly pitfalls:

First, if new web app resides in the same farm, the challenge is, each collection Id has to be unique.
  • use stsadm addcontentdb to assign a different id, but as warned by MS, the site collection very likely becomes an orphan;
  • use stsadm backup/restore for each individual site collection;

Second, it is very tempting to take this shortcut: create a web application and then do content database backup/restore. This is an absolute failure path since SharePoint Config DB is left out totally.

The working path is:
  • Restore the content DB (if in the same SQL instance, file names need to be changed)
  • creating a new web application in a different farm, use the restored db to replace the one randomly generated by SP
or
  • after web application being created, use stsadm -o addcontentdb cmd line or UI to add the restored db, and then remove the one auto-generated by SP.
whether stsadm or UI, the credential needs to have access to the database. In case of UI, it is farm account(running central admin pool) and of course it is logon user account for stsadm. SharePoint will grant all other pool ids (such as application portal pool id) for the database access.

Jan 29, 2010

New SPD, Old Story with Data View

When creating Data View Web Part to connect with external data source, the following is the most infamous error you might get:

"The server returned a non-specific error when trying to get data from the data source. Check the format and content of your query and try again. If the problem persists, contact the server administrator"

Karine Bosch's Blog is the best to describe the root of this problem. Even though it was written for last version SPD, it still works for SPD 2010 with its second solution (only): use stored procedure.


a small side note, you can always see details of each Data Sources in _catalogs/fpdataSources/ folder. Some people said it is the way to work around connections to non-sql DB. Also, using window connection to SQL is not allowed for a good reason:it will be treated as double hop.

Jan 27, 2010

Using SharePoint PowerShell with intellisense

With thousands of cmdlets in SharePoint PowerShell, it is almost impracticable to use PowerShell without intellisense, for this reason, I posted the question on how to get intellisense for SharePoint PowerShell on Twitter, LinkedIn SP groups, MindSharp Mailing list, but didn't get response back. Turns out it is not that difficult, but in case someone needs a quick reference, here is the things you need to do:


First Download Window PowerShell V2.o to install PowerShell ISE (UPDATE:  ISE is installed in  window 2k8 R2, just need to activate as feature You will find it in All Programs -> Accessories ->Windows PowerShell)



Follow this post to load SharePoint snap-in into Window PowerShell ISE

Use intellisense by entering Tab key


One twist is, after using index, such as Lists["shared documents"], intellisense stop working, as a workaround, $list=$siteCollection.RootWeb.Lists["shared documents"], intellisense will work after $list.

Jan 21, 2010

Security in SharePoint Client Object Model

Available authentication types for managed .net client OM include:
  • Anonymous
    web applications need to be anonymous and Client OM permission requirement need to be unchecked as well:

    Even so, some operation like list.getitems(query) are blocked for undocumented reasons.
  • Default (Window Authentication)
  • By default, both .Net Client OM and Silverlight Client OM use window authentication, and credentials are passed through, i.e, sharepoint will authenticate the user who is running client applications.
      For web client application, when debugging in VStudio (F5), it is account running VStudio that will be passed, but for IIS sites, it is either App Pool ID (by default, no impersonation) or user login in account( when impersonation enabled) or anonymous accout (when anonymous enabled)
    • FormsAuthentication



    Addition security restriction:



    • ECMAScript Client OM can only access SharePoint data for current site, no cross site scripting allowed (no place in ECMA OM you can pass credential ). That means ECMAScript Client OM can only be used in SharePoint context, such as application page, web part, and dialogue.
    • Silverlight Client OM can only access resource from the same domain unless explicitly defining clientaccsspolicy.xml.

    Jan 17, 2010

    Load CDN hosted JQuery

    Since loading JQuery libraries from Content Delivery Network (CDN) has many advantages over hosting locally, I adopt this approach today by using script tag as:
    <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.js" type="text/javascript" > </script >

    I didn't expect any problem in doing that, but to my surprise, I kept getting "object expected" error on VStudio debugger. I tried with Google CDN, same error.

    The error indicates that JQuery is not loaded, but what causes it? It turns out this IE setting is the reason, somehow "Active Script" is disabled in my Win2k8 Web(SharePoint 2010) Server:


    Don't believe this could be a common case, but it proves CDN hosted JQuery relies on browser settings, and can fail. So the best practice is to always provide a failover to local JQuery libraries.

    Jan 11, 2010

    debugging SharePoint Silverlight Client OM code

    I have created a Silverlight application in VStudio 2010 (Beta 2) and wired it to sharepoint by using Silverlight Client Object Model. With F5 debugging, the code in ClientRequestEventHandler (OnSuccess) can't be hit:

    ctx.ExecuteQueryAsync(OnSuccess, onFail);

    However, if I put the .xap file in sharepoint _layouts folder, and link it to sharepoint OOB silverlight webpart, the code in the eventHandler are executed well. Even though that doesn't help to debug the silverlight application, it does give me a clue why running from VStudio doesn't work with SharePoint Client OM.

    Silverlight, as a client technology, has limitations on crossing domain access. With sharepoint lives in http://localhost/, and Silverlight test web lives in http://localhost:randomPort , that is treated as crossing domain access. To verify this, under sharepoint iis root path, i create a clientaccesspolicy.xml file. I can then debug into the EventHandler Callback code with VStudio F5. Works like a charm!

    Another anonymity is, when hosting silverlight app by using OOB Silverligh webpart, after updating .xap file, you have to also delete the browser's cookie to see the refresh.

    Jan 6, 2010

    SharePoint 2010 Reusable Workflow

    SharePoint 2010 (beta 2) has 3 kinds of workflow based on association:

    • List WorkFlow: associated with a list
    • Site WorkFlow : associated with a site
    • Reusable WorkFlow: associated with a content type or site column

    Since it is associated with either content type or site column, the Reusable Workflow accompany the same content type or site column across the whole site. It can't be associated directly with lists nevertheless. When Reusable WF is associated with a Site Column at design time, the site column need to be added into a content type first, and then the WF can be associated with that content type.

    Reusable WF can only be created in SPD (WF created in VStudio are always reusable), but it can be imported into VStudio as a list workflow and become reusable in a site collection scope. In Beta 2, Reusable WF automatically has a init form once it gets published, and it is not converted after Reusable WF get imported into VStudio. Te following problem occurs at workflow run time:

    " _layouts/... . /IniWekfllp. aspx " not found.

    Creating a Init From in VStudio can get around this problem.