Showing posts with label SharePoint Online. Show all posts
Showing posts with label SharePoint Online. Show all posts

Friday, 4 July 2014

Working with multiple Microsoft accounts (multiple 365 accounts)

it can be tiresome and confusing working with multiple microsoft accounts. there are countless scneario's where you will need to be logged in to more than one microsoft account at the same time, now the common way of doing this would be to use different browsers, IE and FIrefox or chrome for example, thats one way of doing it but that means you can only have a certain number of accounts, or using in private or incognito browsing but again, they all have limited usage and with the in private you will loose your credentials and history when you cose the window

Scenario's:
Using personal Live account and need to sign in with company account
Using company account and trying to sign in to company dev account
Using client account and trying to sign in with company account
the scenario's go on and on,

Enter Chrome Users....

Chrome has taken the title of best browser from firefox a few years back, it is quick, light and it works, for most web developers it is the browser of choice and thelist of reasons for that are as long as your arm.

chrome has another feature that most people arent aware of or using, this feature is perfect for using multiple accounts

Chrome Users

Setting up Users: he chrome site has all the information you need on setting up users here: https://support.google.com/chrome/answer/2364824?hl=en-GB

On my environment i need to mange four separate Microsoft accounts, for this I have created four users, my first user being my main intranet account:


on that account I have saved passwords and settings for that user, if I click to the "Py" account, a new window opens with that user icon, with that i am able to use all my saved settings and passwords for my "Py" 365 account


You can see when you have multiple windows up, the icon user indicator allows you to easily see which window is which, this works for as many users as you want.


I highly recommend using it for any one who has to manage more than one Microsoft account, it is brilliant and such a simple way of managing multiple accounts!

Tuesday, 17 June 2014

SharePoint 2013/365: Get current page properties/metadata with REST

Scenario

Retrieve the current page layout name via the page metadata on Office 365, this approach must be maintainable, flexible and not have any extra costs


Investigation

There are a number of ways to get the current page metadata with full trust code, simply using the SPContext.Current.ListItem allows you to get the collection, of course that wont work going forward with O365.

The most flexible way of working with any form of SharePoint object in O365 is to use JavaScript, thankfully there are a number of ways that can be done:

  • Use the JSOM - there are a number of blog posts currently on how to return the current items with JavaScript
  • Use Search - mapping properties and matching the search result by url is also a possibility, this is fast and allows easy optimisation
  • Use REST - there isn't much on this approach out there, it looks like a pretty obvious choice so i decided to try this approach.

Solution

The architectural approach is as such:
On Page Load

  1. Using the current context object data form a rest query
  2. Query the ListItem REST endpoint
  3. Get the page fields out of the returned data

Here is the finished codeblock:

Saturday, 15 June 2013

SP2013: Calling SP.ClientContext for an anonymous user causes "object doesnt support this method"

Good Morning!, and what a wonderful Saturday morning it is, the scent of strawberries are in the air!

So I've been working on a public facing 365 website lately and making a few customisations, one request I received was to have the ability for users to add an item to a "mailing list" list, and they wanted maximum portability, so I thought, perfect for the JS-CSOM!

Such a simple idea, add an item to a list, just needs one field adding in very straight forward, or so I thought, so I created the js function and hooked it up, for auth users it worked like a charm but I ran into a problem when accessing it anonymously, I got the error "object doesn't support this method" when calling a new "SP.ClientContext", its a straight forward error meaning it cant find the function in any loaded libraries, so I thought right, gotta be SP not loading sp.js, simple, add a script link in there... no luck the same error came up, then I thought right, gotta be that the method is running before SP.js is properly loaded so I used "ExecuteOrDelayUntilScriptLoaded()" to encapsulate my code and make sure it runs after the code is loaded, published the js and checked it again... no luck!

So it has to be sp.js not loading correctly, remembering the SoD SharePoint is so fond of I then tried the trusty "SP.SOD.executeFunc('sp.js', 'SP.ClientContext', addToMailingList)", and it worked perfectly!

Code:

$("#ben-mailinglist-confirm").click(function () {
    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', addToMailingList)
});

function addToMailingList(metadata) {
    var metadata = $("#ben-mailinglist-email").val();
    if (metadata != "") {
        var clientContext = new SP.ClientContext("/");
        var list = clientContext.get_web().get_lists().getByTitle('MailingList');

        var itemCreateInfo = new SP.ListItemCreationInformation();
        var listItem = list.addItem(itemCreateInfo);
        listItem.set_item('Title', metadata);
        listItem.update();

        clientContext.load(listItem);
        clientContext.executeQueryAsync(
       Function.createDelegate(this, function () { $(".ben-mailinglist-success").show(); $(".ben-mailinglist-form").hide(); }),
       Function.createDelegate(this, function () { $(".ben-mailinglist-failure").show(); })
   );
    }
    else {
        // validation
    }
}

Wednesday, 5 June 2013

SharePoint Online (Office365): Profile images broken / not coming up

Today I had a brilliant issue, I have a 365 authenticated site that uses profile images, these are surfaced in the "ContactFieldControl", I added profile pictures to the profiles and navigating to the mysites worked fine and the profile picture on the contactfieldcontrol worked too but then I opened it in a different browser and the profile image was broken in the webpart, that was strange I thought maybe an MS Job had deleted it so I went to the mysite and the image was there!, so I navigated back to the site and once again it shows up

So it appears if the image is loaded through the contact field webpart it shows as a broken image but if you navigate to the mysite or the image directly it worked

So how to fix it?

this issue appears to be in the first load of an image using the direct path to the image, i was hoping a cache clear or an update of the profiles would fix but but to my knowledge there is no OOTB way of fixing this so i resorted to using a dev's best friend, jQuery!

First I tried running a piece of jQuery on the page to preload the image using an ajax call but that didn't work

Then I noticed something interesting, whilst fiddling the page I saw that it also calls the following URL "/_layouts/15/userphoto.aspx?size=S&url=********", this URL links directly to the image, I thought this was interesting so I wrote a piece of jquery to take the source of the image and transform it into a URL like the one above and hey presto it worked!!

Code:
function checkProfileImages() {
    $(".ben-imgborder img").attr("src", "/_layouts/15/userphoto.aspx?size=S&url=" + $(".ben-imgborder img").attr("src"))
}

Monday, 6 May 2013

Using the C# CSOM to interact with SharePoint Online

So, I had a requirement recently to allow a client to interact with their SPOnline site from their on-prem network, essentially being able to sync data from their on-prem LoB apps to their SPOnline site.

As any sp dev knows there is one main way of interacting with SharePoint remotely, that is through the supplied web services, this can be done either through interacting directly with the web services or by using the SharePoint client site object model which essentially just wraps a basic API around the web services, so its your preference on what you want to use.

Now with the CSOM any interactions with SharePoint are based around the context, to set up the context you need to pass in the credentials and authenticate the accessing user, in SP 2010 this was a feat to accomplish as there was no real way to pass in an authentication token to the context, with the release of SP2013 MS have made this significantly simpler, you can call in a class called "SharePointOnlineCredentials" this will handle any authentication you should need to do. this class is included in version 15 of the Microsoft.SharePoint.Client dll

Depending on how you have your dev environment set up you may encounter a "FileNotFoundException" pointing to "MSOIDCLIL.dll" this usually occurs if you have VS installed locally and have installed the dev tools but you haven't installed the client sdk, you can check this by navigating to this directory "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\Client", if that dir exists and has the dll then there is a broken link somewhere and you will need to reinstall the sdk, if it doesn't exist then a fresh install of the SharePoint Client SDK here.

By using this you now have open to you the full array of functions you can call with the CSOM that you can now call from your on prem network

Here is the code I have used to PoC the process, please use it as you see fit:


    class Program
    {
        static void Main(string[] args)
        {
            args = new string[] { "CreateProjectList" };
            if (args.Length != 1)
            {
                Console.WriteLine("Instanciate the program with a method parameter:");
                Console.WriteLine(" - GetLists");
                Console.WriteLine(" - CreateProjectList");
            }
            else
            {
                switch (args[0])
                {
                    case "GetLists":
                        Console.WriteLine("Getting lists from Online Site");
                        GetLists();
                        Console.WriteLine("List retrieval complete");
                        break;
                    case "CreateProjectList":
                        Console.WriteLine("Creating projects list in Online Site");
                        CreateProjectList();
                        Console.WriteLine("List creation complete");
                        break;
                }

                Console.ReadKey();
            }
        }

        private class Configuration
        {
            public static string ServiceSiteUrl = "https://{mysite}.sharepoint.com";
            public static string ServiceUserName = "{user}@{365-org}.onmicrosoft.com";
            public static string ServicePassword = "{password}";
        }

        static ClientContext GetContext()
        {
            var securePassword = new SecureString();
            foreach (char c in Configuration.ServicePassword)
            {
                securePassword.AppendChar(c);
            }

            var onlineCredentials = new SharePointOnlineCredentials(Configuration.ServiceUserName, securePassword);

            var context = new ClientContext(Configuration.ServiceSiteUrl);
            context.Credentials = onlineCredentials;

            return context;
        }

        static void GetLists()
        {
            var context = GetContext();
            var results = context.LoadQuery(context.Web.Lists.Include(list => list.Title, list => list.Id));
            context.ExecuteQuery();
            results.ToList().ForEach(x =>
            {
                Console.WriteLine("List: " + x.Title);
            });

            context.Dispose();
        }

        static void CreateProjectList()
        {
            ClientContext clientContext = GetContext();
            Web site = clientContext.Web;

            // Create the project list.
            ListCreationInformation listCreationInfo = new ListCreationInformation();
            listCreationInfo.Title = "Projects";
            listCreationInfo.TemplateType = (int)ListTemplateType.GenericList;
            List list = site.Lists.Add(listCreationInfo);

            // Add the category field to the list.
            Field catField = list.Fields.AddFieldAsXml(@"
                <Field Type='Choice' DisplayName='Category' Format='Dropdown'>
                    <Default>IT</Default>
                    <CHOICES>
                      <CHOICE>IT</CHOICE>
                      <CHOICE>Sales</CHOICE>
                      <CHOICE>Research and Development</CHOICE>
                      <CHOICE>CSR</CHOICE>
                    </CHOICES>
                </Field>
                ", true, AddFieldOptions.DefaultValue);

            // Add list data.
            ListItemCreationInformation itemCreationInfo = new ListItemCreationInformation();
            ListItem listItem = list.AddItem(itemCreationInfo);
            listItem["Title"] = "New public facing website";
            listItem["Category"] = "IT";
            listItem.Update();

            listItem = list.AddItem(itemCreationInfo);
            listItem["Title"] = "New Incident Management System";
            listItem["Category"] = "IT";
            listItem.Update();

            listItem = list.AddItem(itemCreationInfo);
            listItem["Title"] = "New internal sales strategy";
            listItem["Category"] = "Sales";
            listItem.Update();

            listItem = list.AddItem(itemCreationInfo);
            listItem["Title"] = "Youtube product visibility";
            listItem["Category"] = "CSR";
            listItem.Update();

            clientContext.ExecuteQuery();
        }