<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="www.w3.org/2005/Atom" xmlns:sy="purl.org/rss/1.0/modules/syndication/" xmlns:dc="purl.org/dc/elements/1.1/" xmlns:content="purl.org/rss/1.0/modules/content/" xmlns:wfw="wellformedweb.org/CommentAPI/" xmlns:slash="purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Experiments With Code</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/dream_in_code/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/dream_in_code/feed.xml</link>
    <description>New learning while working</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:19:20 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Deploying Microsoft Bot Framework app in Google Cloud!</title>
      <link>https://docs.microsoft.com/archive/blogs/dream_in_code/deploying-microsoft-bot-framework-app-in-google-cloud</link>
      <pubDate>Wed, 14 Mar 2018 17:38:03 GMT</pubDate>
      <dc:creator><![CDATA[Mayank MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dream_in_code/?p=175</guid>
      <description><![CDATA[Microsoft has provided a great framework for creating chat bots. If you are coming from a Windows...]]></description>
      <content:encoded><![CDATA[Microsoft has provided a <a href="botframework.com">great framework </a>for creating chat bots. If you are coming from a Windows background, you would typically create one in .NET Framework and deploy it to an Azure App Service since Visual Studio provides a really seamless way to deploy to Azure. But can you do the same in <a href="https://cloud.google.com/">Google Cloud Platform</a> (GCP)? Let's begin the adventure!

If you don't have a Google Cloud account, sign up for a <a href="https://cloud.google.com/free/">free trial</a> which gives you $300 to spend over a year. Once you are done signing up, open up the <a href="https://console.cloud.google.com">Google Cloud Console</a>. (Note - All the features that we will explore here can be done via CLI or API calls. But for sake of simplicity we will use the UI provided by Google).

GCP provides multiple ways to host your app - <em>App Engine Standard, App Engine Flexible, Compute Engine, Kubernetes Engine</em> etc. App Engine and Kubernetes Engine are the PaaS offerings from GCP while Compute Engine is the IaaS one. We will use the <strong>Compute Engine</strong> as our bot will be developed in .NET 4.6 which is not a runtime offered by App Engine.

We begin with creating a Project in GCP. Think of it as the equivalent of subscription in Azure. All the resources that we will create will come under this project. GCP also has a nice feature of Service Accounts which allows us to add Identity to any resource that we will create. Service Accounts allow us to talk to any of the myriad services provided by GCP (like Google Cloud Storage) without the need of additional authentication. Everything is handled seamlessly without we having to write a single line of code.

Although all projects come with a default service account, we will follow the recommended approach and create a custom one to use in our project.

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/image153.png"><img width="804" height="740" class="alignnone wp-image-185 size-full" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/03/image153.png" /></a>

Next we will create a Virtual Network a.k.a VPC in GCP lingo. It's a typical exercise where you provide region and subnet configuration in CIDR blocks.

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture.png"><img width="591" height="860" class="alignnone wp-image-205 size-full" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture.png" /></a>

Next we will create a VM running Windows Server 2016. To do this we go to Compute Engine and fill in the details. We will make sure that we have selected the Service Account and VPC that we have created earlier.

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture1.png"><img width="577" height="863" class="alignnone wp-image-215 size-full" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture1.png" /></a> <a href="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture11.png"><img width="590" height="863" class="alignnone wp-image-225 size-full" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture11.png" /></a>

This completes the infrastructure setup. Next we will configure Visual Studio to allow seamless integration with GCP. To do this we will install a Visual Studio Extension called "<strong>Google Cloud Tools for Visual Studio</strong>".

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture2.png"><img width="1180" height="818" class="alignnone wp-image-235 size-full" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture2.png" /></a>

After we install the extension and sign in with our Google account, we get a host of features inside Visual Studio.

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture3.png"><img width="634" height="1284" class="alignnone wp-image-245 size-full" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture3.png" /></a>

Our bot will be a simple bot which asks the user if they want to upload an image to a Google Cloud Storage Bucket or view the previously uploaded ones. The entire flow will be like this:

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/blog.gif"><img width="1902" height="1001" class="alignnone wp-image-255 size-full" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/03/blog.gif" /></a>

To access the Google Cloud APIs, we will install the Nuget package "Google.Apis" and "Google.Cloud.Storage.V1". This allows access to Google Storage APIs which we will use to create storage buckets and upload files in them.

You can find the entire source code here - <a href="https://github.com/mayankthebest/ms-bot-on-gcp">https://github.com/mayankthebest/ms-bot-on-gcp</a>

<script src="https://gist.github.com/mayankthebest/476532f12f45834c80fc68eb3067a3f3.js"></script>

Now that we have completed developing our bot, let's deploy it on GCP. Instinctively we right-click on our project in Visual Studio and we get a nice little UI -&gt; "Publish to Google Cloud". Voila!

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture4.png"></a><a href="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture4.png"><img width="1920" height="1030" class="alignnone wp-image-265 size-full" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture4.png" /></a>

&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture12.png"><img width="627" height="476" class="alignnone size-full wp-image-275" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/03/Untitled-picture12.png" /></a>

And we are done. This publish mechanism uses Web Deploy to deploy the site but we can use any other method like FTP if it suits us.

Google Cloud Platform is rapidly developing and getting better day-by-day. It has tight integration with Google services which used and loved by millions of people around the world. And now that Google has provided such great tools for .NET developers, there has been no better time to give GCP a try.

What has your been your experience using GCP? Sound off in the comments below.]]></content:encoded>
    </item>
    <item>
      <title>Creating custom middleware for ASP.NET Core</title>
      <link>https://docs.microsoft.com/archive/blogs/dream_in_code/creating-custom-middleware-for-asp-net-core</link>
      <pubDate>Tue, 22 Nov 2016 08:54:16 GMT</pubDate>
      <dc:creator><![CDATA[Mayank MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dream_in_code/?p=165</guid>
      <description><![CDATA[ASP.NET Core provides a great flexibility to interrupt the HTTP request handling pipeline and...]]></description>
      <content:encoded><![CDATA[ASP.NET Core provides a great flexibility to interrupt the HTTP request handling pipeline and customize it. The customization is done by something called as "Middleware". There are tons of ready-made middleware available as Nuget packages. Even the MVC middleware is available as a Nuget package and is by default part of all ASP.NET Core project templates. But sometimes these Nugets do not solve our purpose and we need to create our own middleware. In this post we can see how we can achieve the same.

Middleware work by interrupting the HTTP pipeline and processing the <code>HttpContext</code> object. After it is done processing, the middleware should hand over the context to the next middleware in pipeline. This is achieved by <code>RequestDelegate</code> object which lives in the <code>Microsoft.AspNetCore.Http </code> namespace.  The middleware should also have a Invoke method which takes in a <code>HttpContext</code> and then hands it to next method in pipeline. A complete class is shown below. It interrupts all Http request and writes "Hello from Middleware" to it.

<code>public class GreetingMiddleware
{
private readonly RequestDelegate _next;
public VamMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
await httpContext.Response.WriteAsync("Hello from Middleware");
await _next.Invoke(httpContext);
}
}</code>

To use this middleware, in your <code>Configure</code> method of your <code>Startup.cs</code> class, write <code>app.UseMiddleware&lt;GreetingMiddleware&gt;()</code> . To make our middleware even more friendly to use, we can write an Extension method to it.

<code>public static class GreetingExtensions
{
public static IApplicationBuilder UseGreeting(this IApplicationBuilder builder)
{
return builder.UseMiddleware&lt;GreetingMiddleware&gt;();
}
}</code>

Now we can use it easily as <code>app.UseGreeting()</code> . Enjoy!]]></content:encoded>
    </item>
    <item>
      <title>Creating a Remote App in Microsoft Azure</title>
      <link>https://docs.microsoft.com/archive/blogs/dream_in_code/creating-a-remote-app-in-microsoft-azure</link>
      <pubDate>Mon, 08 Feb 2016 01:52:00 GMT</pubDate>
      <dc:creator><![CDATA[Mayank MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dream_in_code/2016/02/08/creating-a-remote-app-in-microsoft-azure/</guid>
      <description><![CDATA[According to MSDN, &ldquo;Azure RemoteApp brings the functionality of the on-premises Microsoft...]]></description>
      <content:encoded><![CDATA[<div>According to <a href="https://azure.microsoft.com/en-us/documentation/articles/remoteapp-whatis/">MSDN</a>, &ldquo;Azure RemoteApp brings the functionality of the on-premises Microsoft RemoteApp program, backed by Remote Desktop Services, to Azure. Azure RemoteApp helps you provide secure, remote access to applications from many different user devices. Azure RemoteApp basically hosts non-persistent Terminal Server sessions in the cloud, and you get to use them and share them with your users.&rdquo;</div>
<div><br />
<div><span style="font-size: large;">Create a template image</span></div>
<div>&nbsp;</div>
<div>You have two options to create an OS template image which will then be used to host your RemoteApps &ndash; difficult and easy. Let&rsquo;s look at the difficult way first.</div>
<div>To create an image, perform the following steps:</div>
<div>1. Locate a Windows Server 2012 R2 DVD or ISO image.</div>
<div>2. Create a VHD file. (VHDX files [Hyper-V virtual hard drives] are not currently supported).</div>
<div>3. The VHD must not be a generation 2 virtual machine.</div>
<div>4. The VHD can be either fixed-size or dynamically expanding. A dynamically expanding VHD is recommended because it takes less time to upload to Azure than a fixed-size VHD file.</div>
<div>5. The disk must be initialized using the Master Boot Record (MBR) partitioning style. The GUID partition table (GPT) partition style is not supported.</div>
<div>6. The VHD must contain a single installation of Windows Server 2012 R2. It can contain multiple volumes, but only one that contains an installation of Windows.</div>
<div>7. The image size should be a multiple of MBs. If you try to upload an image that is not an exact multiple, the upload will fail.</div>
<div>8. The image size must be 127 GB or smaller.</div>
<div>9. Install Windows Server 2012 R2.</div>
<div>10. Install the Remote Desktop Session Host (RDSH) role and the Desktop Experience feature.</div>
<div>11. The Remote Desktop Connection Broker role must not be installed.</div>
<div>12. Install additional features required by your applications.</div>
<div>13. Install and configure your applications.</div>
<div>14. Perform any additional Windows configurations required by your applications.</div>
<div>15. Disable the Encrypting File System (EFS).</div>
<div>16. REQUIRED: Install KB 2977219 on your image. This KB is required for all Azure RemoteApp template images. Uploading your image will fail if you do not install this KB.</div>
<div>17. SYSPREP the image using the parameters <strong>/oobe /generalize /shutdown</strong> (DO NOT use the<strong> /mode:vm</strong> parameter).</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div>
<div>Thankfully, Microsoft has provided an easy way too to create the template image.</div>
<div>1. In the Azure Portal, go to the Virtual Machines blade and click on the option create a new virtual machine.</div>
<div>2. Select an image of Windows Server 2012 R2 Datacenter from Gallery. This image already contains all the pre-requisites installed and ready to go.</div>
<div>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/2727.1.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/2727.1.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/2727.1.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/2727.1.png" alt="" border="0" /></a></div>
<div>3. Proceed through the steps of the Wizard to create the VM. It does not really matter what options you choose here as we will be deleting this VM shortly.</div>
<div>4. Once the VM is provisioned and ready (this may take a significant amount of time), log in to the VM and start installing the apps that you need.</div>
<div>5. After you have installed the apps, <strong>make sure that you &ldquo;Pin&rdquo; them to the Start Screen</strong>. This is very essential as we will be using the apps present on Start screen as Remote Apps.</div>
<div>6. Once all the apps are installed and required configuration is done, we now to need to SYSPREP the VM. This will create an OS image with all the software installed and ready to go. To SYSPREP the image, Microsoft has provided a handy desktop link to the PowerShell file which will start the SYSPREP called &ldquo;<strong>ValidateAzureRemoteAppImage.ps1</strong>&rdquo;. Double click on that and answer &ldquo;Y&rdquo; to the confirmation prompt.</div>
<div>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/3058.2.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/3058.2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/3058.2.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/3058.2.png" alt="" border="0" /></a></div>
<div>7. The process to start the SYSPREP will initiate and the VM will now shut down. After the VM has shut down completely, use the Azure portal to capture the image of your virtual machine.</div>
<div>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5852.3.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5852.3.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5852.3.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5852.3.png" alt="" border="0" /></a></div>
<div>8. This will open up a prompt. Confirm that you have run SYSPREP.</div>
<div>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/3755.4.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/3755.4.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/3755.4.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/3755.4.png" alt="" border="0" /></a></div>
<div>9. This will create a new image in your Virtual Machines tab in Azure Portal. We will be using this image to create our RemoteApp.</div>
<br /> <br />
<div><span style="font-size: large;">Add the Disk Image to RemoteApp image</span></div>
<div>&nbsp;&nbsp;</div>
<div>1. Use the Remote Apps tab of Azure Portal to navigate to Template Images tab.</div>
<div>2. Click on Add and choose &ldquo;Import an image from your Virtual Machines library (recommended).&rdquo;</div>
<div>3. In the next step, choose your image name from the dropdown and confirm the prompt.</div>
<div>4. Give a name and a location to this image. Keep a note of the location that you are selecting as it will be very important in the next step.</div>
<div>5. This process will take close to an hour to complete. Be patient!</div>
<br /> <br />
<div><span style="font-size: large;">Create a RemoteApp Collection</span></div>
<div>&nbsp;&nbsp;</div>
<div>1. Click on the &ldquo;New&rdquo; button on the RemoteApps blade on the Azure Portal.</div>
<div>2. Choose quick create and choose the same region as you had selected while creating the RemoteApp image.</div>
<div>3. Your image will appear in the Template Image dropdown. Select that and let the RemoteApp collection get created. This will again take few minutes.</div>
<br /> <br />
<div><span style="font-size: large;">Publish your apps</span></div>
<div>&nbsp;&nbsp;</div>
<div>In this section we will publish the apps that we want to be available to the end users. Explore the RemoteApp collection that you just created and navigate to Publishing tab.</div>
<div>From the bottom bar, select the Publish button and choose the applications that you want to publish. Choose publish start menu programs and select the programs that you had installed earlier.</div>
<div>Additionally you may want to grant access to users from the User Access tab.</div>
<div><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/0272.5.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/0272.5.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/0272.5.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/0272.5.png" alt="" border="0" /></a></div>
<div>&nbsp;</div>
<br /> <br />
<div><span style="font-size: large;">Use your RemoteApps</span></div>
<div>&nbsp;&nbsp;</div>
<div>1. Navigate to <a href="https://www.remoteapp.windowsazure.com/" target="_blank">https://www.remoteapp.windowsazure.com/</a> and choose your platform and install the Remote App launcher provided by Microsoft.</div>
<div>2. Sign in to the Azure RemoteApp application. You should be able to see the programs that you had published earlier.</div>
<div>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/6406.6.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/6406.6.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/6406.6.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/6406.6.png" alt="" border="0" /></a></div>
<div>3. Now launch the apps and enjoy! You can identify a RemoteApp from a local one by the subtle icon change after you have launched the app.</div>
<div>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/6685.7.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/6685.7.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/6685.7.png" original-url="blogs.msdn.com/resized-image.ashx/__size/40x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/6685.7.png" alt="" border="0" /></a></div>
&nbsp;&nbsp;<br /> &nbsp;&nbsp;<br />
<div><span style="font-size: large;">Conclusion</span></div>
<div>&nbsp;&nbsp;</div>
<div>Creating and using RemoteApps has never been easier. Microsoft Azure has provided great tools to make sure that the process is as painless as possible.</div>
</div>
<div>&nbsp;</div>]]></content:encoded>
    </item>
    <item>
      <title>Working with SharePoint Workflow inside Outlook add-in – Part 2</title>
      <link>https://docs.microsoft.com/archive/blogs/dream_in_code/working-with-sharepoint-workflow-inside-outlook-add-in-part-2</link>
      <pubDate>Sun, 07 Jun 2015 10:24:00 GMT</pubDate>
      <dc:creator><![CDATA[Mayank MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dream_in_code/2015/06/07/working-with-sharepoint-workflow-inside-outlook-add-in-part-2/</guid>
      <description><![CDATA[This is second in a two part series where I will show you how we can work with a SharePoint Approval...]]></description>
      <content:encoded><![CDATA[<p align="justify"><em>This is second in a two part series where I will show you how we can work with a SharePoint Approval workflow within the familiar environment of Outlook. You can read the first part <a href="https://blogs.msdn.com/b/dream_in_code/archive/2015/06/04/working-with-sharepoint-workflow-inside-outlook-add-in-part-1.aspx" target="_blank">here</a>.</em></p>
<p align="justify">Last week we saw how we can retrieve entire email content in Read Mode of Outlook add-in using Exchange Web Services (EWS). This post talks about how we can integrate that information with SharePoint Online to work on workflows from inside Outlook environment.</p>
<p align="justify">The first step in the process is to create an application in the Azure AD instance linked to your SharePoint Online tenant. <em>(Fyi, Microsoft provides a free trial of Azure for developers.)</em></p>
<p align="justify">We will navigate to our Active Directory inside Azure Management Portal and navigate to Applications tab. From there we click on &ldquo;Add" button and select &ldquo;Add an application my organization is developing&rdquo;. Give it a name and select &ldquo;Web Application&rdquo; from the choices and hit next. Provide a Sign-On URL and App ID URI. The sign on URL in our case will be where you have hosted your Outlook web application. The App ID can be anything unique. Clicking on checkbox will create our application.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/2605.image_6FD9800C.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/2605.image_5F00_6FD9800C.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/3568.image_thumb_25DDFF1A.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/3568.image_5F00_thumb_5F00_25DDFF1A.png" alt="image" width="746" height="536" border="0" /></a></p>
<p align="justify">After your application is created, it will appear in the Applications list. Click on it and navigate to Configure tab. Here we will find few properties which are important for our application. Make a note of Client ID and generate an App Key either for 1 or 2 year. Also enter a Reply URL which is the URL where the Azure AD instance will navigate to provide the Authentication Token.</p>
<p align="justify">We will then need to click on &ldquo;Add Application&rdquo; and choose &ldquo;Office 365 SharePoint Online&rdquo; application. We will provide the application appropriate rights which in this case would be &ldquo;Read and write items in lists in all site collections&rdquo;. After you are done your application configuration will look something like this.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/2148.image_7297A479.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/2148.image_5F00_7297A479.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/7416.image_thumb_2C3F5FC6.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/7416.image_5F00_thumb_5F00_2C3F5FC6.png" alt="image" width="802" height="466" border="0" /></a></p>
<p>Now that we are done with all the configuration (whew!) we will go back to our code. In the web.config of our Outlook web application, we will add the following appSettings.</p>
<pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">&lt;add key="ida:AuthorizationUri" value="https://login.windows.net" /&gt;
&lt;add key="ida:ClientID" value="ad039897-blablabla" /&gt;
&lt;add key="ida:AppKey" value="supersecretappkey" /&gt;</pre>
<p>&nbsp;</p>
<p align="justify">The Client ID and AppKey that we have generated in previous steps need to populated here.</p>
<p align="justify">Next we will add code in our Home Controller to actually use this information to authenticate with Azure AD and use SharePoint Online APIs. As we will be already authenticated when we are inside OWA, the authentication process will be completely seamless to the end user.</p>
<p><em>Note: For best user experience, I suggest to keep the View of Home controller blank so that the authentication process is completely hidden from the end user.</em></p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">private readonly string _clientId = ConfigurationManager.AppSettings["ida:ClientID"];
private readonly string _appKey = ConfigurationManager.AppSettings["ida:AppKey"];
private readonly string _authorizationUri = ConfigurationManager.AppSettings["ida:AuthorizationUri"];
private const string ServiceResourceId = "https://&lt;tenant&gt;.sharepoint.com";</pre>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">public async Task&lt;ActionResult&gt; Index(string et, string code, string error, string error_description)
{
	if (error != null) return RedirectToAction("Error", new { error, error_description });

	var authContext = new AuthenticationContext(_authorizationUri + "/common", true);

	// Check if you received an authorization code, if not you need to sign in
	if (code == null)
	{
		// Get the authorization URL (https://login.windows.net/common/oauth2/authorize)
		var redirectUri = authContext.GetAuthorizationRequestURL(ServiceResourceId, _clientId, new Uri(Request.Url.AbsoluteUri.Split('?')[0]), UserIdentifier.AnyUser, string.Empty);

		return Redirect(redirectUri.ToString());
	}

	// If the code is empty, show the user the error page
	if (String.IsNullOrEmpty(code)) return RedirectToAction("Error", new { error = "AuthToken", error_description = "The authorization token was not retrieved." });

	// If a code is retrieved, the access token can be generated
	var clientCredentials = new ClientCredential(_clientId, _appKey);
	var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(code, new Uri(Request.Url.AbsoluteUri.Split('?')[0]), clientCredentials);
	return Redirect("/AppRead/Home/Home.html?auth=" + authResult.AccessToken);
}</pre>
<p><span style="font-family: Calibri;">Note how we are navigating to the Home.html page along with the Auth Token acquired by AAD. This token is then extracted and used for subsequent calls to work with SharePoint workflows.</span><span style="font-family: Calibri;">In this example, I have hardcoded the List name and item name as this is a POC. You can improve the code to dynamically fetch these values.</span></p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">[ActionName("spQuery")]
public ApprovalApi.Models.ServiceResponse PostSPQuery(ServiceRequest request)
{
_request = request;
ApprovalApi.Models.ServiceResponse response = new Models.ServiceResponse();
ClientContext clientContext = new ClientContext("https://&lt;tenant&gt;.sharepoint.com/");
clientContext.AuthenticationMode = ClientAuthenticationMode.Anonymous;
clientContext.FormDigestHandlingEnabled = false;
clientContext.ExecutingWebRequest +=
	delegate(object oSender, WebRequestEventArgs webRequestEventArgs)
	{
		webRequestEventArgs.WebRequestExecutor.RequestHeaders["Authorization"] =
			"Bearer " + request.SPAuthToken;
	};
ListCollection lists = clientContext.Web.Lists;
List selectedList = clientContext.Web.Lists.GetByTitle("Tasks");
ListItem item = selectedList.GetItemById(2);
clientContext.Load&lt;ListCollection&gt;(lists);
clientContext.Load&lt;List&gt;(selectedList);
clientContext.Load(item);
clientContext.ExecuteQuery();
if (request.Approve)
{
	item["Completed"] = true;
	item["PercentComplete"] = 1;
	item["Status"] = "Approved";
	item["WorkflowOutcome"] = "Approved";
	response.isApproved = true;
}
else
{
	item["Completed"] = false;
	item["PercentComplete"] = 0;
	item["Status"] = "Rejected";
	item["WorkflowOutcome"] = "Rejected";
	response.isApproved = false;
}
item.Update();
clientContext.ExecuteQuery();
response.isError = false;
return response;
}</pre>
<p>&nbsp;</p>
<p>The UI of our Outlook web app will look something like this.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/2604.image_66C3ADE6.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/2604.image_5F00_66C3ADE6.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/5355.image_thumb_018C0BB0.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/5355.image_5F00_thumb_5F00_018C0BB0.png" alt="image" width="962" height="655" border="0" /></a></p>
<p>User can now click on Approve or Reject button from inside Outlook to deal with workflow tasks!</p>
<p>This was a quick look at how easy it is to integrate SharePoint and Office <span style="text-decoration: line-through;">apps</span> add-ins to improve the user experience. If you have any question or comment, please hit the comments section below.</p>
<p><em>As usual, the code is attached to this post.</em></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/62/01/58/ApprovalApp.zip" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-62-01-58/ApprovalApp.zip">ApprovalApp.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Working with SharePoint Workflow inside Outlook add-in – Part 1</title>
      <link>https://docs.microsoft.com/archive/blogs/dream_in_code/working-with-sharepoint-workflow-inside-outlook-add-in-part-1</link>
      <pubDate>Thu, 04 Jun 2015 07:40:00 GMT</pubDate>
      <dc:creator><![CDATA[Mayank MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dream_in_code/2015/06/04/working-with-sharepoint-workflow-inside-outlook-add-in-part-1/</guid>
      <description><![CDATA[This is the first part of a 2 part series where I will show you how we can work with a SharePoint...]]></description>
      <content:encoded><![CDATA[<p><em>This is the first part of a 2 part series where I will show you how we can work with a SharePoint Approval workflow within the familiar environment of Outlook. You find second part <a href="https://blogs.msdn.com/b/dream_in_code/archive/2015/06/07/working-with-sharepoint-workflow-inside-outlook-add-in-part-2.aspx" target="_blank">here</a>.</em></p>
<p align="justify">If you have been following Build 2015, you would know that Office apps and SharePoint apps have been renamed to Office add-ins and SharePoint add-ins respectively. You should also watch this excellent session available on Channel 9 in which the future of SharePoint and Office is discussed at length - <a href="https://channel9.msdn.com/events/Ignite/2015/FND2202">Office Development Matters, and Here's Why...</a></p>
<p>If you have worked with SharePoint Approval workflow, you would know that once a new item is added you can have a functionality where a mail is triggered to the approver for his approval. A typical approval mail looks something like this:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/4807.image_2EFFD624.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/4807.image_5F00_2EFFD624.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/8321.image_thumb_5A098ED1.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/8321.image_5F00_thumb_5F00_5A098ED1.png" alt="image" width="896" height="524" border="0" /></a></p>
<p align="justify">The user is then expected to click on the link which opens the browser where he logs-in and approves/rejects the request. What if we can provide the user a better experience within the Outlook app itself! Here we are going to create an Outlook add-in which will read the email, extract the link and provide a UI for approval to the user. In this first part, we will see how our app will identify the email and read the contents of the mail.</p>
<p>We will begin with creating a task pane app for Outlook. We will call it <strong>ApprovalApp</strong> which will run in <strong>Read mode</strong> of an Outlook email.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/5126.image_12B6C990.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/5126.image_5F00_12B6C990.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/0830.image_thumb_2F534563.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/0830.image_5F00_thumb_5F00_2F534563.png" alt="image" width="624" height="463" border="0" /></a></p>
<p>We will start with defining something called <strong>Activation Rule</strong> which defines when an add-in will detect the proper mail and show its UI. Here we are going with a very simple Regex applied on the subject of the mail.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/4331.image_7A4946E3.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/4331.image_5F00_7A4946E3.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/1680.image_thumb_22146E63.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/1680.image_5F00_thumb_5F00_22146E63.png" alt="image" width="968" height="477" border="0" /></a></p>
<p align="justify">Next we will define a Web API which will host our service which will help in getting the mail content as well as working with the SharePoint workflow once the List item URL is extracted from the email body. To avoid cross-domain issue, we will keep both the Web API as well as Outlook add-in website within the same project.</p>
<p>The UI of our app looks something like this:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/8081.image_5DF8B26B.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/8081.image_5F00_5DF8B26B.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/metablogapi/5417.image_thumb_45F762B4.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11-metablogapi/5417.image_5F00_thumb_5F00_45F762B4.png" alt="image" width="1079" height="550" border="0" /></a></p>
<p>On click of "Get Mail Body" button, our app will call the Web API which will in turn authenticate with the EWS and return the mail item body. The code for making the Web API request is pretty simple.</p>
<pre class="brush: js; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">function makeServiceRequest() {
    $.ajax({
        url: "/api/Approval",
        type: "POST",
        data: JSON.stringify(serviceRequest),
        contentType: "application/json",
        complete: responseComplete
    });
};</pre>
<p align="justify">Now the main problem here is that in the current version of Office.js, you cannot access the mail body in Read Mode. To workaround this we have to use Exchange Web Services (EWS).</p>
<p align="justify">To authenticate with EWS, you do not have access to the user&rsquo;s password. Instead Office.js provides a token via method <span style="font-family: 'Courier New';">getCallbackTokenAsync</span> which can be used to authenticate with EWS. This is not very clearly documented anywhere and the following code will help you if you ever want to do the same thing.</p>
<pre class="brush: js; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">function getMailBody() {
    Office.context.mailbox.getCallbackTokenAsync(authorizationTokenCallback);
};

function authorizationTokenCallback(asyncResult, userContext) {
    if (asyncResult.status == "succeeded") {
        serviceRequest.AuthToken = asyncResult.value;
        makeServiceRequest();
    }
    else {
        $('#taskUrl').text("Could not get callback token: " + asyncResult.error.message);
    }
}</pre>
<p align="justify">This token can then be used in EWS Managed API to authenticate with Exchange and load the item body. The code taken in the authentication token passed by our app and uses <span style="font-family: 'Courier New';">OAuthCredentials</span> to authenticate with Exchange. In the following code, we are also extracting the URLs from the email body via Regex.</p>
<p><em>Note: There are other simpler ways to extract URLs from email. The aim of this post is to show how we can access the entire email in Read mode.</em></p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">public ApprovalApi.Models.ServiceResponse Post(ServiceRequest request)
        {
            ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
            service.Credentials = new OAuthCredentials(request.AuthToken);
            service.Url = new Uri(request.EwsURL);
            Item item = Item.Bind(service, request.ItemId);
            if (item.Body != null)
            {
                Regex linkParser = new Regex(@"\b(?:https?://|www\.)\S+\b", RegexOptions.Compiled | RegexOptions.IgnoreCase);
                Match match = linkParser.Matches(item.Body.Text)[1];
                ApprovalApi.Models.ServiceResponse response = new Models.ServiceResponse();
                response.isError = false;
                response.url = match.Value;
                return response;
            }

            return null;
        }</pre>
<p>Now that we have the entire email body and also the item URL, in the next part we will look at how we can use this information to bring SharePoint functionality within Outlook.</p>
<p>Stay tuned!</p>
<p><em>P.S. &ndash; You can find the source code attached with this post below.</em></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/61/96/41/ApprovalApp.zip" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-61-96-41/ApprovalApp.zip">ApprovalApp.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Using Vorlon to debug Office Apps Javascript</title>
      <link>https://docs.microsoft.com/archive/blogs/dream_in_code/using-vorlon-to-debug-office-apps-javascript</link>
      <pubDate>Wed, 27 May 2015 02:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Mayank MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dream_in_code/2015/05/27/using-vorlon-to-debug-office-apps-javascript/</guid>
      <description><![CDATA[If you have been following Build 2015, you must have heard about the cool new Javascript debugging...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: small;">If you have been following <a href="www.buildwindows.com/" target="_blank">Build 2015</a>, you must have heard about the cool new Javascript debugging tool released by Microsoft Open Source - <a href="vorlonjs.com/" target="_blank">VorlonJS</a>. The steps to install Vorlon are real easy.</span></p>
<ol>
<li><span style="font-size: small;">Install <a href="https://nodejs.org/" target="_blank">Node.js</a> on your system.</span></li>
<li><span style="font-size: small;">Install Vorlon on your install by the following command in NPM - "<strong>npm i -g vorlon</strong>"</span></li>
<li><span style="font-size: small;">Run Vorlon by command - "<strong>vorlon</strong>".</span></li>
</ol>
<div><span style="font-size: small;">Vorlon is especially useful in scenarios where an app supports devices of multiple sizes in different environments. Since Office apps (including SharePoint apps) can now run literally anywhere - Web, Windows, Android, iOS - it makes sense to have a tool which helps you quickly debug issues in all these environments without resorting to weird hacks.</span></div>
<div><span style="font-size: small;">In this example, I am going to show you how easy it is to use Vorlon in a Word Task Pane app.&nbsp;</span></div>
<div><ol>
<li><span style="font-size: small;">Include a reference to Vorlon in your webpage -&nbsp;</span>
<pre class="scroll"><code class="js">&lt;script src="localhost:1337/vorlon.js"&gt;&lt;/script&gt;</code></pre>
</li>
<li><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/3362.code.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/3362.code.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/3362.code.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/3362.code.png" alt="" border="0" /></a></li>
<li><span style="font-size: small;">Done!</span></li>
</ol>
<div><span style="font-size: small;">Here are some screenshots (Click for original image size):</span></div>
</div>
<div><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5241.identify.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5241.identify.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5241.identify.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5241.identify.png" alt="" border="0" /></a></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/2063.selection.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/2063.selection.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/2063.selection.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/2063.selection.png" alt="" border="0" /></a></div>
<div>&nbsp;</div>
<div><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/6724.cmd.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/6724.cmd.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/6724.cmd.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/6724.cmd.png" alt="" border="0" /></a></div>]]></content:encoded>
    </item>
    <item>
      <title>Cross Origin Request Implementation for Internet Explorer 8</title>
      <link>https://docs.microsoft.com/archive/blogs/dream_in_code/cross-origin-request-implementation-for-internet-explorer-8</link>
      <pubDate>Thu, 24 Oct 2013 04:21:49 GMT</pubDate>
      <dc:creator><![CDATA[Mayank MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dream_in_code/2013/10/24/cross-origin-request-implementation-for-internet-explorer-8/</guid>
      <description><![CDATA[Internet Explorer 8 and below does not support cross origin requests. To enable cross domain...]]></description>
      <content:encoded><![CDATA[<p>Internet Explorer 8 and below does not support cross origin requests. To enable cross domain requests in IE 8, we have to follow certain workarounds.</p>
<p>IE 8 allows &ldquo;<a href="https://msdn.microsoft.com/en-us/library/ie/cc197015(v=vs.85).aspx">postMessage</a>&rdquo; method. We take advantage of this method to communicate between the host page and the cross origin page that is loaded in an IFrame in the host page.</p>
<p>The cross origin page which is loaded in the IFrame, attaches itself to the &ldquo;onmessage&rdquo; event and begins listening for incoming messages.</p>
<p>When the cross domain page receives any message, it parses the message and then performs the requested operation. It will then send back response to host page through &ldquo;postMessage&rdquo; method.</p>
<p>If there are multiple concurrent requests, the host page needs to figure out the request-response mapping. For this, we declare a global counter in the page called <strong>messageIndex</strong>. Each message that the host page sends to the IFrame contains certain parameters as properties:</p>
<ol>
<li>URL &ndash; The URL where the request needs to be sent for processing</li>
<li>Type &ndash; GET/POST/PUT/DELETE</li>
<li>Content Type &ndash; text/json etc.</li>
<li>Payload Data</li>
<li>Message ID &ndash; The globally incrementing counter (messageIndex).</li>
</ol>
<p>The cross domain page would process the request and send back the response which will contain the following properties:</p>
<ol>
<li>Result</li>
<li>Message ID</li>
</ol>
<p>At the host page, we again attach to the &ldquo;onmessage&rdquo; event and receive and process the data accordingly.</p>
<p>The cross origin page can decide whether to allow request coming from any origin or can check the origin of the incoming request and allow/reject the call.</p>]]></content:encoded>
    </item>
    <item>
      <title>Open XML with Word App - Can we do that?</title>
      <link>https://docs.microsoft.com/archive/blogs/dream_in_code/open-xml-with-word-app-can-we-do-that</link>
      <pubDate>Wed, 24 Apr 2013 09:47:00 GMT</pubDate>
      <dc:creator><![CDATA[Mayank MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dream_in_code/2013/04/24/open-xml-with-word-app-can-we-do-that/</guid>
      <description><![CDATA[A general perception amongst developers regarding Office App JavaScript API is that it is not as...]]></description>
      <content:encoded><![CDATA[<p style="text-align: justify;"><span style="font-size: medium;">A general perception amongst developers regarding Office App JavaScript API is that it is not as powerful or as flexible as earlier VSTO based add-in solutions. This, albeit being true to a large extent, is not entirely true. The new Office API is not meant to replace existing&nbsp;Interop&nbsp;based solutions but supplement them. An Office App makes more sense when we look at the security, scalability and flexibility that come along with it.</span></p>
<p style="text-align: justify;"><span style="font-size: medium;">We all, however, do agree that Open XML is a pretty neat way to manipulate Office documents. It offers nearly all the advantages and even more as compared to Interop solutions. In this post I am going to show you a way in which you can get the full power of Open XML SDK while using Word Apps.</span></p>
<p style="text-align: justify;"><span style="font-size: medium;">The new Office API provides a way to get the entire document without any user interaction. The method <a title="msdn.microsoft.com/en-us/library/jj715284.aspx" href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/getFileAsync">getFileAsync </a>provides a way to get the document either as plain text or in OOXML format. Getting data as plain text is simple and we don&rsquo;t like doing simple things. Hence we will get data in OOXML format which is returned as byte array.</span></p>
<p style="text-align: justify;"><span style="font-size: medium;">One thing to note here is that the <a title="msdn.microsoft.com/en-us/library/jj715284.aspx" href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/getFileAsync">getFileAsync </a>method allows transfer only up to 4 MB of data but that should be sufficient for most purposes.&nbsp;</span></p>
<p style="text-align: justify;"><span style="font-size: medium;"><span>Now that we have the byte array, notice that Office API also provides a handy method to convert it to Base-64 encoded string which we can then POST to any service of our choosing.</span></span></p>
<pre class="scroll"><code class="js"><span style="color: #0000ff;">function</span> GetDocument() {<br /> $('<span style="color: #ff0000;">#Loading</span>').show();<br /> <span style="color: #0000ff;">var</span> documentText = <span style="color: #0000ff;">null</span>;<br /> Office.context.document.getFileAsync(<span style="color: #ff0000;">"compressed"</span>, <span style="color: #0000ff;">function</span> (result) {<br /> <span style="color: #0000ff;">if</span> (result.status == <span style="color: #ff0000;">"succeeded"</span>) {<span style="color: #008000;"><br /> //Get the file</span><br /> <span style="color: #0000ff;">var</span> myFile = result.value;<br /> myFile.getSliceAsync(0, <span style="color: #0000ff;">function</span> (resultSlice) {<br /> <span style="color: #0000ff;">if</span> (result.status == <span style="color: #ff0000;">"succeeded"</span>) {<span style="color: #008000;"> <br />//We got the file slice. Now we will encode the data and post to a service</span><br /> documentText = OSF.OUtil.encodeBase64(resultSlice.value.data);<br /> $.ajax({<br /> type: <span style="color: #ff0000;">"POST"</span>,<br /> url: <span style="color: #ff0000;">"../DocumentService.svc/ParseDocument"</span>,<br /> data: JSON.stringify(documentText),<br /> contentType: <span style="color: #ff0000;">"application/json; charset=utf-8"</span>,<br /> dataType: <span style="color: #ff0000;">"json"</span>,<br /> success: <span style="color: #0000ff;">function</span> (data) {<br /> $(<span style="color: #ff0000;">'#Loading'</span>).hide();<br /> $(<span style="color: #ff0000;">'#Content'</span>).show();<br /> $(<span style="color: #ff0000;">'#Content'</span>).append(data);<br /> },<br /> failure: <span style="color: #0000ff;">function</span> () {<br /> $(<span style="color: #ff0000;">'#Content'</span>).append("Sorry an error occurred!");<br /> }<br /> });<br /> }<br /> });<br /> myFile.closeAsync();<br /> }<br /> });<br /> }</code></pre>
<p style="text-align: justify;"><span style="font-size: medium;">For this example, we are also going to create a secured REST-ful WCF service which will have a single method called as ParseDocument accepting a string parameter. We will creatively name this service as DocumentService.svc.</span></p>
<p style="text-align: justify;"><span style="font-size: medium;">Now we will POST our document which we got earlier as a Base-64 encoded string to this service. At the service side, we will extract byte array from the string. From this byte-array we can easily create an Open XML WordProcessingDocument object. Having a document object opens up a world of possibilities for us to manipulate the document. In this example I am just returning the document&rsquo;s contents in HTML format back to the app but you can be more imaginative than that.</span></p>
<pre class="scroll"><code class="csharp"><span style="color: #0000ff;">public string</span> ParseDocumentData(<span style="color: #0000ff;">string</span> openXml)<br /> {<br /> <span style="color: #0000ff;">byte</span>[] byteArray = <span style="color: #33cccc;">Convert</span>.FromBase64String(openXml);<br /> <span style="color: #0000ff;">using</span> (<span style="color: #0000ff;">var</span> memoryStream = new <span style="color: #33cccc;">MemoryStream</span>())<br /> {<br /> memoryStream.Write(byteArray, 0, byteArray.Length);<span style="color: #008000;"> <br />//We got our document on server. Yay!</span><br /> <span style="color: #0000ff;">using</span> (<span style="color: #0000ff;">var</span> wordDoc = <span style="color: #33cccc;">WordprocessingDocument</span>.Open(memoryStream, true))<br /> {<br /> <span style="color: #0000ff;">var</span> settings = new <span style="color: #33cccc;">HtmlConverterSettings</span>()<br /> {<br /> PageTitle = <span style="color: #ff0000;">"Document Analysis"</span><br /> };<br /> <br /> <span style="color: #33cccc;">XElement</span> html = <span style="color: #33cccc;">HtmlConverter</span>.ConvertToHtml(wordDoc, settings);<br /> <span style="color: #0000ff;">return</span> html.ToString();<br /> }<br /> }<br /> }</code></pre>
<pre class="scroll">&nbsp;</pre>
<pre class="scroll"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5466.demo.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5466.demo.png"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5466.demo.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5466.demo.png" alt="" border="0" /></a></pre>
<p style="text-align: center;">&nbsp;Demo Solution</p>
<p><span style="font-size: medium;">So next time if someone asks you if we can use Open XML with the new Word API, you know what to say!</span></p>
<p><span style="font-size: small;">P.S. - I have attached the working solution. You will need to launch Visual Studio as administrator to run the sample.</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/41/37/09/OpenXMLDemo.zip" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-41-37-09/OpenXMLDemo.zip">OpenXMLDemo.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Azure Mobile Services save the day (or app)!</title>
      <link>https://docs.microsoft.com/archive/blogs/dream_in_code/azure-mobile-services-save-the-day-or-app</link>
      <pubDate>Thu, 11 Apr 2013 08:57:01 GMT</pubDate>
      <dc:creator><![CDATA[Mayank MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dream_in_code/2013/04/11/azure-mobile-services-save-the-day-or-app/</guid>
      <description><![CDATA[When Windows Store first opened to all developers, I created an app Movieoholic which pulls in data...]]></description>
      <content:encoded><![CDATA[<p style="text-align: justify;"><span style="font-size: medium;">When Windows Store first opened to all developers, I created an app <a title="apps.microsoft.com/windows/app/movieoholic/e4f213f7-8d07-4c3e-9e3d-66cab40067d6" href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/Movieoholic">Movieoholic </a>which pulls in data from Rotten Tomatoes (RT), YouTube, and Wikipedia to provide all the information that one wants to know about a movie. Frankly, I didn&rsquo;t have very high hopes from the app so scalability was the last thing on my mind. I just created the app and got it into the store.</span></p>
<p style="text-align: justify;"><span style="font-size: medium;">Now the thing about RT API is that it is rate limited &ndash; 10000 calls per day, 10 calls per second. This initially seemed fairly high number to me. So the initial version of my app didn&rsquo;t implement any kind of caching mechanism. My app pretty soon got somewhat popular. After getting some good reviews, I started getting bad reviews about the app not working\crashing. I looked at the RT Developer dashboard and noticed that I was frequently going over my quota limit. To quickly workaround this I started caching the RT API responses on user&rsquo;s machine; refreshing data from the API only when a time period of 24 hours has been crossed. In hindsight, I should have done this in the initial version of app itself.</span></p>
<p style="text-align: justify;"><span style="font-size: medium;">Caching stabilized things for a while. But as the app popularity grew, I was again back to hitting my quota limits. I needed some kind of middle tier service which cushions the number of requests to RT API and most importantly, I needed to do it quickly. Enter Azure Mobile Services (AMS)!</span></p>
<p style="text-align: justify;"><span style="font-size: medium;">I had known and played with Azure Mobile Services <a title="blogs.msdn.com/b/dream_in_code/archive/2012/09/02/windows-8-azure-mobile-services-amp-office-apps-a-heady-cocktail.aspx" href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/for quite a while then">for quite a while then</a>. But what pushed me into selecting it was when I had a chance to attend a session on it by Josh Twist (<a title="https://twitter.com/joshtwist" href="mce_host/controlpanel/blogs/posteditor.aspx/@joshtwist">@joshtwist</a>). I was amazed at the simplicity and power it provided and the rapid improvements and features that were added to it. I knew it was in good hands.</span></p>
<p style="text-align: justify;"><span style="font-size: medium;">I am not going to list down all the cool features that AMS provides &ndash; Push Notifications for Windows, iOS, and Android, OAuth Authentication for Facebook, Twitter, Google, and Windows are just a few. AMS also provides a way to do some operation whenever an attempt is made to insert, update, delete or read a record from a table. These operations are written in JavaScript and because AMS fully supports Node.js you can easily make HTTP requests (<strong>require ('request') ;</strong>) and take full advantage of its power. All this code is written in the browser window itself so we don&rsquo;t need any editor for writing code.</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5432.Untitled.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5432.Untitled.png"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5432.Untitled.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5432.Untitled.png" alt="" border="0" /></a></p>
<p style="text-align: center;"><strong>Writing code in Azure Mobile Service browser window</strong></p>
<p style="text-align: justify;"><span style="font-size: medium;">In my situation to reduce the number of calls to RT API, my app now calls AMS instead. AMS in turn checks whether it already has the requested data in tables else makes a call to RT API and stores the data back in table for future requests and also return the data back to the client &ndash; all this code written in JavaScript! This mechanism coupled with the caching at user&rsquo;s machine level means that I remain well with in my quota limits. Problem solved.</span></p>
<p style="text-align: justify;"><span style="font-size: medium;">To make things even simpler, AMS provides an SDK for Windows Store apps (apart from SDKs for other platforms). They also provide a sample app showing how to use the SDK. In fact the whole operation to migrate my app to use AMS was so easy and smooth that I was able to finish the process<strong> in a day</strong>, testing included!</span></p>
<p style="text-align: justify;"><span style="font-size: medium;">If you are developing a mobile app for any platform, I highly recommend considering Azure Mobile Services for any kind of network communication. You won&rsquo;t be disappointed.</span></p>]]></content:encoded>
    </item>
    <item>
      <title>Publishing Office App to a Network Share</title>
      <link>https://docs.microsoft.com/archive/blogs/dream_in_code/publishing-office-app-to-a-network-share</link>
      <pubDate>Thu, 20 Sep 2012 09:45:00 GMT</pubDate>
      <dc:creator><![CDATA[Mayank MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dream_in_code/2012/09/20/publishing-office-app-to-a-network-share/</guid>
      <description><![CDATA[After working hard creating a beautiful Office App, it's natural that we now want to share it with...]]></description>
      <content:encoded><![CDATA[<p style="text-align: justify;">After working hard creating a beautiful Office App, it's natural that we now want to share it with the rest of the world. The way we do this is by publishing our app to a central location from where users pick the app and use it. There are 3 ways to publish an Office app:</p>
<ol>
<li><strong>Office Store</strong> - We can publish your app to the <a href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/sellerdashboard.microsoft.com" target="_blank">Office Store</a>&nbsp;from where it is easily available to millions of Office subscribers.</li>
<li><strong>SharePoint App Catalog</strong> &nbsp;- If the app needs to be used within an organization, we can publish the app to the organization App Catalog running on SharePoint 2013.</li>
<li><strong>Network Share</strong> - We just publish the app to a network location accessible to our target audience.</li>
</ol>
<div style="text-align: justify;">Perhaps the easiest and fastest way to start consuming Office apps is by using a network share. It is also very helpful while developing the app when we quickly want to test it out without waiting for long-drawn approvals/certification. In this blog post we will look at how can we publish our app to a network share.</div>
<div></div>
<div><strong style="font-size: medium;">Package and Publish</strong></div>
<div><strong><br /></strong></div>
<div>We will begin by creating a Task Pane app for Word which is just out-of-the-box code that Visual Studio generates when we create a new Office App project. Now that our app is ready, we publish it in following steps -</div>
<div><ol>
<li>Run Visual Studio with Administrator credentials and open the solution.</li>
<li>Right-click the Office project and choose "<strong>Publish</strong>". The following dialog will be displayed which asks either to enter or create a new "Profile".</li>
<li>Profiles are easy way to remember our publishing settings. Since we have not published this app earlier, we have to create a new profile. Let's name it "NetworkProfile". Note that this name is arbitrary and will be available in the drop-down when we come back any time later to re-publish the app.</li>
</ol></div>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/2728.Profile.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/2728.Profile.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/2728.Profile.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/2728.Profile.png" style="vertical-align: text-bottom;" /></a></p>
<p>Next we have to specify where we want to host our app (local machine in this example). Note that specifying the location does not actually host the app at the mentioned&nbsp;location but just packages the app so as to use that location when deploying.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/4162.location.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/4162.location.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/4162.location.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/4162.location.png" style="vertical-align: text-bottom;" /></a></p>
<p>Click next to see a summary and hit Finish. This will package our app and open it in Windows Explorer.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/4162.location.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/4162.location.png"></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/3058.finish.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/3058.finish.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/3058.finish.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/3058.finish.png" style="vertical-align: text-bottom;" /></a></p>
<p></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/3058.finish.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/3058.finish.png"></a>The following is the structure of the package prepared by Visual Studio.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5314.folder.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5314.folder.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5314.folder.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5314.folder.png" style="vertical-align: text-bottom;" /></a></p>
<p style="text-align: justify;">There are many files of interest here- first being the <strong>Web.zip</strong> file.&nbsp;The zip file contains all the DLLs and dependencies necessary to host our app in IIS.</p>
<p style="text-align: justify;">Next there is a handy deployment file (<strong>deploy.cmd</strong>) which will help in deploying the app to IIS by using Web Deploy.</p>
<p>The next file of interest is the <strong>SetParameters.xml</strong> file.<span>This file contains parameters that are passed to Web Deploy when we use the deploy.cmd file to install the package. We can change the values of parameters present in this file as needed.</span></p>
<p><span>To deploy the package to IIS, o</span>pen Command Prompt in admin mode and run deploy.cmd file with following switches -</p>
<ol>
<li><strong>/t</strong> - <strong>Trial Mode</strong> - &nbsp;By specifying this flag, Web Deploy would check all scenarios which will be encountered when the deployment takes place but does not actually make any changes. It just generates a log file similar to what would be generated when actually deploying the app. After we are satisfied with the log files and settings, we can change the flag to /y to begin the actual deployment.</li>
<li><strong>/y</strong> - <strong>Yes or Update Mode</strong> &nbsp;-&nbsp;<span>Web Deploy performs the deployment and displays a log of what it does.</span></li>
</ol>
<div>Since in this case we are deploying the app to local IIS, we run the command - <strong>AwesomeApp.Web.deploy.cmd /y. </strong>If we wanted to deploy it to remote server, we will use the <strong>/m</strong> switch -&nbsp;<strong>AwesomeApp.Web.deploy.cmd /y /m:Remote Server Name. </strong>For a complete list of switches and how to use Web Deploy, refer <a href="https://msdn.microsoft.com/en-us/library/ff356104(VS.110).aspx">here</a>.</div>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5314.folder.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5314.folder.png"></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5826.IIS.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5826.IIS.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5826.IIS.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5826.IIS.png" width="200" height="229" style="vertical-align: text-bottom;" /></a></p>
<p></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5826.IIS.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5826.IIS.png"></a>Now that our app is deployed to IIS, we copy the manifest file present in "OfficeAppManifests" folder and place it on a network location. Next open Office application -&gt; Trust Center -&gt; Trust Center Settings -&gt; Trusted App Catalogs.</p>
<p>Here specify the C<strong>atalog Url</strong> as the network path where we have placed the manifest file and check "Show in Menu" option.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5857.catalog.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5857.catalog.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5857.catalog.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5857.catalog.png" style="vertical-align: text-bottom;" /></a></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5857.catalog.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5857.catalog.png"></a>That's it. Our app is published. We can go to Insert App option and see our app present in the Shared Folder category.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5857.catalog.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5857.catalog.png"></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5482.insert.png" original-url="blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5482.insert.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/11/5482.insert.png" original-url="blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-11/5482.insert.png" style="vertical-align: text-bottom;" /></a><strong></strong></p>
<p><span style="font-size: medium;"><strong>Limitations</strong></span></p>
<p><span style="font-size: medium;"><strong></strong></span>There are certain limitations when publishing Office apps this way.</p>
<ol>
<li>Apps published to a network location cannot use Office Licensing service to license the apps.</li>
<li>Apps cannot be used by general public and is only limited to people having access to the network location.</li>
<li>App developer cannot monetize this app as it does not use Office Store.</li>
</ol>
<p><strong style="font-size: medium;">Conclusion</strong></p>
<div><span style="font-size: medium;"><strong></strong></span></div>
<div>Publishing to a network share is a quick and easy way to distribute Office apps. It also helps in testing without the overhead of going through the Store approval process</div>
<p>In my next blog post, we will see how publishing to Office Store solves these limitations of using a network share by using the Office Licensing service.</p>]]></content:encoded>
    </item>
  </channel>
</rss>