CHUVASH.eu

CHunky Universe of Vigourous Astonishing SHarepoint :)

Tag Archives: sharepoint 2013

What about the SharePoint app domain?

This is an open question about the domains for SharePoint apps. On Technet: Configure an environment for apps for SharePoint (SharePoint 2013) we can read the following:

You must configure a new name in Domain Name Services (DNS) to host the apps. To help improve security, the domain name should not be a subdomain of the domain that hosts the SharePoint sites. For example, if the SharePoint sites are at Contoso.com, consider ContosoApps.com instead of App.Contoso.com as the domain name.

Does it apply to SharePoint Online? Well, apparently not 🙂 So why should we do it on premises?

subdomain

As we all know, sharepoint.com is used for our Office 365 tenancies and for apps.

First look at Yammer integration in SharePoint 2013 SP1

I have installed SharePoint SP1 on my development machine. Yammer and OneDrive links have appeared in the Central Administration:

yammer-001

If you go ahead and click “Configure Yammer”, you can activate it:

yammer-002

Because:

Yammer is Microsoft’s recommended tool for social collaboration.

When you activate Yammer, you’ll get this dialog, and the Yammer link in the SuiteBar:

yammer-003

yammer-004

What happens when you click on Yammer, is that you are redirected to Yammer.com and you are prompted a login page.

Then you have a usual yammer site with all your networks and stuff (in my case, SPC14 network):

yammer-005

Then, if you go to your newsfeed, the following message is shown:

yammer-006

This page displays updates for sites you’re following. To connect with people, use Yammer.

There are still many questions about the Yammer and Newsfeed. But I like the activation process in the SharePoint 2013 SP1

The sessions I attended

My colleagues and friends keep asking me what sessions I went to and what I would recommend to see on channel9 where all of them are publicly available. Here is my prioritized list of sessions:

  1. #spc325 Real-world examples of FTC to CAM transformations. This was the most exciting developer session. Vesa Juvonen takes the Cloud App Model to its maximum. Wanna know more about the future. See this session.
  2. #spc404 Build your own REST service with WebAPI 2. You know REST? You like $filter, $top and $select? Good, why not create an own api? You have all the tools in Visual Studio 2013. Just get inspired by Scott Hillier.
  3. #spc269 Developer audience keynote | What’s new for the Office & SharePoint developer. Get all the developer news presented at #spc14.
  4. #spc3999 SharePoint Power Hour – New developer APIs and features for Apps for SharePoint.
  5. #spc371 Developing socially connected apps with Yammer, SharePoint and OpenGraph. Chris Johnson talks about how to use Yammer API to post updates, like and comment from code. What if you wanted to send an update to Yammer from your Line-of-Business application? Very easy.
  6. #spc303 Advanced Performance Analysis for SharePoint. A real-world case study how performance of a SharePoint site is measured, captured and analyzed. Really interesting.
  7. #spc391 Deep dive into Mail Compose Apps APIs. Main compose apps are similar to SharePoint apps, they are run as iframes and can be used to update an email while writing it or start a workflow. Good stuff.
  8. #spc334 Real-world SharePoint architecture decisions. Wictor Wilén talked about his best topic: architecture decisions. He is probably the best in this area in the world, and his presentation becomes better and better every time he presents it.
  9. #spc3000 Changing the look of Search using Display Templates and CSR. You can do a lot of stuff using the Display Templates and Cliend-Side Rendering. See this session to get inspired and gather a deeper understanding how it works.
  10. #spc382 Managing Search Relevance in SharePoint 2013 and O365. How does XRANK work? Well it is complicated. This session is a must-see.
  11. #spc224 The SharePointConference.com Site: From Sketch to Launch to Live! Did you know that SharePointConference.com was built upon SharePoint? See this session to find out what was good in SharePoint for this site, and what workarounds and hacks were necessary to get it to work.
  12. #spc302 Advanced development patterns for SharePoint Apps. Provider-Hosted Apps are the best type of apps. Let’s see what examples and tips are provided in this session.
  13. #spc322 SharePoint 2013 Search display templates and query rules. An introduction to Search Display Templates.
  14. #spc301 Access is back! High-value, ‘no code’, functional & flexible business apps with the new Access services. There were a lot of jokes in this session. Access apps are new “no-code” solutions and will replace the InfoPath solutions.
  15. #spc407 Deep dive into the SharePoint 2013 CSOM API’s. The name is not correct. It is a dive into the CSOM, but it is not deep. See it if you want an introduction, but please keep in mind, the examples don’t follow the javascript coding conventions.
  16. #spc381 Load testing SharePoint 2013 using Visual Studio 2013. Never used load-testing with Visual Studio? Got a 1.15 hr to kill? Well, see it to learn how to start the Visual Studio and what difference is between a web test and load test.

 

The sessions I wish I had attended:

  1. #spc4o9 Deep dive: SharePoint and Office App Security Model (OAuth & S2S)
  2. #spc417 Speed up your app development skills with API abstraction

 

Custom Error and Access denied pages in Sharepoint

Unfortunately in SharePoint 2013 the custom error pages are not applied: link 1, link 2. Hopefully there will be a hotfix that solves it.

morethansharepoint

Ok, lets get started.

So for my latest project I had to replace the default sharepoint error pages with a custom one. There are different types of error pages such as the ones for 404 and 500 errors. These are set by IIS and are basically simple html pages that are shown if the requested page is not found or other errors.  But the error page that sharepoint uses is shown for errors that relate to sharepoint and shows correlation id and a simple message.

The default page for this type of error is located in the 14 hive /template/layouts/error.aspx.

Error.aspx inherits from Microsoft.Sharepoint.ApplicationPages.ErrorPage and by examining this in Reflector it’s relatively easy to see how it works. When an error occurs, the Item collection in the HttpContext gets filled by some keys such as ErrorText and ErrorCorrelationId. The error page simply gets these strings from the context (and also…

View original post 150 more words

PowerShell: Get version and ProductId from an .app package

In my project I deploy some apps directly through the ObjectModel directly with PowerShell. The apps are built with TFS

I have a script that installs or updates apps if there is a new version of the app. Previously I used Import-SPAppPackage to compare the version and productid with an existing app instance, but often I get this error:

The provided App differs from another App with the same version and product ID.

Here you have the issue. Now the solution is to read the AppManifest.xml. But first the .app package has to be extracted like a usual zip file. This is the powershell function for that:

function Get-SPAppPackageMetadata {
  <#
  .SYNOPSIS
    Gets the version and productid of an app package
  .DESCRIPTION
    This function extracts the AppManifest.xml from the app and gets the Version and the ProductId
  .EXAMPLE
    Get-SPAppPackageMetadata- AppPackagePath "C:\folder\app.publish\1.0.0.1\App1.app"
  .PARAMETER AppPackagePath
    The path to the new version of the app
  .Notes
        Name: Get-SPAppPackageVersion
        Author: Anatoly Mironov
        Last Edit: 2013-12-05
        Keywords: SPApp, SPAppInstance
  .Link
        http://chuvash.eu
  #>
    [CmdLetBinding()]
    param([Parameter(Mandatory=$true)][string]$AppPackagePath)

    $shell = new-object -com shell.application
    $item = get-item $AppPackagePath
    $zipFilePath = $item.FullName + ".zip"
    
    $directory = $item.Directory.FullName
    Copy-Item $item $zipFilePath
    $manifest = @{ "Name" = "AppManifest.xml" }
    $manifest.Path = Join-Path $directory $manifest.Name
    $manifest.File = $shell.NameSpace($zipFilePath).Items() | ? { $_.Name -eq $manifest.Name }
    $shell.Namespace($directory).CopyHere($manifest.File)
    $manifest.Xml = [xml](get-content $manifest.Path)
    $metadata = @{
        "VersionString" = $manifest.Xml.App.Version
        "ProductId" = $manifest.Xml.App.ProductID
    }


    Remove-Item $zipFilePath
    Remove-Item $manifest.Path

    return $metadata
}

Count lines of code with PowerShell

Today I got a question:

How many lines of code are there in our SharePoint solution?

After a little search, I found that PowerShell is really a nice tool to count lines of code:

I wanted to count lines for different types of code:

  1. Code Behind written in C#, the files have .cs file extension
  2. JavaScript code (except jQuery, angular or knockout frameworks)
  3. PowerShell files (.ps1 and psm1)
  4. Xml files (all the SharePoint .xml files)

Here is the powershell code that counts lines of code:

# go to the solution folder
cd <solution directory>

#count lines in .cs files
ls -include *.cs -recurse | select-string . | measure | select count

#count lines in our .js files
ls -include *.js -recurse `
    -exclude *min.js, jquery*, _*, jsrender*, CamlBuilder*, knockout* `
  | select-string . `
  | measure `
  | select Count

#count lines in our powershell scripts
ls -include *.xml -recurse | select-string . | measure | select count

#count lines in our powershell scripts
ls -include *.ps1, *.psm1 -recurse | select-string . | measure | select count

Just a curious fact, I can’t tell you how many lines of code we have in our solution, but I can reveal the proportions. If I used the flexible box model in css3, it would look like this:

lines of code

There are as many lines of code written in javascript as it is in C#. The main reason that for the big js code base are the SharePoint hosted apps. The PowerShell scripts are as big the javascript code base. Xml files are 4 times bigger than C# code, and it is even bigger than the sum of all lines of code written in C#, JavaScript and PowerShell. It isn’t strange that xml is dominating, almost everything in SharePoint is defined in xml.

Fortunately, there are less cases where you have to write raw xml in Visual Studio 2012/2013 and SharePoint 2013.

How does it look in your project? What language is dominating in your SharePoint project?

Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)

I have had a strange bug. The comment text box in a OOB SharePoint 2013 blog doesn’t appear. It only says: “There are no comments for this post.” In this blog post I’ll tell you how I found the bug and I’ll show you how you can temporarily bring the commenting to life.

comments-not-working-001

I have had luck. While it doesn’t work on the Test Environment, it does actually work on my development machine. The comments text box is rendered as an OnPostRender action in the blog comments display template. After debugging the javascript in hours and comparing the two environments, I just could confirm that displaytemplates are the same. There are two main javascript files that are involved:

  • clienttemplates.js
  • sp.ui.blogs.js

So it must some differences elsewhere. The build versions of the environments are

  • Working Environment:  15.0.4420.1017 (SharePoint 2013 RTM)
  • Not-working Environment: 15.0.4517.1005 (SharePoint 2013 June CU)

No errors are thrown, even on the blog where it doesn’t work. It is because of the permissive try-catch in this function that wraps rendering of the comment text box:

function CallFunctionWithErrorHandling(fn, c, erv, execCtx) {
    if (SPClientRenderer.IsDebugMode(c)) {
        return fn();
    }
    try {
        return fn();
    }
    catch (e) {
        if (c.Errors == null)
            c.Errors = [];
        try {
            e.ExecutionContext = execCtx;
            if (Boolean(SPClientRenderer.AddCallStackInfoToErrors) && typeof execCtx == "object" && null != execCtx) {
                execCtx.CallStack = ULSGetCallstack(CallFunctionWithErrorHandling.caller);
            }
        }
        catch (ignoreErr) { }
        c.Errors.push(e);
        return erv;
    }
}

This is where the error occurs but doesn’t appear in the script console. Here is the error:

ExecutionContext: Object
message: "Syntax error, unrecognized expression: #{B808453A-141A-4091-8467-B6915B8B3E99}-{6C3BF638-43F2-4F12-A297-DEF18635540E}-CommentContainer"
stack: "Error: Syntax error, unrecognized expression: #{B808453A-141A-4091-8467-B6915B8B3E99}-{6C3BF638-43F2-4F12-A297-DEF18635540E}-CommentContainer
    at Error ()
    at Function.st.error (jquery-1.9.1.min.js:4:10926)
    at ft (jquery-1.9.1.min.js:4:17138)
    at wt (jquery-1.9.1.min.js:4:19823)
    at Function.st (jquery-1.9.1.min.js:4:6140)
    at b.fn.extend.find (jquery-1.9.1.min.js:4:20941)
    at b.fn.b.init (jquery-1.9.1.min.js:3:1126)
    at b (jquery-1.9.1.min.js:3:206)
    at /ScriptResource.axd:344:53
    at _foreach (ScriptResource.axd:33:17)"

What? jQuery error? Why?

It turns out that jQuery is used to get the html element for the comments area in the server with June CU, but not in the Server with SharePoint 2013 RTM.

To get the reference to the comments area, it invokes the $get method, which invokes Sys.get which in some cases invokes the jQuery (if present)

$get implementation in SP 2013 June CU

These are the functions which can be found in the SharePoint 2013 June CU (15.0.4517.1005)

$get = $type.getElementById = function DomElement$getElementById(id, element) {
    /// <summary locid="M:J#Sys.UI.DomElement.getElementById">Finds an element by id.</summary>
    /// <param name="id" type="String">The id of the element to find.</param>
    /// <param name="element" domElement="true" optional="true" mayBeNull="true"></param>
    /// <returns domElement="true" mayBeNull="true">The element, or null if it was not found.</returns>
    var e = Function._validateParams(arguments, [
        {name: "id", type: String},
        {name: "element", mayBeNull: true, domElement: true, optional: true}
    ]);
    if (e) throw e;
    return Sys.get("#" + id, element || null);
}

 

        get: function get(selector, context) {
            /// <summary>Queries the DOM for a single DOM element.</summary>
            /// <validationOptions enabled="false" />
            /// <param name="selector">
            /// Selector for a DOM element based on id (#&lt;id>), class (.&lt;name>), or tag name (&lt;tagname>).
            //// More complex selectors may be used if jQuery is loaded.
            /// If multiple elements match the selector, the first one is returned.
            /// </param>
            /// <param name="context" optional="true" mayBeNull="true">An element, array of elements, or Sys.UI.TemplateContext to restrict the query within.</param>
            /// <returns>The matching element, or null if none match.</returns>
            return (context && typeof(context.get) === "function") ?
                context.get(selector) :
                this._find(selector, context, true);
        },

 

_find: function _find(selector, context, single, filter) {
    ...
    else if (window.jQuery) {
        if (!filter) {
            found.push.apply(found, jQuery(selector, context).get());
        }
        if (includeSelf) {
            found.push.apply(found, jQuery(context).filter(selector).get());
        }
    }
    ...
},

older (but working) $get implementation in SharePoint 2013 RTM

These are two versions which can be found in the older SharePoint Release: RTM (15.0.4420.1017)

var $get = Sys.UI.DomElement.getElementById = function Sys$UI$DomElement$getElementById(id, element) {
    /// <summary locid="M:J#Sys.UI.DomElement.getElementById" />
    /// <param name="id" type="String"></param>
    /// <param name="element" domElement="true" optional="true" mayBeNull="true"></param>
    /// <returns domElement="true" mayBeNull="true"></returns>
    var e = Function._validateParams(arguments, [
        {name: "id", type: String},
        {name: "element", mayBeNull: true, domElement: true, optional: true}
    ]);
    if (e) throw e;
    if (!element) return document.getElementById(id);
    if (element.getElementById) return element.getElementById(id);
    var nodeQueue = [];
    var childNodes = element.childNodes;
    for (var i = 0; i < childNodes.length; i++) {
        var node = childNodes[i];
        if (node.nodeType == 1) {
            nodeQueue[nodeQueue.length] = node;
        }
    }
    while (nodeQueue.length) {
        node = nodeQueue.shift();
        if (node.id == id) {
            return node;
        }
        childNodes = node.childNodes;
        for (i = 0; i < childNodes.length; i++) {
            node = childNodes[i];
            if (node.nodeType == 1) {
                nodeQueue[nodeQueue.length] = node;
            }
        }
    }
    return null;
}

It doesn’t even go to Sys.get and doesn’t even try to use jQuery.

The id of the comment are is a combination of two guids and -CommentContainer. jQuery fails to select an element with this id:
This error happens when you try to select this html element with jQuery in the web console:

comments-not-working-002

Temporary solution

The solution is to prevent using jQuery for this element selection. Hopefully new updates of SharePoint will address this issue. Until then we have to tweak the $get method. To do it very carefully, we can copy the old $get function and call it $get_asFoundInRTM and copy the new $get and call it $get_asFoundInJuneCU

The $get function has to rewritten like that:

$get_asFoundInJuneCU = $get

$get = function () {
    var id = arguments[0];
    return /\{/.test(id)
        ? $get_asFoundInRTM.apply(null, arguments)
        : $get_asFoundInJuneCU.apply(null, arguments);
}

This javascript code has to be loaded after two ScriptResource.axd files. Please be very careful if you have to implement this temporary fix. Probably it is better to wait for an official Microsoft bug fix.

 

UPDATE 2014-03-27

I have discovered that in SP1 it is already solved.

Log to ULS using javascript

uls_001

The more javascript code is produced in SharePoint solutions, the more need we have to log information and possible errors to a central logging  place in SharePoint: ULS. This blog post is about logging to ULS from javascript.

For a while ago I read a blog post:

The author @avishnyakov mentions the ability log to ULS from javascript. I want to dive deeper.

ULS.enable = true
ULSOnError("Hello from javascript", location.href, 0);

What this function actually does, is that it calls a web service called _vti_bin/diagnostics.asmx

We can follow the function in the init.debug.js

function ULSOnError(msg, url, line) {
    return ULSSendExceptionImpl(msg, url, line, ULSOnError.caller);
}

ULSOnError invokes ULSSendExceptionImpl:

function ULSSendExceptionImpl(msg, url, line, oCaller) {
    if (Boolean(ULS) && ULS.enable) {
        ULS.enable = false;
        window.onerror = ULS.OriginalOnError;
        ULS.WebServiceNS = "http://schemas.microsoft.com/sharepoint/diagnostics/";
        try {
            ULS.message = msg;
            if (url.indexOf('?') != -1)
                url = url.substr(0, url.indexOf('?'));
            ULS.file = url.substr(url.lastIndexOf('/') + 1);
            ULS.line = line;
            ULS.teamName = "";
            ULS.originalFile = "";
            ULS.callStack = '<stack>\n' + ULSGetCallstack(oCaller) + '</stack>';
            ULS.clientInfo = '<client>\n' + ULSGetClientInfo() + '</client>';
            ULSSendReport(true);
        }
        catch (e) { }
    }
    if (Boolean(ULS) && Boolean(ULS.OriginalOnError))
        return ULS.OriginalOnError(msg, url, String(line));
    else
        return false;
}

ULSSendExceptionImpl invokes ULSSendReport:

function ULSSendReport(async) {
    ULS.request = new XMLHttpRequest();
    ULS.request.onreadystatechange = ULSHandleWebServiceResponse;
    ULS.request.open("POST", ULSGetWebServiceUrl(), async);
    ULS.request.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    ULS.request.setRequestHeader("SOAPAction", ULS.WebServiceNS + "SendClientScriptErrorReport");
    ULS.request.send('<?xml version="1.0" encoding="utf-8"?>' 
        + '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' 
        + '<soap:Body>' 
        + '<SendClientScriptErrorReport xmlns="' + ULS.WebServiceNS + '">' 
        + '<message>' + ULSEncodeXML(ULS.message) + '</message>' 
        + '<file>' + ULSEncodeXML(ULS.file) + '</file>' 
        + '<line>' + String(ULS.line) + '</line>' 
        + '<stack>' + ULSEncodeXML(ULS.callStack) + '</stack>' 
        + '<client>' + ULSEncodeXML(ULS.clientInfo) + '</client>' 
        + '<team>' + ULSEncodeXML(ULS.teamName) + '</team>' 
        + '<originalFile>' + ULSEncodeXML(ULS.originalFile) + '</originalFile>' 
        + '</SendClientScriptErrorReport>' 
        + '</soap:Body>' + '</soap:Envelope>');
}

Alternatives

An alternative way is to create an own handler that is invoked through an ajax request and that implement an own logic for writing logs to ULS. You can see a neat solution provided by Albert Jan-Shot:

Not to be confused with SP.ULS.log

There is another utility function for logging: SP.ULS.log, this function logs messages in a new browser window. In my opinion, it is a substitute for console.log, but the good thing is that you have to manually enable it in order to see:
log-001

 

Logging from an app

If you are developing a sharepoint app, you can log app errors easily by using:

SP.Utilities.Utility.logCustomAppError(
       SP.ClientContext.get_current(), errorMessage);

scriptcs and SharePoint. How SharePoint can benefit?

scriptcs-002

scriptcs-001

Last Saturday I attended Leetspeak. Among many awesome speeches and presentations I discovered scriptcs.

scriptcs

scriptcs lets you write C# code directly in the console, or execute scripts written with just your favourite editor. Please see more about it on the site. What I thought during Justin Rusbatch’s session at Leetspeak:

Can we use scriptcs in SharePoint?

Technically there is no limitations in SharePoint for scriptcs. Any .NET code can be registered, imported and invoked in a console or in a standalone script. Here is the simple code for instantiating a site collection and disposing it:

#r Microsoft.SharePoint;
using Microsoft.SharePoint;
var site = new SPSite("http://dev");
site.Url
site.Dispose();

The code above does not do anything, it is just there to demonstrate how you can register the SharePoint assembly (“Microsoft.SharePoint”) and import it into the script:

using Microsoft.SharePoint;

The example shows even that you in scriptcs no longer need the necessary “boilerplate” (compared to a console application): namespace, Program, Main()… You can just directly write your code.
The rest is the same as in a C# application. The code samples for scriptcs can be any code written in C# for SharePoint, code from custom console applications, from feature receivers, you name it. So my next question is:

How can SharePoint development benefit from scriptcs

I can think about these advantages with scriptcs in SharePoint:

  • Less need of PowerShell. As a developer you can use one language for creating SharePoint solutions and server configurations.
  • You don’t need to rewrite your C# code to PowerShell. It saves time. Often one can see two solutions: one for C#, one for PowerShell, example.
  • You can freely move code from feature receivers to scripts, like timer job installation, without rewriting code, example.
  • You can use scriptcs to discover the SharePoint API, site columns, sites, fields and so on. PowerShell can be used as well. But scriptcs lets you use the same syntax. PowerShell is much different. It is not case sensitive. It often doesn’t throw NullReferenceException, it just doesn’t output anything. So if you use PowerShell as an exploratory tool, then you still will need to verify it in a C# code to verify, that your code works. With scriptcs you can directly copy the code from console directly to your code solution.

Of course, if there are advantages, then it must be some disantvantages.

Shortcomings of scriptcs in SharePoint?

I have found these shortcomings

  • Missing powerful cmdlets for SharePoint (special “shortcuts” for configuration steps of SharePoint like New-SPWeb, Set-SPEnterpriseSearchService…)
  • Missing native functionality in PowerShell for parsing xml, importing and exporting to csv and xml, a very easy way to read and write files on disk.
  • There are already tons of PowerShell scripts written for SharePoint in companies and in the community. Mixing a huge amount of PowerShell with little scriptcs can increase complexity.
  • scriptcs is still new. It is not adopted by Microsoft and maybe will not be approved in your project.

So what do you think about scriptcs and SharePoint?

Would you use scriptcs in your SharePoint project? Leave a comment or send me a tweet.

Вула Чăвашла

VulaCV - Чăвашла вулаттаракан сайт

Discovering SharePoint

And going crazy doing it

Bram de Jager - Coder, Speaker, Author

Office 365, SharePoint and Azure

SharePoint Dragons

Nikander & Margriet on SharePoint

Paul J. Swider - RealActivity

RealActivity is a specialized Microsoft healthcare services and solution advisory firm.

Cameron Dwyer | Office 365, SharePoint, Outlook, OnePlace Solutions

Office 365, SharePoint, OnePlace Solutions & Life's Other Little Wonders

paul.tavares

Me and My doings!

Share SharePoint Points !

By Mohit Vashishtha

Jimmy Janlén "Den Scrummande Konsulten"

Erfarenheter, synpunkter och raljerande om Scrum från Jimmy Janlén

Aryan Nava

| Blockchain | Serverless Architecture | Microservices Architecture | DevOps | AWS Lambda | Teraform |

SPJoel

SharePoint for everyone

SharePointRyan

Ryan Dennis is a SharePoint Solution Architect with a passion for SharePoint and PowerShell

SharePoint 2020

The Vision for a Future of Clarity

Aharoni in Unicode

Treacle tarts for great justice

... And All That JS

JavaScript, Web Apps and SharePoint

blksthl

Mostly what I know about SharePoint - CommunicoCuspis