<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Office365 on dotnet.work</title>
        <link>https://dotnet.work/tags/office365/</link>
        <description>Recent content in Office365 on dotnet.work</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-US</language>
        <managingEditor>dotnet@oles.cloud (Ole Albers)</managingEditor>
        <webMaster>dotnet@oles.cloud (Ole Albers)</webMaster>
        <copyright>Ole Albers</copyright>
        <lastBuildDate>Tue, 13 Dec 2016 12:00:00 +0100</lastBuildDate><atom:link href="https://dotnet.work/tags/office365/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Two Apps at the same time: Deploy SharePoint Add-In to Cloud AND On-Premise</title>
            <link>https://dotnet.work/blog/two-apps-at-the-same-time/</link>
            <pubDate>Tue, 13 Dec 2016 12:00:00 +0100</pubDate><author>dotnet@oles.cloud (Ole Albers)</author>
            <guid>https://dotnet.work/blog/two-apps-at-the-same-time/</guid>
            <description>&lt;img src=&#34;https://dotnet.work/blog/two-apps-at-the-same-time/showBuildConfigurations-300x221_hu_6302578466ea388f.png&#34; alt=&#34;Featured image of post Two Apps at the same time: Deploy SharePoint Add-In to Cloud AND On-Premise&#34; /&gt;&lt;p&gt;What the fuzz is this about?&lt;/p&gt;&#xA;&lt;p&gt;I am not absolutely sure if I am the first one who did this, but it seems at least noone else wrote it down until now. :) We hat a customer who liked our Office365 Provider-Hosted App &amp;ldquo;Mydea&amp;rdquo;, but wanted us to install that on his SharePoint 2013 - Installation. In Germany a lot of companies do not trust the cloud. So we had three options:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Tell the customer this does not work&lt;/li&gt;&#xA;&lt;li&gt;Copy&amp;amp;paste the whole solution and change it so it works on OnPrem&lt;/li&gt;&#xA;&lt;li&gt;Do something else&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The first option - of course - wasn&amp;rsquo;t valid for me. The second would have worked. But I did not want to end up in maintanance hell. Our product is about innovation management. And the most innovative about that is the product itself. We develop agile, adding new features (and sometimes bugs) continuously. We do not want to do that twice.&lt;/p&gt;&#xA;&lt;p&gt;So I ended up on the third option: Changing my solution so it will run in an Office365 - SharePoint &lt;strong&gt;and&lt;/strong&gt; on an On-Premise installation of SharePoint 2013 (or above).&lt;/p&gt;&#xA;&lt;p&gt;Common sense about that path seems to be: &lt;em&gt;That does not work&lt;/em&gt;. But it does. It just is a real bumby road to get there. This also means: You should know the basics. You should have created at least one &lt;abbr title=&#34;Microsoft renamed &#39;Apps&#39; to &#39;Add-Ins&#39; Whenever I write one of those it is just always the same&#34;&gt;Add-In&lt;/abbr&gt; for Office365 and one for SharePoint 2013 or above. I will not explain these steps here (which are complicated enough for local installation). I also cannot help you there in the comments or by mail.&lt;/p&gt;&#xA;&lt;p&gt;There are plenty of documents out there that explain what&amp;rsquo;s needed for this. You should read those, first.&lt;/p&gt;&#xA;&lt;p&gt;If you find this article useful and earn lots of money because of it: Feel free to buy me a beer :)&lt;/p&gt;&#xA;&lt;h3 id=&#34;analyzing-the-differences-what-has-to-be-done&#34;&gt;&lt;a href=&#34;#analyzing-the-differences-what-has-to-be-done&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Analyzing the differences: What has to be done?&#xA;&lt;/h3&gt;&lt;p&gt;I started with an Office365-App and added the possibility to run that App under an OnPrem-Installation, too. But you should be able to go the other way with little modifications.&lt;/p&gt;&#xA;&lt;p&gt;My first step was to create two dummy &amp;ldquo;Hello World&amp;quot;ish Applications. One for O365 and one for an OnPrem-Installation and look at the source, to &amp;ldquo;diff&amp;rdquo; it. These are the conclusions I came around:&lt;/p&gt;&#xA;&lt;p&gt;At most of us use NuGet-Packages, that was the starting point. There are different Packages: You need the following:&lt;/p&gt;&#xA;&lt;p&gt;OnPrem: - AppForSharePointWebToolKit&lt;/p&gt;&#xA;&lt;p&gt;Office 365: - AppForSharePointOnlineWebToolKit - Microsoft.SharePointOnline.CSOM&lt;/p&gt;&#xA;&lt;p&gt;These Packages result in different DLLs with the Prefix &lt;em&gt;&amp;ldquo;Microsoft.SharePoint.Client.*&amp;rdquo;&lt;/em&gt;, but different Versions. OnPrem: - Version 15.xxx Office 365: - Version 16.xxx&lt;/p&gt;&#xA;&lt;p&gt;The Sourcecode of the *.cs - files created by that NuGet-Packages (_SharePointContext.cs_ &amp;amp; _Tokenhelper.cs_) are exactly the same. So no need to change anything there.&lt;/p&gt;&#xA;&lt;p&gt;Finally you usually store your Office365-Apps on Azure, but don&amp;rsquo;t for On-Premise-Installations. This results in different Authentications: OnPrem: - Using Certificates - Using Windows Authentication&lt;/p&gt;&#xA;&lt;p&gt;Office 365: - Using ClientSecret - Using OAuth Authentication&lt;/p&gt;&#xA;&lt;p&gt;These Informations are stored inside the &lt;em&gt;Web.Config&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;before-we-start&#34;&gt;&lt;a href=&#34;#before-we-start&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Before we start&#xA;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Create a new Branch in your repository.&lt;/strong&gt; You never know what can go wrong :)&lt;/p&gt;&#xA;&lt;h3 id=&#34;the-web-project-mvc-most-likely&#34;&gt;&lt;a href=&#34;#the-web-project-mvc-most-likely&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;The Web-Project (MVC most likely)&#xA;&lt;/h3&gt;&lt;h5 id=&#34;creating-different-build-configurations&#34;&gt;&lt;a href=&#34;#creating-different-build-configurations&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Creating different Build configurations&#xA;&lt;/h5&gt;&lt;p&gt;The main purpose if this action was to have just one CodeBase for both versions. So new features or bugfixes have only to be made once. No extra code, no branch, no nothing.&lt;/p&gt;&#xA;&lt;p&gt;So I started by creating new Build Configurations. You can create them using &amp;ldquo;Build - Configuration Manager&amp;rdquo;: &lt;img alt=&#34;Show Build Configurations&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;325px&#34; data-flex-grow=&#34;135&#34; height=&#34;221&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/two-apps-at-the-same-time/showBuildConfigurations-300x221_hu_6302578466ea388f.png&#34; width=&#34;300&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt; &lt;/p&gt;&#xA;&lt;p&gt;Create two Configurations. One for Debug and one for Release. Make sure to copy the Settings from the existing &amp;ldquo;Debug&amp;rdquo;- and &amp;ldquo;Release&amp;rdquo;-Configuration &lt;img alt=&#34;New build configuration&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;331px&#34; data-flex-grow=&#34;138&#34; height=&#34;217&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/two-apps-at-the-same-time/newBuildConfiguration-300x217_hu_48cb9448667d9621.png&#34; width=&#34;300&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;At this point, only do this for your web project and - if you have - any backend-projects that are used by your webproject. We will add others later on, but this way you have the chance to validate every single step:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;Changed build configurations&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;328px&#34; data-flex-grow=&#34;136&#34; height=&#34;219&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/two-apps-at-the-same-time/buildConfigurationShow-300x219_hu_9fb22bccea96f250.png&#34; width=&#34;300&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Now its time to create your config file. Find your web.config, click on it with the right mouse button and select &amp;ldquo;Add config transform&amp;rdquo;. After that you should have a Config file for each configuration&lt;/p&gt;&#xA;&lt;h5 id=&#34;nuget-references&#34;&gt;&lt;a href=&#34;#nuget-references&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Nuget-References&#xA;&lt;/h5&gt;&lt;p&gt;I used the PnP - Packages to develop our O365-Add-In. If you only use the &amp;ldquo;base&amp;rdquo; Packages that come with the Add-In-Solution-Template you might have different packages. Nonetheless you will always have a package &lt;em&gt;&amp;ldquo;AppForSharePointOnlineWebToolKit&amp;rdquo;&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Package-wise the main difference between the O365/OnPrem - road are the Azure- and OAuth-packages that are only on the 365-PnP. Also the Office365 Libraries use Version 16, While OnPrem use Version 15.&lt;/p&gt;&#xA;&lt;p&gt;To be able to keep your application updated no matter what configuration you use, create two dummy projects e.g. &lt;em&gt;dummy365&lt;/em&gt; &amp;amp; &lt;em&gt;dummyOnprem&lt;/em&gt;. It does not matter what kind of projects these are. The only purpose of these projects is that there are always the packages for both O365 and OnPrem in the &lt;em&gt;./packages&lt;/em&gt; - folder.&lt;/p&gt;&#xA;&lt;p&gt;Add the O365-pnp-NuGet-packages to your dummy365 and the 2013-pnp-nuget-package to your dummyOnPrem&lt;/p&gt;&#xA;&lt;p&gt;Now: Before you continue, **make a backup of you .csproj - file. It conains information that will be lost after the next step.&lt;/p&gt;&#xA;&lt;p&gt;Now add the &amp;ldquo;other&amp;rdquo; PnP-Package. If you already have the &lt;em&gt;SharePointPnPCoreOnline&lt;/em&gt;-Package installed. now install the &lt;em&gt;SharePointPnpCore2013&lt;/em&gt; NuGet-Package (and vice-versa)&lt;/p&gt;&#xA;&lt;h5 id=&#34;csproj-changes&#34;&gt;&lt;a href=&#34;#csproj-changes&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;csProj-Changes&#xA;&lt;/h5&gt;&lt;p&gt;You can now diff your csproj - files before and after. Or simply believe my words: There are now two differences. One of them is the &lt;em&gt;OfficeDevPnP.Core&lt;/em&gt; - package. The &lt;em&gt;HintPath&lt;/em&gt; from the O365 contains &lt;em&gt;SharePointPnPCoreOnline&lt;/em&gt;, the &lt;em&gt;HintPath&lt;/em&gt; from the 2013-Version contains &lt;em&gt;SharePointPnpCore2013&lt;/em&gt;. This does not seem to be an issue as both DLLs are identical. Nonetheless we will have a look at it. Just in case.&lt;/p&gt;&#xA;&lt;p&gt;The more interesting detail is the Reference to &lt;em&gt;&amp;ldquo;Microsoft.Online.SharePoint.Client.Tenant&amp;rdquo;&lt;/em&gt;. The Office365 - Version uses Version 16.x and the OnPrem - Version uses 15.x. This is absolutely something we have to care about.&lt;/p&gt;&#xA;&lt;p&gt;Luckily, the csProj allows some conditions. So create the following new lines:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;ItemGroup Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug.OnPrem&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release.OnPrem&amp;#39;&amp;#34;&amp;gt;&#xA;&amp;lt;Reference Include=&amp;#34;Microsoft.Online.SharePoint.Client.Tenant, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL&amp;#34;&amp;gt;&#xA;&amp;lt;HintPath&amp;gt;..\\packages\\SharePointPnPCore2013.2.9.1611.0\\lib\\net45\\Microsoft.Online.SharePoint.Client.Tenant.dll&amp;lt;/HintPath&amp;gt;&#xA;&amp;lt;Private&amp;gt;True&amp;lt;/Private&amp;gt;&#xA;&amp;lt;/Reference&amp;gt;&#xA;&amp;lt;Reference Include=&amp;#34;OfficeDevPnP.Core, Version=2.9.1611.0, Culture=neutral, PublicKeyToken=3751622786b357c2, processorArchitecture=MSIL&amp;#34;&amp;gt;&#xA;&amp;lt;HintPath&amp;gt;..\\packages\\SharePointPnPCore2013.2.9.1611.0\\lib\\net45\\OfficeDevPnP.Core.dll&amp;lt;/HintPath&amp;gt;&#xA;&amp;lt;Private&amp;gt;True&amp;lt;/Private&amp;gt;&#xA;&amp;lt;/Reference&amp;gt;&#xA;&amp;lt;/ItemGroup&amp;gt;&#xA;&#xA;&amp;lt;ItemGroup Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release&amp;#39;&amp;#34;&amp;gt;&#xA;&amp;lt;Reference Include=&amp;#34;Microsoft.Online.SharePoint.Client.Tenant, Version=16.1.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL&amp;#34;&amp;gt;&#xA;&amp;lt;HintPath&amp;gt;..\\packages\\Microsoft.SharePointOnline.CSOM.16.1.5813.1200\\lib\\net45\\Microsoft.Online.SharePoint.Client.Tenant.dll&amp;lt;/HintPath&amp;gt;&#xA;&amp;lt;Private&amp;gt;True&amp;lt;/Private&amp;gt;&#xA;&amp;lt;/Reference&amp;gt;&#xA;&#xA;&amp;lt;Reference Include=&amp;#34;OfficeDevPnP.Core, Version=2.9.1611.0, Culture=neutral, PublicKeyToken=3751622786b357c2, processorArchitecture=MSIL&amp;#34;&amp;gt;&#xA;&amp;lt;HintPath&amp;gt;..\\packages\\SharePointPnPCoreOnline.2.9.1611.0\\lib\\net45\\OfficeDevPnP.Core.dll&amp;lt;/HintPath&amp;gt;&#xA;&amp;lt;Private&amp;gt;True&amp;lt;/Private&amp;gt;&#xA;&amp;lt;/Reference&amp;gt;&#xA;&amp;lt;/ItemGroup&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Do not just copy/paste the content from here!&lt;/strong&gt; Use the lines from within &lt;strong&gt;your&lt;/strong&gt; csProj-File instead! Versions will change over time. And when you read these lines, my version used might already be outdated.&lt;/p&gt;&#xA;&lt;p&gt;As a last step, remove the original lines from within the main &lt;em&gt;ItemGroup&lt;/em&gt; containing these two libraries.&lt;/p&gt;&#xA;&lt;p&gt;Well done. You should now try to rebuild your solution on all your four Build configurations, where the OnPrem-Configurations should create a &lt;em&gt;Microsoft.Online.SharePoint.Client.Tenant.dll&lt;/em&gt; with Version 15 in your bin-directory and the Office365-Version should create a V16-dll. If you encounter a problem try to unload and reload the projects.&lt;/p&gt;&#xA;&lt;p&gt;Please be advised: I am not sure what happens if you update one of those two Nuget-Packages. You might have to modify your csproj-file again&lt;/p&gt;&#xA;&lt;h5 id=&#34;webconfig&#34;&gt;&lt;a href=&#34;#webconfig&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Web.Config&#xA;&lt;/h5&gt;&lt;p&gt;Now its time to modify your Web.Configs.&lt;/p&gt;&#xA;&lt;p&gt;Add the following lines just before the closing &lt;em&gt;&amp;quot;&lt;/configuration&gt;&amp;rdquo;&lt;/em&gt; section into your *.OnPrem.config - files:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;runtime&amp;gt;&#xA;&amp;lt;assemblyBinding xmlns=&amp;#34;urn:schemas-microsoft-com:asm.v1&amp;#34;&amp;gt;&#xA;&amp;lt;dependentAssembly xdt:Transform=&amp;#34;Replace&amp;#34; xdt:Locator=&amp;#34;Condition(./\_defaultNamespace:assemblyIdentity/@name=&amp;#39;Microsoft.Online.SharePoint.Client.Tenant&amp;#39;)&amp;#34;&amp;gt;&#xA;&amp;lt;assemblyIdentity name=&amp;#34;Microsoft.Online.SharePoint.Client.Tenant&amp;#34; publicKeyToken=&amp;#34;71e9bce111e9429c&amp;#34; culture=&amp;#34;neutral&amp;#34; /&amp;gt;&#xA;&amp;lt;bindingRedirect oldVersion=&amp;#34;0.0.0.0-15.0.0.0&amp;#34; newVersion=&amp;#34;15.0.0.0&amp;#34; /&amp;gt;&#xA;&amp;lt;/dependentAssembly&amp;gt;&#xA;&amp;lt;/assemblyBinding&amp;gt;&#xA;&amp;lt;/runtime&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As before: If at time of reading, the most current version is not 15.0, but 15.1 or higher replace the version numbers instead.&lt;/p&gt;&#xA;&lt;p&gt;Now it is time to modify your &amp;ldquo;normal&amp;rdquo; Configs for Debug and Release&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;runtime&amp;gt;&#xA;&amp;lt;assemblyBinding xmlns=&amp;#34;urn:schemas-microsoft-com:asm.v1&amp;#34;&amp;gt;&#xA;&amp;lt;dependentAssembly xdt:Transform=&amp;#34;Replace&amp;#34; xdt:Locator=&amp;#34;Condition(./\_defaultNamespace:assemblyIdentity/@name=&amp;#39;Microsoft.Online.SharePoint.Client.Tenant&amp;#39;)&amp;#34;&amp;gt;&#xA;&amp;lt;assemblyIdentity name=&amp;#34;Microsoft.Online.SharePoint.Client.Tenant&amp;#34; publicKeyToken=&amp;#34;71e9bce111e9429c&amp;#34; culture=&amp;#34;neutral&amp;#34; /&amp;gt;&#xA;&amp;lt;bindingRedirect oldVersion=&amp;#34;0.0.0.0-16.1.0.0&amp;#34; newVersion=&amp;#34;16.1.0.0&amp;#34; /&amp;gt;&#xA;&amp;lt;/dependentAssembly&amp;gt;&#xA;&amp;lt;/assemblyBinding&amp;gt;&#xA;&amp;lt;/runtime&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is not 100% necessary at this time as these values should already be in the main Web.Config, but this makes sure it still works if that changes. Again: Check the version number.&lt;/p&gt;&#xA;&lt;h3 id=&#34;authentication&#34;&gt;&lt;a href=&#34;#authentication&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Authentication&#xA;&lt;/h3&gt;&lt;p&gt;Your O365 - Config Files should still contain something like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;appSettings&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientValidationEnabled&amp;#34; value=&amp;#34;true&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;UnobtrusiveJavaScriptEnabled&amp;#34; value=&amp;#34;true&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientId&amp;#34; value=&amp;#34;aaaaaaaa-beef-face-bbbb-cchcchcchcch&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientSecret&amp;#34; value=&amp;#34;lsdschnabbeldiwuppsfkjashriuae=&amp;#34; /&amp;gt;&#xA;&amp;lt;/appSettings&amp;gt;&#xA;`now your OnPrem-configs looks a little bit different:`&#xA;&amp;lt;appSettings&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientValidationEnabled&amp;#34; value=&amp;#34;true&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;UnobtrusiveJavaScriptEnabled&amp;#34; value=&amp;#34;true&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientId&amp;#34; value=&amp;#34;aaaaaaaa-beed-face-bbbb-cchcchcchcch&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientSigningCertificatePath&amp;#34; value=&amp;#34;C:\\Certs\\myCert.pfx&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientSigningCertificatePassword&amp;#34; value=&amp;#34;p@ssw0rd&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;IssuerId&amp;#34; value=&amp;#34;bbbbbbbb-beef-face-bbbb-cchcchcchcch&amp;#34; /&amp;gt;&#xA;&amp;lt;/appSettings&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The main difference here is that you don&amp;rsquo;t just use a ClientId/ClientSecret - Combination for an OnPrem-Installation but have to use a Certificate. I will not describe here how to obtain it. It is just the &amp;ldquo;normal&amp;rdquo; OnPrem-procedure for provider hosted apps. Also be aware that the IssuerId is &lt;strong&gt;not&lt;/strong&gt; the ClientId.&lt;/p&gt;&#xA;&lt;p&gt;If you need help on this part: There are plenty of documents about this. For example on&lt;a class=&#34;link&#34; href=&#34;https://msdn.microsoft.com/en-us/library/office/fp179901.aspx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;MSDN&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;backend-webjobs-and-other-projects-that-talk-directly-to-sharepoint&#34;&gt;&lt;a href=&#34;#backend-webjobs-and-other-projects-that-talk-directly-to-sharepoint&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Backend, Webjobs and other projects that talk directly to SharePoint&#xA;&lt;/h3&gt;&lt;h5 id=&#34;appconfig&#34;&gt;&lt;a href=&#34;#appconfig&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;App.Config&#xA;&lt;/h5&gt;&lt;p&gt;If you have any other Projects than the Web Project and the AddIn, you might have to do some extra steps. For example if you use a backend-project, you have to modify that, too. Ignore this chapter if you don&amp;rsquo;t have any additional projects.&lt;/p&gt;&#xA;&lt;p&gt;But if you have any console application (like Azure WebJobs) you have to modify those configs, too. Sadly. Config-transform does not work out of the box with App.Config - files. But there is a way to change that.&lt;/p&gt;&#xA;&lt;p&gt;First: Create your Config Files manually. So select Add - New Item and select &amp;ldquo;&lt;em&gt;Application Config File&lt;/em&gt;&amp;rdquo;. Name it &lt;em&gt;App.OnPrem.config&lt;/em&gt;. Now open the csProj-File with Notepad. Look for an &lt;em&gt;ItemGroup&lt;/em&gt; containing the App.Config. There already should be an &lt;em&gt;App.Debug.config&lt;/em&gt; and &lt;em&gt;App.Release.config&lt;/em&gt; with a &amp;ldquo;&lt;em&gt;DependentUpon&lt;/em&gt;&amp;rdquo; - Attribute. Just copy that attribute to your newly created files. So that you end with something like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;ItemGroup&amp;gt;&#xA;&amp;lt;None Include=&amp;#34;App.config&amp;#34; /&amp;gt;&#xA;&amp;lt;None Include=&amp;#34;App.Debug.config&amp;#34;&amp;gt;&#xA;&amp;lt;DependentUpon&amp;gt;App.config&amp;lt;/DependentUpon&amp;gt;&#xA;&amp;lt;/None&amp;gt;&#xA;&amp;lt;None Include=&amp;#34;App.Debug.OnPrem.config&amp;#34; &amp;gt;&#xA;&amp;lt;DependentUpon&amp;gt;App.config&amp;lt;/DependentUpon&amp;gt;&#xA;&amp;lt;/None&amp;gt;&#xA;&amp;lt;None Include=&amp;#34;App.Release.OnPrem.config&amp;#34; &amp;gt;&#xA;&amp;lt;DependentUpon&amp;gt;App.config&amp;lt;/DependentUpon&amp;gt;&#xA;&amp;lt;/None&amp;gt;&#xA;&amp;lt;None Include=&amp;#34;App.Release.config&amp;#34;&amp;gt;&#xA;&amp;lt;DependentUpon&amp;gt;App.config&amp;lt;/DependentUpon&amp;gt;&#xA;&amp;lt;/None&amp;gt;&#xA;&amp;lt;/ItemGroup&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After that all your OnPrem-Configs should be displayed as children from App.Config in Visual Studio (2015). Now transform should work. You can check your csproj - File. If there is something like &lt;em&gt;&amp;lt;UsingTask TaskName=&amp;ldquo;TransformXml&amp;rdquo; ../&amp;gt;&lt;/em&gt; in it you are ready to go. If not, you are probably using an older Visual Studio version. I would not advise it, but you can go with it, but have to do some extra steps: &lt;a class=&#34;link&#34; href=&#34;http://harrewijnen.net/app-config-xdt-transforms/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;XDT Transforms for older VS Versions&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Now its the same fun again with the config files as before. So add the same stuff into the App.*.config - files as you have done with the web.configs. In addtion add the transform Property to the configuration tag, so it looks like this: &lt;configuration xmlns:xdt=&#34;http://schemas.microsoft.com/XML-Document-Transform&#34;&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;test-what-you-have-done-until-now&#34;&gt;&lt;a href=&#34;#test-what-you-have-done-until-now&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Test what you have done until now&#xA;&lt;/h3&gt;&lt;p&gt;Now you should build your Solution for all four configurations. Check if all DLLs where created correctly for the O365 and OnPrem-Configurations. Deploy your application still with the O365 - Settings. Everything should look like before.&lt;/p&gt;&#xA;&lt;h3 id=&#34;changes-on-the-web-project&#34;&gt;&lt;a href=&#34;#changes-on-the-web-project&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Changes on the Web Project&#xA;&lt;/h3&gt;&lt;p&gt;Now it is time to modify your main SharePoint-Project.&lt;/p&gt;&#xA;&lt;p&gt;First of all: Add your SharePoint-Project to the build configurations. The good thing is: This time you don&amp;rsquo;t have to care about the configs. There will most likely be an app.config in your SharePoint-project, but you can just ignore it, because there are no real references in this project.&lt;/p&gt;&#xA;&lt;h5 id=&#34;sharepoint---url&#34;&gt;&lt;a href=&#34;#sharepoint---url&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;SharePoint - URL&#xA;&lt;/h5&gt;&lt;p&gt;The (nearly) final step is to put the right SharePoint-URL to your AddIn-Project depending on your Configuration. The simple way is to just enter the right URL each time you start debugging. The more complex (but better) way is to go the same way as you did with the MVC (Server) part. To do this, enter your Build-Configuration Settings again and set &amp;ldquo;&lt;em&gt;Debug.OnPrem&lt;/em&gt;&amp;rdquo; and &amp;ldquo;&lt;em&gt;Release.OnPrem&lt;/em&gt;&amp;rdquo; for your AddIn-Project.&lt;/p&gt;&#xA;&lt;p&gt;The URL is stored in the user-settings instead of the project settings. But you can use the same magic to make a conditional path there. Open the file YourApp.csproj.user and add the condition to the &amp;ldquo;SharePointSiteUrl&amp;rdquo; - entry:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;PropertyGroup&amp;gt;&#xA;&amp;lt;SharePointSiteUrl Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug.OnPrem&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release.OnPrem&amp;#39;&amp;#34;&amp;gt;http://myDevMachine:10000/sites/Dev\_Ole/&amp;lt;/SharePointSiteUrl&amp;gt;&#xA;&amp;lt;SharePointSiteUrl Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release&amp;#39;&amp;#34;&amp;gt;https://my365AppName.sharepoint.com/sites/dev-ole/&amp;lt;/SharePointSiteUrl&amp;gt;&#xA;&amp;lt;/PropertyGroup&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;IF you want you can also simply delete the user-file and put these values into your main .csproj. Sadly this cannot be loaded &amp;ldquo;on the fly&amp;rdquo; by switching your Build configuration . You have to unload and reload your project for this setting to be re-read. This is no issue when deploying your solution using an automated build (like tfs online), but while debugging locally.&lt;/p&gt;&#xA;&lt;h5 id=&#34;target-office-version--sharepoint-url&#34;&gt;&lt;a href=&#34;#target-office-version--sharepoint-url&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Target office version &amp;amp; SharePoint-URL&#xA;&lt;/h5&gt;&lt;p&gt;The csproj - file contains an entry called &amp;ldquo;&lt;em&gt;TargetOfficeVersion&lt;/em&gt;&amp;rdquo; which should contain the value &amp;ldquo;16.1&amp;rdquo;. Just like before we need to modify this using conditional values.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;TargetOfficeVersion Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release&amp;#39;&amp;#34;&amp;gt;16.1&amp;lt;/TargetOfficeVersion&amp;gt;&#xA;&amp;lt;TargetOfficeVersion Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug.OnPrem&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release.OnPrem&amp;#39;&amp;#34;&amp;gt;15.0&amp;lt;/TargetOfficeVersion&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can validate this setting while selecting the properties of the project and display the &amp;ldquo;Sharepoint&amp;rdquo;-Tab. Under &amp;ldquo;Target Sharepoint version&amp;rdquo; it should say &amp;ldquo;SharePoint 2013&amp;rdquo; if 15.0 is used or &amp;ldquo;SharePoint Online&amp;rdquo; if 16.1 is used.&lt;/p&gt;&#xA;&lt;h5 id=&#34;authentication-1&#34;&gt;&lt;a href=&#34;#authentication-1&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Authentication&#xA;&lt;/h5&gt;&lt;p&gt;Office365 uses OAuth for Authentication. For SharePoint 2013 you have to use Windows Authentication instead. As I wrote before: There are a few documents out there explaining the Certificate-Part. But you also have to tell your project to use Windows Authentication. Again we use the same conditions like before, but this time use it for the IISExpressAuth:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;IISExpressWindowsAuthentication Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug.OnPrem&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release.OnPrem&amp;#39;&amp;#34;&amp;gt;enabled&amp;lt;/IISExpressWindowsAuthentication&amp;gt;&#xA;&amp;lt;IISExpressWindowsAuthentication Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release&amp;#39;&amp;#34;&amp;gt;disabled&amp;lt;/IISExpressWindowsAuthentication&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h5 id=&#34;appmanifest&#34;&gt;&lt;a href=&#34;#appmanifest&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;AppManifest&#xA;&lt;/h5&gt;&lt;p&gt;The Appmanifest does not allow any conditional entries. That&amp;rsquo;s why we have to create a copy of it and do the conditional stuff inside the csproj file. So first create a copy called AppManifest.OnPrem.xmlns&lt;/p&gt;&#xA;&lt;p&gt;In that file change the &amp;ldquo;SharePointMinVersion&amp;rdquo; from &lt;em&gt;16.0.0.0&lt;/em&gt; to &lt;em&gt;15.0.0.0&lt;/em&gt; in the &amp;ldquo;&lt;em&gt;App&lt;/em&gt;&amp;quot;-Section.&lt;/p&gt;&#xA;&lt;p&gt;Now it is finally time again to modify the csproj - File. You should be used to it by now :)&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;ItemGroup Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug.OnPrem&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release.OnPrem&amp;#39;&amp;#34;&amp;gt;&#xA;&amp;lt;AppManifestFile Include=&amp;#34;AppManifest.OnPrem.xml&amp;#34;&amp;gt;&#xA;&amp;lt;SubType&amp;gt;Designer&amp;lt;/SubType&amp;gt;&#xA;&amp;lt;/AppManifestFile&amp;gt;&#xA;&amp;lt;/ItemGroup&amp;gt;&#xA;&amp;lt;ItemGroup Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release&amp;#39;&amp;#34;&amp;gt;&#xA;&amp;lt;AppManifestFile Include=&amp;#34;AppManifest.xml&amp;#34;&amp;gt;&#xA;&amp;lt;SubType&amp;gt;Designer&amp;lt;/SubType&amp;gt;&#xA;&amp;lt;/AppManifestFile&amp;gt;&#xA;&amp;lt;/ItemGroup&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; &lt;/p&gt;&#xA;&lt;h2 id=&#34;things-to-mention-on-v-150-sharepoint-2013&#34;&gt;&lt;a href=&#34;#things-to-mention-on-v-150-sharepoint-2013&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Things to mention on V 15.0 (SharePoint 2013)&#xA;&lt;/h2&gt;&lt;p&gt;While most of the code works on Version 15.0 as well on 16.1, there are some minor differences between these two. The following issues appeared on my project: - FieldUserValue has no Property &amp;ldquo;Email&amp;rdquo; - Microsoft.Client.SharePoint.Folder has no &amp;ldquo;Exists()&amp;rdquo; Both work on 16.1 but not on 15.0. So you have to write your own code to get around this issue.&lt;/p&gt;&#xA;&lt;h3 id=&#34;custom-compiler-symbols&#34;&gt;&lt;a href=&#34;#custom-compiler-symbols&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Custom Compiler Symbols&#xA;&lt;/h3&gt;&lt;p&gt;Because of the differences between V16 and V15 you might want to have custom code depending on your configuration. Just like the DEBUG - Symbol you can add your custom Symbol for the OnPrem-Configurations. Just select the properties of each project you need that symbol in, select the Build - tab and into &amp;ldquo;_Conditional compilation symbol_s&amp;rdquo; enter &amp;ldquo;&lt;em&gt;ONPREM&lt;/em&gt;&amp;rdquo; (or whatever you like):&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;symbol&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;612px&#34; data-flex-grow=&#34;255&#34; height=&#34;278&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/two-apps-at-the-same-time/symbol_hu_350c26df9784dc31.png&#34; width=&#34;710&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Afterwards you can use the following code:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#if OnPrem&#xA;var userMail=GetMailFromUser(fieldUserValue); &#xA;#else &#xA;var userMail=FieldUserValue.Email;&#xA;#endif&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;final-thoughts&#34;&gt;&lt;a href=&#34;#final-thoughts&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Final thoughts&#xA;&lt;/h2&gt;&lt;p&gt;You are done now. Just keep in mind: If you use any Azure-connections (e.g. for caching, insights, blob-storage) you will have to handle that, too if you need to get rid of any external connection. The custom Compiler Symbols should help you with that task&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>It&#39;s because they at Microsoft hate web developers</title>
            <link>https://dotnet.work/blog/its-because-they-at-microsoft-hate-web-developers/</link>
            <pubDate>Tue, 14 Jun 2016 12:00:00 +0200</pubDate><author>dotnet@oles.cloud (Ole Albers)</author>
            <guid>https://dotnet.work/blog/its-because-they-at-microsoft-hate-web-developers/</guid>
            <description>&lt;p&gt;That remark isn&amp;rsquo;t mine, it is from StackOverflow. :)&lt;/p&gt;&#xA;&lt;p&gt;I had an issue that my Office365-App did not work correctly on the machine of ONE user. Sadly though that user was the Microsoft validation crew. I was unable to reproduce the error and did not even see any clue in the Server logs. Everything seemed to work fine.&lt;/p&gt;&#xA;&lt;p&gt;Finally I managed to reproduce the error. It only happened under the following conditions: 1. Internet Explorer 11; IE - what else :) 2. Caching in IE has to be on &amp;ldquo;Automatic&amp;rdquo; 3. Developer Console MUST NOT be open 3.1. In fact: Even if you open it and close it afterwards, the error does not appear anymore 4. I had to retract/reinstall the app each time to check this behaviour which took about 10 minutes every time&lt;/p&gt;&#xA;&lt;p&gt;I had issues with console on older IEs before, but at least angular uses some magic, so that issue is resolved. Nearly all questions in the web combining IE and console repeat the solution that you may not use &amp;ldquo;console.log()&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;But the real issue was: Caching. IE - in its wisdom - decided that the API-Call that returns the installation state should be cached. That cached value always responded that the app is not installed, even if it was. So the user kept receiving the &amp;ldquo;please install&amp;rdquo; - Page.&lt;/p&gt;&#xA;&lt;p&gt;Any other browser (Chrome, Firefox, &amp;hellip;) doesn&amp;rsquo;t cache these calls. And the IE doesn&amp;rsquo;t either when you open the Developer Console (what you do if you want to debug an application) which makes it really hard to track that error.&lt;/p&gt;&#xA;&lt;p&gt;So the solution is to make sure the call isn&amp;rsquo;t cached using No-Cache-Headers or just by adding a random value to the target address. And of course resist the urge to display a reminder to use another browser. That could be bad for the validation results :)&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
