Welcome to my blog, stay tunned :

Using CSOM from an App Part

Hi,

Since I couldn't find any example on the web showing how to use CSOM from an App Part and since it's actually a bit more tricky than using CSOM from the App itself, I thought it could be a good idea to blog about that!

Tip when developping auto-hosted Apps

Hi,

If like me, you have several Office 365 accounts, you might be annoyed when deploying Apps from Visual Studio if you checked the option "Maintian my connection" when Visual Studio prompts you for credentials.

As soon as you do that, if you switch to another Office 365 instance, Visual Studio keeps sign in you with the previously entered credentials which results in a failure since you are not a member of this new instance and it does not you offer the option to sign in as a different user.

Tip with localized InfoPath web browser-enabled forms

Hi,

One technique to localize InfoPath forms is explained on MSDN at the following address. Basically, the idea is to embed your resx files into the form, associate a default one with a XML data connection and then, dynamically load the right resx file corresponding to the current locale of your SharePoint site.

However, what this article doesn't mention and what I couldn't find anywhere is that there is a small trap when using this technique. Indeed, if you do as specified in the article, you'll be facing a silly error and switching from one language to another will just not work.

It will work from the InfoPath Designer previewer but not from Forms Services (once published to SharePoint). This problem is because the path determined by the FileLocation property is not the same...In InfoPath Designer, it contains only the name of your resx file, say myfile.en-US.resx while in Forms Services, this path is prefixed by x-soln:///...

Therefore, in your code, say the loading event, you'd better add this check and adjust the path accordingly:

if (Application.Environment.IsBrowser)
                    ResxFilePath = "x-soln:///";

dc.FileLocation = string.Concat(ResxFilePath,"your file","the dynamic locale",".resx");
dc.Execute();



Happy Coding!

OData CRUD in SharePoint 2013 + Authentication scheme explanation

Hi,

A while ago, I wrote a blog post about OData and recorded a video that shed some light on how to use one of the most unused built-in factory of SharePoint 2010.
This example was explaining how to leverage OData to query data stored in memory but it only demonstrated the "R" of CRUD operations. Before reading further this post, if you're not familiar with hosting WCF Data Services in SharePoint, I'd really recommend you to read my previous post since I won't go into details anymore.
In SharePoint 2010, this was quite difficult to implement because in many scenarios, the authentication providers associated with the web applications are still based on windows integrated security. When coming to data update. As described on MSDN, the article on WCF Services in SharePoint Foundation explains that the authentication scheme (anonymous/ntlm/kerberos) is added by SharePoint Foundation 2010 to the URL (and to the ID of the returned entities) to uniquely identity resources when multiple authentication protocols are enabled for a single webapp...(example anonymous/kerberos).
So far so good but what MSDN doesn't explain is that because of this, only the R of CRUD is working....To illustrate that, I've written a very basic service that is exactly the same between 2010 and 2013 but you'll see that the behavior is slightly different. This demo service allows to handle a list of courses with the support of CRUD operations. I'll share the code a bit later but first let's see how this service reacts on SharePoint 2010.
When calling it from the browser, you get this:

As you can see, the authentication scheme is indeed part of the URL... Therefore, if you try to perform an update from a server-side consumer component, say a console app for which you've added a service reference to /_vti_bin/ODataCRUD.svc, you get the following :

Because as you can see, the URL used to target the object we want to update contains NEGOCIATE...and this results in the highlighted error.
Despites of the fact that the very promising class attribute [ServiceFactoryUsingAuthSchemeInEndpointAddress(UsingAuthSchemeInEndpointAddress = false)] exists, it has, at the time of writing absolutely no effect on the WCF service behavior...meaning that the above error persists.
So, except consuming a custom OData service for update/delete via AJAX (with AJAX, you generate the URLS manually), I never managed to get it working from server-side component consuming the WCF service via a proxy. Of course, working with HttpWebRequest works :













HttpWebRequest req = HttpWebRequest.Create("http://server/_vti_bin/ODataCRUD.svc/Courses(ID)") as HttpWebRequest;
req.Method = "MERGE";
req.Credentials = System.Net.CredentialCache.DefaultCredentials;
req.ContentType = "application/json";
byte[] data = UTF8Encoding.UTF8.GetBytes("{ \"CourseTitle\" : \"Updated Course\" }");
req.ContentLength = data.Length;
Stream DataStream=req.GetRequestStream();
DataStream.Write(data, 0, data.Length);
DataStream.Close();
req.GetResponse();

Leveraging .NET 4 in SharePoint 2013 Series (7) - WCF REST Caching

Hi,
I'll be writing a series of blog posts about leveraging .NET 4 within SharePoint 2013. As you might know already, SharePoint 2013 is now based on this .NET runtime version v4.0.30319 which actually allows developers to benefit from .NET 4 features. You couldn't do that with SharePoint 2010 which was still based on .NET runtime v2.0.50727.

AspNetCacheProfile

WCF 4 brings a new caching mechanism that is built on top of ASP.NET caching. One can easily use that in the context of SharePoint 2013. Say that you want to build a service that returns the latest news of the company on the form of either ATOM XML, either RSS.

Say that these news are the results of an aggregation that takes time to complete, you'd likely want to cache that in order to avoid to perform costly operations whenever someone sends a request to visualize those news.

With WCF 4, it's a piece of cake and the good news is that, it's not much more complicated to integrate that in SharePoint 2013. Indeed, two things must be done:

  • Define cache profiles in the web.config
  • <caching>
    <outputCacheSettings>
      <outputCacheProfiles>
        <add name="CompanyNewsFeed" 
          duration="3600" 
          varyByHeader="Accept"
          varyByParam="" />
      </outputCacheProfiles>
    </outputCacheSettings>
    </caching>
    

    The drawback you have here is that you must define this in the web.config of the SharePoint web app you are targeting. You can't define the caching section in a custom web.config that you would deploy along with your .svc file because this section can only be defined in the root web.config. So, you'd either see with your administrators, either write some piece of code with SPWebConfigModification (automatic but sometimes dangerous), either you document the change and let the administrators cope with it.
    The best would have been of course to deploy a custom web.config file along with your service so that nothing needed to be changed but I couldn't succeed unless I convert the ISAPI (_vti_bin) virtual directory as an application but that's not something you want to do in SharePoint, right?.
    Anyway, above I'm just declaring a cache profile that retains data during 1 hour. So, any subsequent request after the first request will pull the data from the cache unless the Accept header changes. In the case of RSS/ATOM, this will change according to the choice you make.

  • Decorate your service methods with the AspNetCacheProfile attribute and specify the cache profile you want to use
  • For sake of simplicity, I'm not going to follow the WCF best pracitces (Contract/Service/DataContract) and I'm not making any error handling to make it short and focus on the caching story. I'm sure you'll forgive me :). So, I've assembled everything in those two following classes:

    //Data object
    public class News
    {
        public string Title;
        public string Body;
        public string Author;
        public DateTime PublishedDate;
        public News() { }
    }
    
    //Service Attributes
    [ServiceContract]
    [ServiceKnownType(typeof(Atom10FeedFormatter))]
    [ServiceKnownType(typeof(Rss20FeedFormatter))]
    [AspNetCompatibilityRequirements(
      RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]    
    [System.ServiceModel.ServiceBehavior(
      IncludeExceptionDetailInFaults = true)]
    public class NewsService 
    {
      [OperationContract]
      //This is where you make the link to the cache profile you defined earlier in the web.config
      [AspNetCacheProfile("CompanyNewsFeed")]        
      [WebGet(UriTemplate = "/news/feed/{format}")]
      public SyndicationFeedFormatter GetCompanyNews(string format)
      {
        //Here I'm just building a dummy list of news but
        //in the real world, this could be a heavy operation
        List<News> DummyNews = new List<News>();
        for (int i = 0; i < 4; i++)
        {
          DummyNews.Add(new News
          {
             Title = string.Concat("News ",i),
             Body = string.Concat("This is the fake news number ",i),                    
             PublishedDate = DateTime.Now
          });
        }
        //Building the returned feed    
        SyndicationFeed ReturnedNews = new SyndicationFeed            
        {
          Title = new TextSyndicationContent("Company News"),
          Description = new TextSyndicationContent("Company Feed"),
          Items = from NewsItem in DummyNews
                  select new SyndicationItem
                  {
                    Title=new TextSyndicationContent(NewsItem.Title),
                    Content=new TextSyndicationContent(NewsItem.Body),                                                      
                    PublishDate=NewsItem.PublishedDate
                  }
        };
    
        if(format == "atom")
          return ReturnedNews.GetAtom10Formatter();
        else
          return ReturnedNews.GetRss20Formatter();
        }
    }
    
    

So, the result looks like this:

and if you look at the date & time, it won't change during 1 hour unless you decide to change the format (atom or rss). Last thing I should add even if it's obvious, since this WCF caching capability relies on ASP.Net caching, it's not distributed. This means that in the context of SharePoint where you usually have several WFE, each WFE will have its own cache state. This could lead to troubles for more sensitive data if the load balancer redirects your request randomly to any WFE, you could have different states unless you're using sticky sessions.

Happy Coding!

Mobile development for SharePoint

Hi,

I'll be writing a series of blog posts explaining how to develop mobile applications for SharePoint. Here is what is planned:

Mobile development for SharePoint - Part I

In this blog post, I'll be talking about the various possibilities to design mobile apps for SharePoint. You'll also see what's my preferred framework and I'll give some input on what are the key factors to take into account in order to make a choice. Of course, the choice will always be yours, my goal is just to give some tips.

Mobile development for SharePoint - Part II

In this blog post, I'll be talking about how to integrate the Sencha framework with SharePoint. I'll build a small app and will give the necessary explanations to understand the interactions between Sencha & SharePoint.

Mobile development for SharePoint - Part III (to be written)

I'll go a little bit further and show how to build a production ready Sencha Package and how to deploy it properly into SharePoint. I'll also go a little bit further regarding the interactions (read/write) operations from a mobile app and custom server-side components that are more suitable for communications purposes.

Mobile development for SharePoint - Part IV (to be written)

In this blog post, I'll be talking about how to integrate PhoneGap together with Sencha & SharePoint.

Mobile development for SharePoint - Part V (to be written)

In this blog post, I'll be talking about SharePoint 2013 specific features with regards to mobile development

Happy Coding!

Mobile development for SharePoint - Part II

Hi,

If you didn't read the first part, I encourage you to do so before going any further. In this second part, I'm going to show you how to develop a very simple mobile app for SharePoint.
As mentioned in my previous post, I've opted for Sencha as a mobile framework. Sencha is a free framework for non-commercial applications and cost about 400€ if you want to distribute commercial applications. For a good overview of their product, you can of course visit their web site at http::/www.sencha.com. It gives the information you need to know to get started, a lot of documentation and a growing community using their forums.
In this blog post, I'm going to show you how to build a basic mobile app that will get some data from a SharePoint list. We will collect items from an Announcement list :





Mobile development for SharePoint - Part 1

Hi,

I'll be starting a new series of blog posts about mobile development and SharePoint. On a recent project, I've been in charge of making a POC in order to make a SharePoint 2010 Intranet available on mobile devices. Of course, the goal was to really benefit from the device capabilities.

The main target was iPad. My first reaction when looking at these requirements was that with a tablet such as an iPad and soon Microsoft Surface, your web sites don't need to be so mobile-ready to be browsable & usable.

Indeed, my opinion (that's mine only) is that the added value of a mobile site/app is really there when targeting phone devices because they have such a small screen, a poor keyboard that it's often very boring and tedious to interact with a non-mobile web site.

That said, I kept of course the phones in mind when working on the POC.

In this first blog post, I'm going to talk about the different possibilities we've analyzed (me & the development team) and the choices we made that were IMHO the most relevant. In the next blog posts, I'll enter more in the technical details and some demo code. Note that all what I'll state in this series will be valid for SharePoint 2007, 2010 and even 2013 although the latter has a new plumbing & controls to facilitate cross device implementations.

Native App VS Mobile Framework
As you might know, there are several ways to tackle mobile implementations. If we think of Apple's AppStore, we all know that we can easily install an app from the AppStore such as Twitter, Facebook etc.. and start using it. Usually, this is a very convenient way to leverage all the capabilities of your mobile device and these apps are very user friendly.
What's a native app
A pure native app is specifically packaged for a mobile operating system such as IOS, Android etc.. and deployed either to an Enterprise AppStore, either to a public AppStore.


Tip : Using Device Channels of SharePoint 2013 using CloudShare

Hi,

I've been trying to use the device channels using a CloudShare environment and I've been facing a silly problem that made me lose a bit of time. You could probably encounter the same issue so that's why I'm writing this note.

If you're using the preconfigured SharePoint 2013 Server image, you will likely enable web access so that you can test the device channels with actual mobile devices. If you end-up like me with no error but just SharePoint that keeps ignoring the configuration and launches the default channel whatever device you are using fror browsing, then, you'll be in the same situation than the one I was experiencing :).

Although that might not sound obvious, this is actually due to an AAM issue. In the CloudShare FAQ, they explain that you're supposed to add this AAM if you encounter problems to connect to a SharePoint 2010 environment

In my case, with their default 2013 image, I didn't face any problem other than the fact that SharePoint was not launching the right device channel.

Anyway, I decided to add my vanity URL as an extra AAM public URL and the magic happened! This drove me nuts for a while so that's why I decided to share this tip :)

Happy Coding!

Leveraging AppFabric for custom caching in SharePoint 2013

Hi,

[Update] the scenario depicted in this blog post is not supported. I wrote it in 2012 with the public beta of SharePoint and I had doubts about supportability. Microsoft confirmed 1 year later that this is indeed not supported to use SharPoint's AppFabric for custom caching. You should create another cluster instance...

As you might have noticed, AppFabric is now one of the pre-requisites when installing SharePoint 2013. SharePoint makes use of it for workflows and activity feeds.

When I noticed that AppFabric was part of the pre-requisites, I directly thought of trying to figure out whether SharePoint would give developers new APIs to leverage AppFabric's distributed cache capabilities. As SharePoint developers, on the 2007/2010 versions, when it came to caching, we always had to either use ASP.NET cache (mostly inproc), either rely on third parties such as NCache or AppFabric but we had to install/configure those ourselves as they were not integrated to SharePoint.

Unfortunately, at the time of writing, Microsoft did not release any public API enabling us to benefit from a Farm-Wide caching system. Indeed, the classes leveraging AppFabric are all marked internal, so there is no public API. However, the good news is that we know AppFabric will be deployed on every SharePoint setup, therefore, we can start using it the context of SharePoint using the AppFabric client DLLS.

I built a wrapper that you can download here http://sptoolbasket2013.codeplex.com/ whose the purpose is to ease the use of the AppFabric layer in the context of SharePoint 2013. I should add that this is currently at an experimental stage since I've never used that for a real project and I don't even know whether this wrapper would be supported by Microsoft :).

I'll describe hereafter all the testings I made with this wrapper & AppFabric in SharePoint 2013.