<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Second Life of a Hungarian SharePoint Geek</title>
	<atom:link href="http://pholpar.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://pholpar.wordpress.com</link>
	<description>If your sword is too short, take one step forward</description>
	<lastBuildDate>Mon, 20 May 2013 18:02:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='pholpar.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/5ce925449c0b4e5877ba46ccc93f3f55?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Second Life of a Hungarian SharePoint Geek</title>
		<link>http://pholpar.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://pholpar.wordpress.com/osd.xml" title="Second Life of a Hungarian SharePoint Geek" />
	<atom:link rel='hub' href='http://pholpar.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Accessing Office 365 SharePoint sites using REST from a local HTML / JavaScript Host</title>
		<link>http://pholpar.wordpress.com/2013/05/11/accessing-office-365-sharepoint-sites-using-rest-from-a-local-html-javascript-host/</link>
		<comments>http://pholpar.wordpress.com/2013/05/11/accessing-office-365-sharepoint-sites-using-rest-from-a-local-html-javascript-host/#comments</comments>
		<pubDate>Sat, 11 May 2013 21:12:37 +0000</pubDate>
		<dc:creator>Peter Holpar</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Office 365]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[SP 2013]]></category>

		<guid isPermaLink="false">https://pholpar.wordpress.com/?p=1113</guid>
		<description><![CDATA[A few month ago I wrote about accessing Office 365 sites using the JavaScript. In that sample I used the SharePoint ECMAScript client object model. Last month a commenter, Gilles asked if we could use REST the same way to access the information on the O365 site. The answer is a definitive yes, I already [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1113&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A few month ago I wrote about <a href="http://pholpar.wordpress.com/2013/01/09/using-ie-as-a-local-host-for-sharepoint-ecmascript-client-object-model-the-office-365-version/">accessing <em>Office 365</em> sites using the <em>JavaScript</em></a>. In that sample I used the <em>SharePoint ECMAScript</em> client object model. Last month a commenter, <em>Gilles</em> asked if we could use <em>REST</em> the same way to access the information on the <em>O365</em> site. The answer is a definitive yes, I already provided similar solutions in my <em>Favorites in the Cloud</em> posts (<a href="http://pholpar.wordpress.com/2013/02/24/favorites-in-the-cloud-implementing-a-windows-8-share-target-application-with-an-office-365-backend/">here</a> and <a href="http://pholpar.wordpress.com/2013/02/24/favorites-in-the-cloud-implementing-a-windows-8-search-application-with-an-office-365-backend/">here</a>). In those posts I used however <em>WinJS.xhr</em> and not the <em>ajax </em>method of <em>jQuery</em>, so it might worth to see another sample that utilizes <em>jQuery</em>.</p>
<p>Originally – to keep the samples in this post short – I planned to include only the code that is relevant to the solution and / or differs from the client OM solution, however later I made a lot of small enhancements in the original code as well, so probably it is simpler to publish the full code “as is” even with possible duplicates / overlapping with the former version.</p>
<p>The sample in this post simply creates a document library in the <em>O365</em> site, but it illustrates the process of authentication and can serve as a base for more sophisticated applications as well.</p>
<p>The format of the token (<em>tokenReq</em>) and the authentication requests (<em>authReq</em>) is the same as the <em>JSCOM</em> sample, and the process itself is also very similar:</p>
<p>1. We get the token from the <em>security token service</em> (<em>STS</em>) of <em>MS Online</em>.</p>
<p>2. &quot;Login&quot; to the actual <em>O365 site </em>using the token provided by <em>STS</em> in the former step. As a result of this step, we have the required cookies (<em>FedAuth</em> and <em>rtFA</em>) to be used automatically in the next steps. These cookies are set by <em>Set-Cookie</em> headers of the response and cached and reused by the browser for later requests targeting the same site.</p>
<p>3. Get the digest from the <em>contextinfo REST </em>endpoint (see <a href="http://msdn.microsoft.com/en-us/library/fp142386.aspx">MSDN</a> for details) or from the <em>Sites</em> web service store the value into a <em>JavaScript</em> variable (<em>digest</em>).</p>
<p>4. Execute the <em>REST </em>request.</p>
<p>
<div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d2ad0246-affb-4ecb-ac6c-1c61d132bf30" class="wlWriterEditableSmartContent" style="float:none;margin:0;display:inline;padding:0;">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:500px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="color:#0000ff;">&lt;</span><span style="color:#800000;">script</span> <span style="color:#ff0000;">type</span><span style="color:#0000ff;">=&quot;text/ecmascript&quot;</span> <span style="color:#ff0000;">src</span><span style="color:#0000ff;">=&quot;<a href="http://code.jquery.com/jquery-1.8.3.min.js&quot;&gt;&lt;/" rel="nofollow">http://code.jquery.com/jquery-1.8.3.min.js&quot;&gt;&lt;/</a></span><span style="color:#800000;">script</span><span style="color:#0000ff;">&gt;</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li><span style="color:#0000ff;">&lt;</span><span style="color:#800000;">script</span> <span style="color:#ff0000;">language</span><span style="color:#0000ff;">=&quot;ecmascript&quot;</span> <span style="color:#ff0000;">type</span><span style="color:#0000ff;">=&quot;text/ecmascript&quot;&gt;</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">var</span> tokenReq = <span style="color:#800000;">&#039;&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;&#039;</span>;</li>
<li style="background:#f3f3f3;">    tokenReq += <span style="color:#800000;">&#039;&lt;soap:Envelope xmlns:xsi=&quot;<a href="http://www.w3.org/2001/XMLSchema-instance&#038;quot" rel="nofollow">http://www.w3.org/2001/XMLSchema-instance&#038;quot</a>; xmlns:xsd=&quot;<a href="http://www.w3.org/2001/XMLSchema&#038;quot" rel="nofollow">http://www.w3.org/2001/XMLSchema&#038;quot</a>; xmlns:soap=&quot;<a href="http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;&#038;#039" rel="nofollow">http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;&#038;#039</a>;</span>;</li>
<li>    tokenReq += <span style="color:#800000;">&#039;  &lt;soap:Body&gt;&#039;</span>;</li>
<li style="background:#f3f3f3;">    tokenReq += <span style="color:#800000;">&#039;    &lt;GetUpdatedFormDigestInformation xmlns=&quot;<a href="http://schemas.microsoft.com/sharepoint/soap/&#038;quot" rel="nofollow">http://schemas.microsoft.com/sharepoint/soap/&#038;quot</a>; /&gt;&#039;</span>;</li>
<li>    tokenReq += <span style="color:#800000;">&#039;  &lt;/soap:Body&gt;&#039;</span>;</li>
<li style="background:#f3f3f3;">    tokenReq += <span style="color:#800000;">&#039;&lt;/soap:Envelope&gt;&#039;</span>;</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#006400;">// you should set these values according your actual request</span></li>
<li>    <span style="color:#0000ff;">var</span> usr = <span style="color:#800000;">&#039;username@yourdomain.onmicrosoft.com&#039;</span>;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">var</span> pwd = <span style="color:#800000;">&#039;password&#039;</span>;</li>
<li>    <span style="color:#0000ff;">var</span> siteFullUrl = <span style="color:#800000;">&quot;<a href="https://yourdomain-my.sharepoint.com&#038;quot" rel="nofollow">https://yourdomain-my.sharepoint.com&#038;quot</a>;</span>;</li>
<li style="background:#f3f3f3;">   </li>
<li>    <span style="color:#0000ff;">var</span> loginUrl = siteFullUrl + <span style="color:#800000;">&quot;/_forms/default.aspx?wa=wsignin1.0&quot;</span>;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">var</span> authReq =   <span style="color:#800000;">&#039;&lt;s:Envelope xmlns:s=&quot;<a href="http://www.w3.org/2003/05/soap-envelope&#038;quot" rel="nofollow">http://www.w3.org/2003/05/soap-envelope&#038;quot</a>; xmlns:a=&quot;<a href="http://www.w3.org/2005/08/addressing&#038;quot" rel="nofollow">http://www.w3.org/2005/08/addressing&#038;quot</a>; xmlns:u=&quot;<a href="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd&quot;&gt;&#038;#039" rel="nofollow">http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd&quot;&gt;&#038;#039</a>;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;  &lt;s:Header&gt;&#039;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;    &lt;a:Action s:mustUnderstand=&quot;1&quot;&gt;<a href="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue&lt;/a:Action&gt;&#038;#039" rel="nofollow">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue&lt;/a:Action&gt;&#038;#039</a>;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;    &lt;a:ReplyTo&gt;&#039;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;      &lt;a:Address&gt;<a href="http://www.w3.org/2005/08/addressing/anonymous&lt;/a:Address&gt;&#038;#039" rel="nofollow">http://www.w3.org/2005/08/addressing/anonymous&lt;/a:Address&gt;&#038;#039</a>;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;    &lt;/a:ReplyTo&gt;&#039;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;    &lt;a:To s:mustUnderstand=&quot;1&quot;&gt;<a href="https://login.microsoftonline.com/extSTS.srf&lt;/a:To&gt;&#038;#039" rel="nofollow">https://login.microsoftonline.com/extSTS.srf&lt;/a:To&gt;&#038;#039</a>;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;    &lt;o:Security s:mustUnderstand=&quot;1&quot; xmlns:o=&quot;<a href="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&quot;&gt;&#038;#039" rel="nofollow">http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&quot;&gt;&#038;#039</a>;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;      &lt;o:UsernameToken&gt;&#039;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;        &lt;o:Username&gt;&#039;</span> + usr + <span style="color:#800000;">&#039;&lt;/o:Username&gt;&#039;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;        &lt;o:Password&gt;&#039;</span> + pwd + <span style="color:#800000;">&#039;&lt;/o:Password&gt;&#039;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;      &lt;/o:UsernameToken&gt;&#039;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;    &lt;/o:Security&gt;&#039;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;  &lt;/s:Header&gt;&#039;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;  &lt;s:Body&gt;&#039;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;    &lt;t:RequestSecurityToken xmlns:t=&quot;<a href="http://schemas.xmlsoap.org/ws/2005/02/trust&quot;&gt;&lt;wsp:AppliesTo" rel="nofollow">http://schemas.xmlsoap.org/ws/2005/02/trust&quot;&gt;&lt;wsp:AppliesTo</a> xmlns:wsp=&quot;<a href="http://schemas.xmlsoap.org/ws/2004/09/policy&quot;&gt;&#038;#039" rel="nofollow">http://schemas.xmlsoap.org/ws/2004/09/policy&quot;&gt;&#038;#039</a>;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;      &lt;a:EndpointReference&gt;&#039;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;        &lt;a:Address&gt;&#039;</span> + loginUrl + <span style="color:#800000;">&#039;&lt;/a:Address&gt;&#039;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;      &lt;/a:EndpointReference&gt;&#039;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;      &lt;/wsp:AppliesTo&gt;&#039;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;      &lt;t:KeyType&gt;<a href="http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey&lt;/t:KeyType&gt;&#038;#039" rel="nofollow">http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey&lt;/t:KeyType&gt;&#038;#039</a>;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;      &lt;t:RequestType&gt;<a href="http://schemas.xmlsoap.org/ws/2005/02/trust/Issue&lt;/t:RequestType&gt;&#038;#039" rel="nofollow">http://schemas.xmlsoap.org/ws/2005/02/trust/Issue&lt;/t:RequestType&gt;&#038;#039</a>;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;      &lt;t:TokenType&gt;urn:oasis:names:tc:SAML:1.0:assertion&lt;/t:TokenType&gt;&#039;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;    &lt;/t:RequestSecurityToken&gt;&#039;</span></li>
<li style="background:#f3f3f3;">    authReq +=      <span style="color:#800000;">&#039;  &lt;/s:Body&gt;&#039;</span></li>
<li>    authReq +=      <span style="color:#800000;">&#039;&lt;/s:Envelope&gt;&#039;</span>;    </li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">function</span> startScript() {</li>
<li style="background:#f3f3f3;">      getToken();</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">var</span> token;</li>
<li style="background:#f3f3f3;">    <span style="color:#006400;">// Step 1: we get the token from the STS</span></li>
<li>    <span style="color:#0000ff;">function</span> getToken()</li>
<li style="background:#f3f3f3;">    {</li>
<li>        $.support.cors = <span style="color:#0000ff;">true</span>; <span style="color:#006400;">// enable cross-domain query</span></li>
<li style="background:#f3f3f3;">        $.ajax({</li>
<li>            type: <span style="color:#800000;">&#039;POST&#039;</span>,</li>
<li style="background:#f3f3f3;">            data: authReq,</li>
<li>            crossDomain: <span style="color:#0000ff;">true</span>, <span style="color:#006400;">// had no effect, see support.cors above</span></li>
<li style="background:#f3f3f3;">            contentType: <span style="color:#800000;">&#039;application/soap+xml; charset=utf-8&#039;</span>,</li>
<li>            url: <span style="color:#800000;">&#039;<a href="https://login.microsoftonline.com/extSTS.srf&#038;#039" rel="nofollow">https://login.microsoftonline.com/extSTS.srf&#038;#039</a>;</span>,</li>
<li style="background:#f3f3f3;">            dataType: <span style="color:#800000;">&#039;xml&#039;</span>,</li>
<li>            success: <span style="color:#0000ff;">function</span> (data, textStatus, result) {</li>
<li style="background:#f3f3f3;">                <span style="color:#006400;">// extract the token from the response data</span></li>
<li>                <span style="color:#006400;">// var token = $(result.responseXML).find(&quot;wsse&#092;&#092;:BinarySecurityToken&quot;).text(); // we should work with responseText, because responseXML is undefined, due to Content-Type: application/soap+xml; charset=utf-8</span></li>
<li style="background:#f3f3f3;">                token = $(result.responseText).find(<span style="color:#800000;">&quot;wsse&#092;&#092;:BinarySecurityToken&quot;</span>).text();</li>
<li>                getFedAuthCookies();</li>
<li style="background:#f3f3f3;">            },</li>
<li>            error: <span style="color:#0000ff;">function</span> (result, textStatus, errorThrown) {</li>
<li style="background:#f3f3f3;">                reportError(result, textStatus, errorThrown);</li>
<li>            }</li>
<li style="background:#f3f3f3;">        });</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#006400;">// Step 2: &quot;login&quot; using the token provided by STS in step 1</span></li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">function</span> getFedAuthCookies()</li>
<li>    {</li>
<li style="background:#f3f3f3;">        $.support.cors = <span style="color:#0000ff;">true</span>; <span style="color:#006400;">// enable cross-domain query</span></li>
<li>        $.ajax({</li>
<li style="background:#f3f3f3;">            type: <span style="color:#800000;">&#039;POST&#039;</span>,</li>
<li>            data: token,</li>
<li style="background:#f3f3f3;">            crossDomain: <span style="color:#0000ff;">true</span>, <span style="color:#006400;">// had no effect, see support.cors above</span></li>
<li>            contentType: <span style="color:#800000;">&#039;application/x-www-form-urlencoded&#039;</span>,</li>
<li style="background:#f3f3f3;">            url: loginUrl,         </li>
<li>            <span style="color:#006400;">// dataType: &#039;html&#039;, // default is OK: Intelligent Guess (xml, json, script, or html)</span></li>
<li style="background:#f3f3f3;">            success: <span style="color:#0000ff;">function</span> (data, textStatus, result) { </li>
<li>                <span style="color:#006400;">// we should update the digest</span></li>
<li style="background:#f3f3f3;">                <span style="color:#006400;">//refreshDigestViaWS(); // or alternatively:</span></li>
<li>                refreshDigestViaREST();</li>
<li style="background:#f3f3f3;">            },</li>
<li>            error: <span style="color:#0000ff;">function</span> (result, textStatus, errorThrown) {</li>
<li style="background:#f3f3f3;">                reportError(result, textStatus, errorThrown);</li>
<li>            }</li>
<li style="background:#f3f3f3;">        });</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">var</span> digest;</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#006400;">// Step 3a: get the digest from the Sites web service and refresh the one stored locally</span></li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">function</span> refreshDigestViaWS()</li>
<li>    {</li>
<li style="background:#f3f3f3;">        $.support.cors = <span style="color:#0000ff;">true</span>; <span style="color:#006400;">// enable cross-domain query</span></li>
<li>        $.ajax({</li>
<li style="background:#f3f3f3;">            type: <span style="color:#800000;">&#039;POST&#039;</span>,</li>
<li>            data: tokenReq,</li>
<li style="background:#f3f3f3;">            crossDomain: <span style="color:#0000ff;">true</span>, <span style="color:#006400;">// had no effect, see support.cors above</span></li>
<li>            contentType: <span style="color:#800000;">&#039;text/xml; charset=&quot;utf-8&quot;&#039;</span>,</li>
<li style="background:#f3f3f3;">            url: siteFullUrl + <span style="color:#800000;">&#039;/_vti_bin/sites.asmx&#039;</span>,</li>
<li>            headers: {</li>
<li style="background:#f3f3f3;">                <span style="color:#800000;">&#039;SOAPAction&#039;</span>: <span style="color:#800000;">&#039;<a href="http://schemas.microsoft.com/sharepoint/soap/GetUpdatedFormDigestInformation&#038;#039" rel="nofollow">http://schemas.microsoft.com/sharepoint/soap/GetUpdatedFormDigestInformation&#038;#039</a>;</span>,</li>
<li>                <span style="color:#800000;">&#039;X-RequestForceAuthentication&#039;</span>: <span style="color:#800000;">&#039;true&#039;</span></li>
<li style="background:#f3f3f3;">            },</li>
<li>            dataType: <span style="color:#800000;">&#039;xml&#039;</span>,</li>
<li style="background:#f3f3f3;">            success: <span style="color:#0000ff;">function</span> (data, textStatus, result) {</li>
<li>                digest = $(result.responseXML).find(<span style="color:#800000;">&quot;DigestValue&quot;</span>).text(); </li>
<li style="background:#f3f3f3;">                sendRESTReq();</li>
<li>            },</li>
<li style="background:#f3f3f3;">            error: <span style="color:#0000ff;">function</span> (result, textStatus, errorThrown) {</li>
<li>                        <span style="color:#0000ff;">var</span> response = JSON.parse(result.responseText);</li>
<li style="background:#f3f3f3;">                        <span style="color:#0000ff;">if</span> ((response.error != undefined) &amp;&amp; (response.error.message != undefined)) { </li>
<li>                            alert(response.error.message.value);</li>
<li style="background:#f3f3f3;">                        }</li>
<li>            }</li>
<li style="background:#f3f3f3;">        });</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#006400;">// Step 3b: get the digest from the contextinfo and refresh the one stored locally</span></li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">function</span> refreshDigestViaREST()</li>
<li>    {</li>
<li style="background:#f3f3f3;">        $.support.cors = <span style="color:#0000ff;">true</span>; <span style="color:#006400;">// enable cross-domain query</span></li>
<li>        $.ajax({</li>
<li style="background:#f3f3f3;">            type: <span style="color:#800000;">&#039;POST&#039;</span>,</li>
<li>            data: tokenReq,</li>
<li style="background:#f3f3f3;">            crossDomain: <span style="color:#0000ff;">true</span>, <span style="color:#006400;">// had no effect, see support.cors above</span></li>
<li>            contentType: <span style="color:#800000;">&#039;text/xml; charset=&quot;utf-8&quot;&#039;</span>,</li>
<li style="background:#f3f3f3;">            url: siteFullUrl + <span style="color:#800000;">&#039;/_api/contextinfo&#039;</span>,</li>
<li>            dataType: <span style="color:#800000;">&#039;xml&#039;</span>,</li>
<li style="background:#f3f3f3;">            success: <span style="color:#0000ff;">function</span> (data, textStatus, result) {  </li>
<li>                digest = $(result.responseText).find(<span style="color:#800000;">&quot;d&#092;&#092;:FormDigestValue&quot;</span>).text(); </li>
<li style="background:#f3f3f3;">                sendRESTReq();</li>
<li>            },</li>
<li style="background:#f3f3f3;">            error: <span style="color:#0000ff;">function</span> (result, textStatus, errorThrown) {</li>
<li>                        <span style="color:#0000ff;">var</span> response = JSON.parse(result.responseText);</li>
<li style="background:#f3f3f3;">                        <span style="color:#0000ff;">if</span> ((response.error != undefined) &amp;&amp; (response.error.message != undefined)) { </li>
<li>                            alert(response.error.message.value);</li>
<li style="background:#f3f3f3;">                        }</li>
<li>            }</li>
<li style="background:#f3f3f3;">        });</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#006400;">// Step 4: send the REST request</span></li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">function</span> sendRESTReq() {</li>
<li>        $.support.cors = <span style="color:#0000ff;">true</span>; <span style="color:#006400;">// enable cross-domain query</span></li>
<li style="background:#f3f3f3;">        $.ajax({</li>
<li>            type: <span style="color:#800000;">&#039;POST&#039;</span>,   </li>
<li style="background:#f3f3f3;">            data: JSON.stringify({</li>
<li>                                    __metadata: { type: <span style="color:#800000;">&#039;SP.List&#039;</span> }, </li>
<li style="background:#f3f3f3;">                                    Title: <span style="color:#800000;">&#039;RESTDocLib&#039;</span>,</li>
<li>                                    BaseTemplate: 101</li>
<li style="background:#f3f3f3;">                                }),</li>
<li>            <span style="color:#006400;">// equivalent:       </span></li>
<li style="background:#f3f3f3;">            <span style="color:#006400;">// data: &quot;{&#039;__metadata&#039;: { &#039;type&#039;: &#039;SP.List&#039; }, &#039;Title&#039;: &#039;RESTDocLib&#039;,&#039;BaseTemplate&#039;: 101}&quot; ,</span></li>
<li>            url: siteFullUrl + <span style="color:#800000;">&quot;/_api/web/lists&quot;</span>,</li>
<li style="background:#f3f3f3;">            crossDomain: <span style="color:#0000ff;">true</span>, <span style="color:#006400;">// had no effect, see support.cors above</span></li>
<li>            contentType: <span style="color:#800000;">&#039;application/json;odata=verbose&#039;</span>,</li>
<li style="background:#f3f3f3;">             headers: {</li>
<li>                 <span style="color:#800000;">&#039;X-RequestDigest&#039;</span>: digest,</li>
<li style="background:#f3f3f3;">                 <span style="color:#800000;">&quot;Accept&quot;</span>: <span style="color:#800000;">&quot;application/json; odata=verbose&quot;</span></li>
<li>             },</li>
<li style="background:#f3f3f3;">            success: <span style="color:#0000ff;">function</span> (data, textStatus, result) {  </li>
<li>                alert(<span style="color:#800000;">&quot;Created&quot;</span>);</li>
<li style="background:#f3f3f3;">            },</li>
<li>            error: <span style="color:#0000ff;">function</span> (result, textStatus, errorThrown) {</li>
<li style="background:#f3f3f3;">                        <span style="color:#0000ff;">var</span> response = JSON.parse(result.responseText);</li>
<li>                        <span style="color:#0000ff;">if</span> ((response.error != undefined) &amp;&amp; (response.error.message != undefined)) { </li>
<li style="background:#f3f3f3;">                            alert(response.error.message.value);</li>
<li>                        }</li>
<li style="background:#f3f3f3;">            }</li>
<li>        });</li>
<li style="background:#f3f3f3;">    }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">function</span> reportError(result, textStatus, errorThrown) {</li>
<li>        <span style="color:#0000ff;">var</span> response = JSON.parse(result.responseText);</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">if</span> ((response.error != undefined) &amp;&amp; (response.error.message != undefined)) {</li>
<li>            alert(response.error.message.value);</li>
<li style="background:#f3f3f3;">        }</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    $(document).ready(startScript);</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li><span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">script</span><span style="color:#0000ff;">&gt;</span></li>
</ol></div>
</p></div>
</p></div>
</p>
<p><strong>Note 1</strong>: The lookup of the <em>token</em> (in the <em>getToken</em> method) had to be changed. In the former version we used:</p>
<p><em>$(result.responseText).find(&quot;BinarySecurityToken&quot;).text();</em></p>
<p>in the new version we have to use:</p>
<p><em>$(result.responseText).find(&quot;<strong>wsse\\:</strong>BinarySecurityToken&quot;).text();</em></p>
<p><strong>Note 2</strong>: I used <em>JSON</em>’s <em>stringify</em> and <em>parse</em> methods to (de)serialize <em>JavaScript</em> objects to / from text. Important experience, that this methods <a href="http://stackoverflow.com/questions/7146268/json-stringify-and-json-parse-not-working-in-ie9"><strong>do not work</strong> in the Quirks mode of Internet Explorer</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pholpar.wordpress.com/1113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pholpar.wordpress.com/1113/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1113&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pholpar.wordpress.com/2013/05/11/accessing-office-365-sharepoint-sites-using-rest-from-a-local-html-javascript-host/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/31db6921f6eddb38f5f86b0a220dbd58?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pholpar</media:title>
		</media:content>
	</item>
		<item>
		<title>Extending the classes generated by SPMetal to access the login name of the users</title>
		<link>http://pholpar.wordpress.com/2013/05/09/extending-the-classes-generated-by-spmetal-to-access-the-login-name-of-the-users/</link>
		<comments>http://pholpar.wordpress.com/2013/05/09/extending-the-classes-generated-by-spmetal-to-access-the-login-name-of-the-users/#comments</comments>
		<pubDate>Thu, 09 May 2013 12:25:03 +0000</pubDate>
		<dc:creator>Peter Holpar</dc:creator>
				<category><![CDATA[LINQ]]></category>
		<category><![CDATA[SP 2010]]></category>

		<guid isPermaLink="false">https://pholpar.wordpress.com/?p=1111</guid>
		<description><![CDATA[Recently I was working on a console application that collects data from SharePoint list using LINQ for further analysis. Assume we have a list called Developers (no specific Content Type, only the default Item) with a field User (Person or Group, Allow multiple selections: No, People Only). Of course, we have in fact a lot [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1111&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Recently I was working on a console application that collects data from <em>SharePoint</em> list using <em>LINQ </em>for further analysis. Assume we have a list called <em>Developers </em>(no specific <em>Content Type</em>, only the default <em>Item</em>) with a field <em>User</em> (<em>Person or Group</em>, <em>Allow multiple selections: No</em>, <em>People Only</em>). Of course, we have in fact a lot more lists and columns, but they do not affect the lesson of this post.</p>
<p>I’ve generated the object model for <em>LINQ </em>using <em>SPMetal</em>, using a configuration <em>XML </em>for the <em>Developers </em>list like this fragment:</p>
<p><em>&lt;List Name=&quot;Developers&quot;&gt;     <br />&#160; &lt;ContentType Name=&quot;Item&quot; Class=&quot;Developer&quot; /&gt;      <br />&lt;/List&gt;</em>    </p>
<p><strong>Problem</strong>: We need the login name of the users in our report, however, using the default generated classed only the display name (<em>User</em> property) and the <em>ID</em> (<em>UserId</em> property) of the user are accessible.</p>
<p><strong>Solution</strong>: Fortunately, we can extend the generated partial classes, for example, in our case we should add a new <em>LoginName</em> property to the <em>Developer</em> class. To achieve that, we have to implement the <em>ICustomMapping</em> interface.</p>
<div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7bde5dbd-3014-41bc-8213-29c66031b3eb" class="wlWriterEditableSmartContent" style="float:none;margin:0;display:inline;padding:0;">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:400px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">partial</span> <span style="color:#0000ff;">class</span> <span style="color:#2b91af;">Developer</span> : <span style="color:#2b91af;">ICustomMapping</span></li>
<li style="background:#f3f3f3;">{</li>
<li>    [<span style="color:#2b91af;">CustomMapping</span>(Columns = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">String</span>[] { <span style="color:#a31515;">&quot;LoginName&quot;</span> })]</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> MapFrom(<span style="color:#0000ff;">object</span> listItem)</li>
<li>    {</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">this</span>.LoginName = <span style="color:#0000ff;">null</span>;</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="color:#2b91af;">SPListItem</span> item = (<span style="color:#2b91af;">SPListItem</span>)listItem;</li>
<li>        <span style="color:#0000ff;">if</span> (item[<span style="color:#a31515;">&quot;User&quot;</span>] != <span style="color:#0000ff;">null</span>)</li>
<li style="background:#f3f3f3;">        {</li>
<li>            <span style="color:#0000ff;">using</span> (<span style="color:#2b91af;">SPWeb</span> web = item.Web)</li>
<li style="background:#f3f3f3;">            {</li>
<li>                <span style="color:#2b91af;">SPFieldUserValue</span> usr = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">SPFieldUserValue</span>(web, (<span style="color:#0000ff;">string</span>)item[<span style="color:#a31515;">&quot;User&quot;</span>]);</li>
<li style="background:#f3f3f3;">                <span style="color:#0000ff;">this</span>.LoginName = (usr.User != <span style="color:#0000ff;">null</span>) ? usr.User.LoginName : <span style="color:#0000ff;">null</span>;</li>
<li>            }</li>
<li style="background:#f3f3f3;">        }</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> MapTo(<span style="color:#0000ff;">object</span> listItem)</li>
<li style="background:#f3f3f3;">    {</li>
<li>        <span style="color:#0000ff;">throw</span> <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">NotImplementedException</span>();</li>
<li style="background:#f3f3f3;">    }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Resolve(<span style="color:#2b91af;">RefreshMode</span> mode, <span style="color:#0000ff;">object</span> originalListItem, <span style="color:#0000ff;">object</span> databaseObject)</li>
<li>    {</li>
<li style="background:#f3f3f3;">    }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> LoginName { <span style="color:#0000ff;">get</span>; <span style="color:#0000ff;">internal</span> <span style="color:#0000ff;">set</span>; }</li>
<li>}</li>
</ol></div>
</p></div>
</p></div>
<p><strong>Note</strong>: In our case, we need only to read the account name, so (as you can see from the code above) I’ve implemented only the <em>MapFrom </em>method, but not the <em>MapTo </em>and <em>Resolve </em>methods. A solution that is able to write back the value might be a bit more complex, especially when one considers various validation and error handling scenarios.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pholpar.wordpress.com/1111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pholpar.wordpress.com/1111/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1111&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pholpar.wordpress.com/2013/05/09/extending-the-classes-generated-by-spmetal-to-access-the-login-name-of-the-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/31db6921f6eddb38f5f86b0a220dbd58?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pholpar</media:title>
		</media:content>
	</item>
		<item>
		<title>Creating a mail distributor system using the incoming mail feature of SharePoint</title>
		<link>http://pholpar.wordpress.com/2013/04/24/creating-a-mail-distributor-system-using-the-incoming-mail-feature-of-sharepoint/</link>
		<comments>http://pholpar.wordpress.com/2013/04/24/creating-a-mail-distributor-system-using-the-incoming-mail-feature-of-sharepoint/#comments</comments>
		<pubDate>Wed, 24 Apr 2013 20:56:04 +0000</pubDate>
		<dc:creator>Peter Holpar</dc:creator>
				<category><![CDATA[Incoming email]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[SP 2010]]></category>

		<guid isPermaLink="false">https://pholpar.wordpress.com/?p=1109</guid>
		<description><![CDATA[Wouldn’t it be great to implement your own custom logic to distribute mails to targeted addresses (for example, based on sender or subject of the mail) using SharePoint lists and event receivers? In this post I show you the fundamental technical issues and their solution to achieve that goal. My “custom logic” is quite simple, [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1109&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Wouldn’t it be great to implement your own custom logic to distribute mails to targeted addresses (for example, based on sender or subject of the mail) using <em>SharePoint</em> lists and event receivers? In this post I show you the fundamental technical issues and their solution to achieve that goal. My “custom logic” is quite simple, I send the same mail back to the sender, however you can build more sophisticated logic using the same technique, but more on that later.</p>
<p>Before starting <em>Visual Studio</em>, I’ve created a simple custom list called <em>MailDistributor</em> on my <em>SharePoint </em>site.</p>
<p>In <em>Visual Studio</em> I chose the <em>Empty SharePoint Project</em> template, and added a new <em>List Email Event </em>event receiver item.</p>
<p>Having these artifacts, I altered the default <em>Elements.xml</em>, to register the event receiver to the list I created earlier:</p>
<div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ca2b90d8-4e64-4b76-b1f1-df3208c78ec3" class="wlWriterEditableSmartContent" style="float:none;margin:0;display:inline;padding:0;">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:200px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="color:#0000ff;">&lt;?</span><span style="color:#a31515;">xml</span><span style="color:#0000ff;"> </span><span style="color:#ff0000;">version</span><span style="color:#0000ff;">=</span>&quot;<span style="color:#0000ff;">1.0</span>&quot;<span style="color:#0000ff;"> </span><span style="color:#ff0000;">encoding</span><span style="color:#0000ff;">=</span>&quot;<span style="color:#0000ff;">utf-8</span>&quot;<span style="color:#0000ff;">?&gt;</span></li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Elements</span><span style="color:#0000ff;"> </span><span style="color:#ff0000;">xmlns</span><span style="color:#0000ff;">=</span>&quot;<span style="color:#0000ff;"><a href="http://schemas.microsoft.com/sharepoint/" rel="nofollow">http://schemas.microsoft.com/sharepoint/</a></span>&quot;<span style="color:#0000ff;">&gt;</span></li>
<li>    <span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Receivers</span><span style="color:#0000ff;"> </span><span style="color:#ff0000;">ListUrl</span><span style="color:#0000ff;">=</span>&quot;<span style="color:#0000ff;">Lists/MailDistributor</span>&quot;<span style="color:#0000ff;">&gt;</span></li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Receiver</span><span style="color:#0000ff;">&gt;</span></li>
<li>            <span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Name</span><span style="color:#0000ff;">&gt;</span>IncomingMailHandlerEmailReceived<span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Name</span><span style="color:#0000ff;">&gt;</span></li>
<li style="background:#f3f3f3;">            <span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Type</span><span style="color:#0000ff;">&gt;</span>EmailReceived<span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Type</span><span style="color:#0000ff;">&gt;</span></li>
<li>            <span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Assembly</span><span style="color:#0000ff;">&gt;</span>$SharePoint.Project.AssemblyFullName$<span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Assembly</span><span style="color:#0000ff;">&gt;</span></li>
<li style="background:#f3f3f3;">            <span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Class</span><span style="color:#0000ff;">&gt;</span>MailDistributor.IncomingMailHandler<span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Class</span><span style="color:#0000ff;">&gt;</span></li>
<li>            <span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">SequenceNumber</span><span style="color:#0000ff;">&gt;</span>10000<span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">SequenceNumber</span><span style="color:#0000ff;">&gt;</span></li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Receiver</span><span style="color:#0000ff;">&gt;</span></li>
<li>    <span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Receivers</span><span style="color:#0000ff;">&gt;</span></li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Elements</span><span style="color:#0000ff;">&gt;</span></li>
</ol></div>
</p></div>
</p></div>
<p>Regarding the code, the first step was to create the extension method <em>GetMailMessage </em>for the <em>SPEmailMessage</em> type to convert it to a <em>MailMessage</em> object (<em>System.Net.Mail</em> namespace). Fortunately, both of these object types have the same stream format in the background. This stream is directly accessible from the <em>SPEmailMessage</em>, however, <em>MailMessage</em>&#160; is not creatable from the stream (or <em>ByteArray </em>/ <em>String</em>) format. To solve this issue, I utilized the <em><a href="http://www.codeproject.com/Articles/15611/POP3-Email-Client-with-full-MIME-Support-NET-2-0">RxMailMessage</a></em> type (copyright by <em>Peter Huber</em>, <em>Singapore</em>), that is a derived class of <em>MailMessage</em> with <em>Stream </em>and <em>File </em>support.</p>
<div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1f8c9b62-a582-4d54-b2fe-f712dad6a99d" class="wlWriterEditableSmartContent" style="float:none;margin:0;display:inline;padding:0;">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:200px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#2b91af;">MailMessage</span> GetMailMessage(<span style="color:#0000ff;">this</span> <span style="color:#2b91af;">SPEmailMessage</span> spEmailMessage)</li>
<li style="background:#f3f3f3;">{</li>
<li>    <span style="color:#2b91af;">MailMessage</span> result = <span style="color:#0000ff;">null</span>;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">if</span> (spEmailMessage != <span style="color:#0000ff;">null</span>)</li>
<li>    {</li>
<li style="background:#f3f3f3;">        result = <span style="color:#2b91af;">RxMailMessage</span>.CreateFromStream(spEmailMessage.GetMessageStream());</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">return</span> result;</li>
<li style="background:#f3f3f3;">}</li>
</ol></div>
</p></div>
</p></div>
<p>Below is the structure of the solution, highlighted the classes borrowed from <em>Peter Huber</em>.</p>
<p><a href="http://pholpar.files.wordpress.com/2013/04/image1.png"><img title="image" style="border-top:0;border-right:0;background-image:none;border-bottom:0;padding-top:0;padding-left:0;margin:0;border-left:0;display:inline;padding-right:0;" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/04/image_thumb1.png?w=202&#038;h=244" width="202" height="244" /></a></p>
<p>The next challenge was to set the addressee (<em>To</em> property) of the <em>MailMessage</em> instance. Since there is no way to change this read-only property using the public methods of the type (in practice, you should set it already in the constructor), I had to apply my experience with <em>Reflection</em>, and set the private field <em>to</em> of the private field <em>message</em> of the <em>MailMessage</em> instance. Although I set only the <em>To</em> property in the example using the <em>SetTo </em>extension method, you could (and should!) set the <em>Cc</em> and <em>Bcc</em> fields as well. For example, clear these values to avoid perpetual sending / receiving the same message in the case the one of the <em>Cc</em> / <em>Bcc</em> fields contain the incoming mail address of the SharePoint list. To do that, you should implement the <em>SetCc</em> and <em>SetBcc</em> methods and from these methods call the <em>SetMailAddressCollection</em> method with the parameters “<em>cc</em>” and “<em>bcc</em>” accordingly.</p>
<div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ecd71c36-e588-4762-933f-77d42f3239f5" class="wlWriterEditableSmartContent" style="float:none;margin:0;display:inline;padding:0;">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:400px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> SetTo(<span style="color:#0000ff;">this</span> <span style="color:#2b91af;">MailMessage</span> mailMessage, <span style="color:#2b91af;">MailAddressCollection</span> mailAddressCollection)</li>
<li style="background:#f3f3f3;">{</li>
<li>    <span style="color:#0000ff;">if</span> ((mailMessage != <span style="color:#0000ff;">null</span>) &amp;&amp; (mailAddressCollection != <span style="color:#0000ff;">null</span>))</li>
<li style="background:#f3f3f3;">    {</li>
<li>        SetMailAddressCollection(mailMessage, mailAddressCollection, <span style="color:#a31515;">&quot;to&quot;</span>);</li>
<li style="background:#f3f3f3;">    }</li>
<li>}</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> SetMailAddressCollection(<span style="color:#2b91af;">MailMessage</span> mailMessage, <span style="color:#2b91af;">MailAddressCollection</span> mailAddressCollection, <span style="color:#0000ff;">string</span> fieldName)</li>
<li style="background:#f3f3f3;">{</li>
<li>    <span style="color:#0000ff;">if</span> ((mailMessage != <span style="color:#0000ff;">null</span>) &amp;&amp; (mailAddressCollection != <span style="color:#0000ff;">null</span>) &amp;&amp; (fieldName != <span style="color:#0000ff;">null</span>))</li>
<li style="background:#f3f3f3;">    {</li>
<li>        <span style="color:#2b91af;">Type</span> typeMailMessage = <span style="color:#0000ff;">typeof</span>(<span style="color:#2b91af;">MailMessage</span>);</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>        <span style="color:#2b91af;">FieldInfo</span> fi = typeMailMessage.GetField(<span style="color:#a31515;">&quot;message&quot;</span>, <span style="color:#2b91af;">BindingFlags</span>.NonPublic | <span style="color:#2b91af;">BindingFlags</span>.Instance);</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>        <span style="color:#0000ff;">if</span> (fi != <span style="color:#0000ff;">null</span>)</li>
<li style="background:#f3f3f3;">        {</li>
<li>            <span style="color:#0000ff;">object</span> message = fi.GetValue(mailMessage);</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>            <span style="color:#0000ff;">if</span> (message != <span style="color:#0000ff;">null</span>)</li>
<li style="background:#f3f3f3;">            {</li>
<li>                <span style="color:#2b91af;">Type</span> typeMessage = message.GetType(); <span style="color:#008000;">// it is internal class System.Net.Mail.Message</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>                <span style="color:#2b91af;">FieldInfo</span> fi2 = typeMessage.GetField(fieldName, <span style="color:#2b91af;">BindingFlags</span>.NonPublic | <span style="color:#2b91af;">BindingFlags</span>.Instance);</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>                <span style="color:#0000ff;">if</span> (fi2 != <span style="color:#0000ff;">null</span>)</li>
<li style="background:#f3f3f3;">                {</li>
<li>                    fi2.SetValue(message, mailAddressCollection);</li>
<li style="background:#f3f3f3;">                }</li>
<li>            }</li>
<li style="background:#f3f3f3;">        }</li>
<li>    }</li>
<li style="background:#f3f3f3;">}</li>
</ol></div>
</p></div>
</p></div>
<p>In the event receiver, we convert the <em>SPEmailMessage</em> into a <em>MailMessage</em> instance, set its <em>To</em> property to the e-mail address of the original poster (<em>From</em> property of the <em>MailMessage</em>) and send the mail using an <em>SmtpClient</em> object. The <em>Host</em> property of the <em>SmtpClient</em> instance can be set using the <em>Address </em>of the configured <em>SMTP </em>server of the <em>OutboundMailServiceInstance</em> in the current web application.</p>
<p>As you can see, most of the code below is just tracing to help us to follow the process using <em>DebugView</em>. You are free to remove these lines without affecting the functionality, of course.</p>
<div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2e06737d-2135-43fb-a7b2-38fbcb8eb276" class="wlWriterEditableSmartContent" style="float:none;margin:0;display:inline;padding:0;">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:500px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="color:#0000ff;">using</span> System;</li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">using</span> System.Diagnostics;</li>
<li><span style="color:#0000ff;">using</span> System.Net.Mail;</li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">using</span> Microsoft.SharePoint;</li>
<li><span style="color:#0000ff;">using</span> Microsoft.SharePoint.Utilities;</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li><span style="color:#0000ff;">namespace</span> MailDistributor</li>
<li style="background:#f3f3f3;">{</li>
<li>    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> <span style="color:#2b91af;">IncomingMailHandler</span> : <span style="color:#2b91af;">SPEmailEventReceiver</span></li>
<li style="background:#f3f3f3;">    {</li>
<li>        <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">void</span> EmailReceived(<span style="color:#2b91af;">SPList</span> list, <span style="color:#2b91af;">SPEmailMessage</span> emailMessage, <span style="color:#0000ff;">string</span> receiverData)</li>
<li style="background:#f3f3f3;">        {</li>
<li>            <span style="color:#0000ff;">try</span></li>
<li style="background:#f3f3f3;">            {</li>
<li>                <span style="color:#2b91af;">Trace</span>.TraceInformation(<span style="color:#a31515;">&quot;IncomingMailHandler starting&#8230;&quot;</span>);</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>                <span style="color:#0000ff;">foreach</span> (<span style="color:#2b91af;">SPEmailHeader</span> header <span style="color:#0000ff;">in</span> emailMessage.Headers)</li>
<li style="background:#f3f3f3;">                {</li>
<li>                    <span style="color:#2b91af;">Trace</span>.TraceInformation(<span style="color:#a31515;">&quot;EmailReceived emailMessage header {0}, {1}&quot;</span>, header.Name, header.Value);</li>
<li style="background:#f3f3f3;">                }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">                <span style="color:#2b91af;">SmtpClient</span> smtpClient = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">SmtpClient</span>();</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">                smtpClient.Host = list.ParentWeb.Site.WebApplication.OutboundMailServiceInstance.Server.Address;</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">                <span style="color:#2b91af;">Trace</span>.TraceInformation(<span style="color:#a31515;">&quot;IncomingMailHandler: getting mail message from stream&quot;</span>);</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">                <span style="color:#2b91af;">MailMessage</span> mailMessage = emailMessage.GetMailMessage();</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">                <span style="color:#2b91af;">Trace</span>.TraceInformation(<span style="color:#a31515;">&quot;IncomingMailHandler: setting mail message To field&quot;</span>);</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">                mailMessage.SetTo(<span style="color:#0000ff;">new</span> <span style="color:#2b91af;">MailAddressCollection</span> { mailMessage.From });</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">                <span style="color:#2b91af;">Trace</span>.TraceInformation(<span style="color:#a31515;">&quot;IncomingMailHandler: sending mail&quot;</span>);</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">                smtpClient.Send(mailMessage);</li>
<li>                </li>
<li style="background:#f3f3f3;">                <span style="color:#2b91af;">Trace</span>.TraceInformation(<span style="color:#a31515;">&quot;IncomingMailHandler: finished&quot;</span>);</li>
<li>            }</li>
<li style="background:#f3f3f3;">            <span style="color:#0000ff;">catch</span> (<span style="color:#2b91af;">Exception</span> ex)</li>
<li>            {</li>
<li style="background:#f3f3f3;">                <span style="color:#2b91af;">Trace</span>.TraceInformation(<span style="color:#a31515;">&quot;IncomingMailHandler exception: {0}&quot;</span>, ex.Message);</li>
<li>            }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>        }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>}</li>
</ol></div>
</p></div>
</p></div>
<p>After deploying the solution and activating the feature, we should enable the incoming mail for the <em>MailDistributor</em> list, set the mail address alias, and send a test message to this address. If there is no error, within about a minute we should receive the same mail, including formatting and attachments to the mailbox of the sender.</p>
<h3>Using the Category settings of the mail to route the message</h3>
<p>The rule we implemented is really a trivial one and has not much sense, but one can implement more complicated and more useful routing rules as well. My plan is to build a routing “engine” based on the <em>Category</em> settings of the mail.</p>
<p>As part of the <em>Options</em> / <em>Tracking</em> properties in Outlook, we can set not only <em>Blue</em> or <em>Green</em> categories, but our own custom categories (like <em>SharePoint</em> and <em>Silverlight</em> below) as well. As long as these categories are transferred within the mail, we can process them in our event receiver, look up <em>SharePoint</em> user profiles having the same values set in the <em>Ask me about</em> property, and route the message exactly to those users, implementing thus a simple but efficient knowledge management solution.</p>
<p>It would be even better if the user could choose those category values from a <em>SharePoint Managed Metadata</em> keyword list (a candidate for an <em>Office 2013 </em>mail-app?).</p>
<p><a href="http://pholpar.files.wordpress.com/2013/04/image2.png"><img title="image" style="border-top:0;border-right:0;background-image:none;border-bottom:0;padding-top:0;padding-left:0;border-left:0;display:inline;padding-right:0;" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/04/image_thumb2.png?w=511&#038;h=484" width="511" height="484" /></a></p>
<p>However there are some issues with the <em>Category </em>property that you should be aware of.</p>
<p>Based on <a href="http://www.slipstick.com/outlook/email/sending-categories-on-email-messages/">this information</a>, <em>Outlook</em> removes category settings from outgoing mails due to privacy concerns. One can alter this settings via registry (<em>HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\xx.0\Outlook\Preferences\SendPersonalCategories</em>, where <em>xx</em> is the version number of <em>Outlook</em>, like <em>14 </em>for <em>Outlook 2010</em>).</p>
<p><em>Exchange 2010</em> also removes the categories from the outgoing messages by default, as I’ve learned <a href="http://social.technet.microsoft.com/Forums/en-US/exchange2010/thread/d5afc406-02cd-4244-8e6a-da3341031051">here</a>. This behavior can be changes using the following <em>PowerShell </em>command:</p>
<p><em>Set-TransportConfig -ClearCategories:$False</em></p>
<p>A workaround for these issues might be an <em>Outlook add-in</em>, or a simply <em>VBA</em> code like this one, that illustrates, how to copy the mail categories to a custom mail header called <em>X-Categories</em> when sending the mail, thus avoiding losing of the categories:</p>
<p><em>Private Sub Application_ItemSend(ByVal item As Object, Cancel As Boolean)     <br />&#160;&#160;&#160; Dim mi As MailItem      <br />&#160;&#160;&#160; Set mi = item      <br />&#160;&#160;&#160; If Not mi Is Nothing Then      <br />&#160;&#160;&#160;&#160;&#160;&#160; item.PropertyAccessor.SetProperty &quot;<a href="http://schemas.microsoft.com/mapi/string/" rel="nofollow">http://schemas.microsoft.com/mapi/string/</a>{00020386-0000-0000-C000-000000000046}/X-Categories&quot;, item.Categories      <br />&#160;&#160;&#160; End If      <br />End Sub</em></p>
<p>Of course, we should filter the mails affected by this behavior based on the <em>To</em> e-mail address, limiting it to the mails sent to our <em>MailDistributor</em> list.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pholpar.wordpress.com/1109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pholpar.wordpress.com/1109/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1109&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pholpar.wordpress.com/2013/04/24/creating-a-mail-distributor-system-using-the-incoming-mail-feature-of-sharepoint/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/31db6921f6eddb38f5f86b0a220dbd58?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pholpar</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/04/image_thumb1.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/04/image_thumb2.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Replacing the standard textbox for numeric fields with a Slider using HTML5</title>
		<link>http://pholpar.wordpress.com/2013/04/17/replacing-the-standard-textbox-for-numeric-fields-with-a-slider-using-html5/</link>
		<comments>http://pholpar.wordpress.com/2013/04/17/replacing-the-standard-textbox-for-numeric-fields-with-a-slider-using-html5/#comments</comments>
		<pubDate>Wed, 17 Apr 2013 10:39:50 +0000</pubDate>
		<dc:creator>Peter Holpar</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[SP 2010]]></category>
		<category><![CDATA[SP 2013]]></category>

		<guid isPermaLink="false">https://pholpar.wordpress.com/?p=1103</guid>
		<description><![CDATA[HTML5 supports a special input field type called Range. It would be nice to use this type of control when we should provide the user an edit form to enter a limited range of integer values. If this type of control is required in multiple lists, a straightforward option would be to create a custom [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1103&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><em>HTML5</em> supports a special input field type called <em><a href="http://www.html5tutorial.info/html5-range.php">Range</a></em>. It would be nice to use this type of control when we should provide the user an edit form to enter a limited range of integer values.</p>
<p>If this type of control is required in multiple lists, a straightforward option would be to create a custom field type. However, if it’s about only a single list, or deploying the assembly and other artifacts for the custom field is not allowed (like in the case of O365), than there is a simpler way to choose. We have to hide the original <em>Text</em> field for the numeric field and inject the <em>Range</em> control using <em>JavaScript</em> / <em>jQuery</em>. To persist the values set through the slider, we have to write back the changed values to the original, hidden <em>Text </em>field.</p>
<p>I’ve created a new custom list called <em>Values </em>on my <em>O365 </em>site, with a numeric field <em>Value</em>. The <em>jQuery</em> library was uploaded to a document library called <em>scripts</em>. Then I injected the following script block using a <em>Content Editor</em> web part into the <em>NewForm.aspx</em> / <em>EditForm.aspx</em> pages:</p>
<div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:33a47e2d-4557-41fd-8ef0-c5ee3e27dedf" class="wlWriterEditableSmartContent" style="float:none;margin:0;display:inline;padding:0;">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:300px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li>&lt;script language=<span style="color:#800000;">&quot;javascript&quot;</span> src=<span style="color:#800000;">&quot;/scripts/jquery-1.8.3.min.js&quot;</span> type=<span style="color:#800000;">&quot;text/javascript&quot;</span>&gt;&lt;/script&gt; </li>
<li style="background:#f3f3f3;">&lt;script language=<span style="color:#800000;">&quot;javascript&quot;</span> type=<span style="color:#800000;">&quot;text/javascript&quot;</span>&gt;</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    $(document).ready(startAction);</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">function</span> startAction() {</li>
<li>        <span style="color:#006400;">// hide original Text input field</span></li>
<li style="background:#f3f3f3;">        $(<span style="color:#800000;">&quot;input[title$=Value]&quot;</span>).hide();</li>
<li>        <span style="color:#006400;">// inject our range control that allows entering values between 0 and 10</span></li>
<li style="background:#f3f3f3;">        $(<span style="color:#800000;">&quot;input[title$=Value]&quot;</span>).before(<span style="color:#800000;">&#039;&lt;input id=&quot;myRange&quot; type=&quot;range&quot; min=&quot;0&quot; max=&quot;10&quot;/&gt;&amp;nbsp;&lt;span id=&quot;myRangeValue&quot;/&gt;&#039;</span>);</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">var</span> cv = $(<span style="color:#800000;">&quot;input[title$=Value]&quot;</span>).val();</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="color:#006400;">// if the value is empty, set a default value of 0</span></li>
<li>        cv = (cv == <span style="color:#800000;">&quot;&quot;</span>) ? 0 : cv;</li>
<li style="background:#f3f3f3;">        $(<span style="color:#800000;">&quot;input[title$=Value]&quot;</span>).val(cv);</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="color:#006400;">// synchronize initial values</span></li>
<li>        $(<span style="color:#800000;">&quot;input#myRange&quot;</span>).val(cv);</li>
<li style="background:#f3f3f3;">        $(<span style="color:#800000;">&quot;span#myRangeValue&quot;</span>).html(cv);</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="color:#006400;">// register change event handler</span></li>
<li>        $(<span style="color:#800000;">&quot;input#myRange&quot;</span>).change(<span style="color:#0000ff;">function</span>() { updateValue(); });</li>
<li style="background:#f3f3f3;">    }    </li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">function</span> updateValue() {</li>
<li>        <span style="color:#0000ff;">var</span> cv = $(<span style="color:#800000;">&quot;input#myRange&quot;</span>).val();</li>
<li style="background:#f3f3f3;">        $(<span style="color:#800000;">&quot;input[title$=Value]&quot;</span>).val(cv);</li>
<li>        $(<span style="color:#800000;">&quot;span#myRangeValue&quot;</span>).html(cv);</li>
<li style="background:#f3f3f3;">    }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">&lt;/script&gt;</li>
</ol></div>
</p></div>
</p></div>
<p>The figure below illustrates the effect of the customization. Of course, you need to have a <em>HTML5</em>-compatible browser, like <em>IE10</em> and the browser compatibility mode correctly set using <em>IE developer tools (F12)</em>:</p>
<p><a href="http://pholpar.files.wordpress.com/2013/04/image.png"><img title="image" style="border-top:0;border-right:0;background-image:none;border-bottom:0;padding-top:0;padding-left:0;border-left:0;display:inline;padding-right:0;" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/04/image_thumb.png?w=565&#038;h=175" width="565" height="175" /></a></p>
<p>And what’s with <em>SharePoint 2010</em>? There are options to enable <em>HTML5</em> for <em>SharePoint 2010</em> (see a solution <a href="http://blogs.msdn.com/b/chhopkin/archive/2012/05/25/enable-html-5-in-sharepoint-2010-specifically-for-overlays-in-visio-services.aspx">here</a>), however be aware, that it may have negative impacts on other vital <em>SharePoint</em> features, as described <a href="http://get-spblog.com/2012/05/23/html5-sp2010/">here</a>. I’ve tested the same solution with <em>SP2010</em>, and it seems to be OK, nevertheless, I suggest you to turn on <em>HTML5</em> support only for the affected pages, setting their master page to a custom one as described in the referenced article, and not altering the default master page for the site.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pholpar.wordpress.com/1103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pholpar.wordpress.com/1103/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1103&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pholpar.wordpress.com/2013/04/17/replacing-the-standard-textbox-for-numeric-fields-with-a-slider-using-html5/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/31db6921f6eddb38f5f86b0a220dbd58?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pholpar</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/04/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>How to use LINQ expressions in your JavaScript code when accessing the REST API (and other useful JavaScript libraries)</title>
		<link>http://pholpar.wordpress.com/2013/04/17/how-to-use-linq-expressions-in-your-javascript-code-when-accessing-the-rest-api-and-other-useful-javascript-libraries/</link>
		<comments>http://pholpar.wordpress.com/2013/04/17/how-to-use-linq-expressions-in-your-javascript-code-when-accessing-the-rest-api-and-other-useful-javascript-libraries/#comments</comments>
		<pubDate>Wed, 17 Apr 2013 03:24:21 +0000</pubDate>
		<dc:creator>Peter Holpar</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[Project Server]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[SP 2010]]></category>
		<category><![CDATA[SP 2013]]></category>

		<guid isPermaLink="false">https://pholpar.wordpress.com/?p=1099</guid>
		<description><![CDATA[Working with both C# and JavaScript to process and display information stored on Project Server, I had to realize the power of LINQ in C#, and the lack of this language feature in JavaScript. Fortunately, after a quick search I found the LINQ for JavaScript library, that enables a very similar syntax. Below I show [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1099&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Working with both <em>C#</em> and <em>JavaScript</em> to process and display information stored on <em>Project Server</em>, I had to realize the power of <em>LINQ</em> in <em>C#</em>, and the lack of this language feature in <em>JavaScript</em>. Fortunately, after a quick search I found the <em><a href="http://linqjs.codeplex.com/">LINQ for JavaScript</a></em> library, that enables a very similar syntax. Below I show a few examples to give you a highlight of its features.</p>
<p>The other handy library I use these days frequently is <a href="http://www.datejs.com/"><em>Datejs</em></a>, that enables effective handling of the <em>Date</em> objects in <em>JavaScript</em>.</p>
<p>Although the code samples in this post are related to <em>Project Server</em>, you can apply the same technique to <em>SharePoint</em> as well. For the sake of simplicity I post only code snippets, and not the full code of the application. Hopefully it will be enough to demonstrate the power of these libraries.</p>
<h3>LINQ for JavaScript </h3>
<p><strong>Note</strong>, that I’m using version <em>3.0.3-Beta4</em> in the samples below, and not the stable <em>2.2.0.2</em> version. There are considerable syntax differences between these versions, like lower case vs. upper case function names, so be sure the check the <em>reference.htm</em> coming with the actual version of your choice.</p>
<p>See <a href="http://pholpar.wordpress.com/2013/03/28/limitations-of-the-expand-rest-query-option-when-working-with-project-server-odata-services/">my former post</a> about using and limitations of the <em>$expand</em> query option.</p>
<p>In the first step I send a few <em>REST</em> request to the server and store the results in <em>JavaScript</em> object trees.</p>
<p>The sample below sends a <em>REST</em> request to the <em>Project Server</em> to query information, like <em>Name</em>, <em>Id</em> and <em>ResourceCalendarExceptions</em> properties of the enterprise resources as well as the <em>Name</em> of their <em>BaseCalendar</em> property. We need the response as a <em>JSON</em> stream, so we set the <em>Accept</em> header to &#8216;<em>application/json; odata=verbose</em>&#8216;. If the call was successful, the result is stored in the <em>resources</em> variable.</p>
<p><em>var siteFullUrl = &#8216;<a href="http://yourProjectSite&#038;#8217" rel="nofollow">http://yourProjectSite&#038;#8217</a>;;</em></p>
<p><em>var resources;      <br />var calendars;       <br />var assignments;       <br /></em></p>
<p><em>$.ajax({      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; type: &#8216;GET&#8217;,&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; contentType: &#8216;application/json;odata=verbose&#8217;,       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; url: siteFullUrl + &quot;/sites/pwa/_api/ProjectServer/EnterpriseResources?$select=Name,Id,ResourceCalendarExceptions,BaseCalendar/Name&amp;$expand=ResourceCalendarExceptions,BaseCalendar/Name&quot;,       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; headers: {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8216;X-RequestDigest&#8217;: $(&#8216;#__REQUESTDIGEST&#8217;).val(),       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8216;Accept&#8217;: &#8216;application/json; odata=verbose&#8217;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; },       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dataType: &#8216;json&#8217;,       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; complete: function (result) {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var response = JSON.parse(result.responseText);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (response.error) {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; alert(&quot;Error: &quot; + response.error.code + &quot;\n&quot; + response.error.message.value);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; resources = response.d.results;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />});</em></p>
<p>We can request the enterprise calendar data (name and exceptions) using a similar call of <em>jQuery AJAX</em> method, but in this case the <em>URL</em> of the <em>REST</em> query looks like this one below:</p>
<p><em>&quot;/sites/pwa/_api/ProjectServer/Calendars?$select=Name,BaseCalendarExceptions&amp;$expand=BaseCalendarExceptions&quot;</em></p>
<p>and we store the response in the <em>calendars</em> variable.</p>
<p><em>calendars = response.d.results;</em></p>
<p>To to get the assignments for March I submitted a REST request with the following URL:</p>
<p><em>&quot;/sites/pwa/_api/ProjectData/Assignments?$select=ResourceId,ProjectName,AssignmentStartDate,AssignmentFinishDate,AssignmentBookingId&amp;$filter=AssignmentStartDate+le+datetime&#8217;2013-03-31&#8242; and AssignmentFinishDate+ge+datetime&#8217;2013-03-01&#8242;&quot;</em></p>
<p>and stored the results in the <em>assignments</em> variable:</p>
<p><em>assignments = response.d.results;</em>     </p>
<p>Having all of the responses on the client side, we can process them using a code like this one:</p>
<p><em>// default enterprise base calendar      <br />var wdExcs = calendars[0].BaseCalendarExceptions.results;</em></p>
<p><em>$.each(resources, function (index) {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; // get the calendar exceptions of the current resource       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var wdExcsPriv = this.ResourceCalendarExceptions.results;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var resId = this.Id;</em></p>
<p><em>&#160;&#160;&#160;&#160;&#160;&#160;&#160; // get all assignments of the current resource      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var assignmentsPriv = Enumerable.from(assignments).where(function(x) { return (x.ResourceId == resId); }).toArray();       </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; // get the first day of the current month, that was 1st of March at the time of test       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var day = Date.today();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var day = day.moveToFirstDayOfMonth();       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var dayOfWeek = day.getDay();</em></p>
<p><em>&#160;&#160;&#160;&#160;&#160;&#160;&#160; var assignmentsForThisDay = Enumerable.from(assignmentsPriv).where(function(x) { return (new Date(parseInt(x.AssignmentStartDate.substr(6))) &lt;= day) &amp;&amp; (new Date(parseInt(x.AssignmentFinishDate.substr(6))) &gt;= day) }).toArray();</em></p>
<p><em>&#160;&#160;&#160;&#160;&#160;&#160;&#160; // is it a weekend, a base calendar exception (like state holidays) or a resource exception (private holiday)?      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var isHoliday = ((dayOfWeek == 0) || (dayOfWeek == 6)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; || (Enumerable.from(wdExcs).any(function(x) { return (Date.parse(x.Start) &lt;= day) &amp;&amp; (Date.parse(x.Finish) &gt;= day) }))       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; || (Enumerable.from(wdExcsPriv).any(function(x) { return (Date.parse(x.Start) &lt;= day) &amp;&amp; (Date.parse(x.Finish) &gt;= day) })));</em></p>
<p><em>&#160;&#160;&#160;&#160;&#160;&#160;&#160; // is there at least a single committed assignment or only proposed ones?      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var isBooked = (Enumerable.from(assignmentsForThisDay).any(function(x) { return (x.AssignmentBookingId==0); }));</em></p>
<p><em>&#160;&#160;&#160;&#160;&#160;&#160;&#160; // aggregate (join) the assignment names      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; var projects = (Enumerable.from(assignmentsForThisDay).select(&quot;$.ProjectName&quot;)).join();       </p>
<p>});</em></p>
<h3>Datejs</h3>
<p>You can see <em>Datejs</em> in action in the previous code snippet, like the call of the <em>moveToFirstDayOfMonth</em> function above.</p>
<p>It has a lot of other useful features, for example, to get the number of days in the current month:</p>
<p><em>var month = today.getMonth();     <br />var year = today.getFullYear();      <br />var dayCount = Date.getDaysInMonth(year, month);</em></p>
<p>The <em>getDayDiff</em> function (requires t<em>ime.js</em>) returns the number of days between two dates:</p>
<p><em>function getDayDiff(time1, time2) {     <br />&#160; var timeSpan = new TimeSpan(time1 &#8211; time2);      <br />&#160; var dayCount = timeSpan.getDays() ;      <br />&#160; return dayCount;       <br />}</em></p>
<p>The next snippet sets the variable <em>firstDay </em>to the first day of the current month, and <em>lastDay </em>to the last day of the following month:</p>
<p><em>var firstDay = Date.today();     <br />firstDay.moveToFirstDayOfMonth();</em></p>
<p><em>var lastDay = Date.today().add(1).month();     <br />lastDay.moveToLastDayOfMonth();</em></p>
<p>I’ve been working with these libraries for a few weeks now, and I can say they made my coding more efficient, so I think they worth a try if you have to work with complex <em>REST </em>responses and <em>Date</em> objects from <em>JavaScript</em>, that is very likely if you would like to implement some exciting <em>SharePoint </em>applications based on the new <em>app </em>model.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pholpar.wordpress.com/1099/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pholpar.wordpress.com/1099/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1099&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pholpar.wordpress.com/2013/04/17/how-to-use-linq-expressions-in-your-javascript-code-when-accessing-the-rest-api-and-other-useful-javascript-libraries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/31db6921f6eddb38f5f86b0a220dbd58?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pholpar</media:title>
		</media:content>
	</item>
		<item>
		<title>Dynamically populating Group Calendars, Part I &#8211; the basics</title>
		<link>http://pholpar.wordpress.com/2013/03/28/dynamically-populating-group-calendars-part-i-the-basics/</link>
		<comments>http://pholpar.wordpress.com/2013/03/28/dynamically-populating-group-calendars-part-i-the-basics/#comments</comments>
		<pubDate>Thu, 28 Mar 2013 12:54:41 +0000</pubDate>
		<dc:creator>Peter Holpar</dc:creator>
				<category><![CDATA[Calendar]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[SP 2010]]></category>

		<guid isPermaLink="false">https://pholpar.wordpress.com/?p=1097</guid>
		<description><![CDATA[A few month ago I was working on a prototype of an internal SharePoint application to make it easier to HR and project managers to track and administer the status (like holiday, sick leave) of the employees. My plan included a group calendar to administer the employee status (note: this feature seems to be already [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1097&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p align="left">A few month ago I was working on a prototype of an internal <em>SharePoint</em> application to make it easier to <em>HR</em> and project managers to track and administer the status (like holiday, sick leave) of the employees.</p>
<p align="left">My plan included a group calendar to administer the employee status (<strong>note</strong>: this feature seems to be already obsolete in <em>SP 2013</em>, see section <em>Group Work site template and Group Work </em>solution on <a href="http://technet.microsoft.com/en-us/library/ff607742.aspx"><em>TechNet</em></a>). User should be able to choose a project from the ribbon, and the calendars of the project members would be displayed in the group calendar view. The ribbon extension itself was not difficult (I will discuss it in the next part of this post), however the dynamic refresh of the group calendar <em>UI</em> was really a bit challenging. The main topic of this post is how to add / remove users to / from the group calendar.</p>
<p align="left">The only <a href="http://zepeda-mcmillan.blogspot.co.at/2011/03/displaying-default-resources-on-group.html">post</a> I found on a similar issue is related to resources (I recommend you to read that post first, as I don’t repeat all of the details discussed there!), but it provided at least a good starting point for me, and the discovery of the <em>JavaScript </em>libraries and a lot of <a href="http://www.fiddler2.com/">fiddlering</a> began…</p>
<p align="left">I won’t describe here all the steps I followed, but rather the most important results.</p>
<p align="left"><strong>Note</strong>: that the methods and properties below are not officially documented, and using them from your custom code is not supported. Be aware, that they can be changed due to Service Packs or other updates without any prior notice, immediately breaking solutions build upon these techniques, so use them at your own risks.</p>
<p align="left">The bulk of the functionality related to the group calendar is encapsulated into the <em>SP.UI.ApplicationPages.Calendar.js</em> (see the debug version: <em>SP.UI.ApplicationPages.Calendar.debug.js</em>). If not mentioned otherwise, all of the described <em>JS </em>objects can be found in this file.</p>
<p align="left">The <em>SP.UI.ApplicationPages.ResolveEntity </em>(defined in <em>SP.js</em> / <em>SP.debug.js</em>) is primarily a data container to hold information on a calendar entity resolved by <em>SharePoint</em>.</p>
<p align="left">When you add a new user, group or resource entity to the group calendar (for example using the <em>People Picker,</em> either the text box or the dialog), or add / edit / delete events, the calendar control sends an asynchronous request to the server to resolve the entity to be able to refresh the UI, and the “<em>Loading calendar…</em>” message is displayed.</p>
<p align="left"><a href="http://pholpar.files.wordpress.com/2013/03/image26.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb22.png?w=217&#038;h=74" width="217" height="74" /></a></p>
<p align="left">To provide the async communication between the calendar control on the webpage and the data on the server side, the <em>CalendarService.ashx</em> ASP.NET Web Handler is used. For example, if we are adding the calendar of the <em>CONTOSO Administrator</em> to the group calendar the following data is send through a POST request to <em>/_layouts/CalendarService.ashx</em>:</p>
<p align="left"><em>cmd=query&amp;listName=ecd80beb-7ba7-4ad0-810a-3e2a95f07c30&amp;viewName=e7d89ac0-7bd6-42b7-9ee5-de7e8b4773bb&amp;dataSourceId=00000000-0000-0000-0000-000000000000&amp;viewType=weekgroup&amp;entity=1;#CONTOSO\administrator;Administrator@contoso.com&amp;selectedDate=&amp;options=1</em></p>
<p align="left"><a href="http://pholpar.files.wordpress.com/2013/03/image27.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb23.png?w=490&#038;h=484" width="490" height="484" /></a></p>
<p align="left">The response is a <em>JSON</em> representation of the events for the <em>Administrator</em> (assuming this user has a single meeting as illustrated above):</p>
<p align="left"><em>[{&quot;Options&quot;:1,&quot;Table&quot;:null,&quot;DatePicker&quot;:null,&quot;Dates&quot;:null,&quot;RangeJDay&quot;:null,&quot;Navs&quot;:null,&quot;Items&quot;:{&quot;Data&quot;:[[0,1,2,150563,150563,3,3,4,5,5,0,60,0,0,0,6,7]],&quot;Strings&quot;:[&quot;8&quot;,&quot;Admin event&quot;,&quot;Office&quot;,&quot;3/25/2013&quot;,&quot;5:00 am&quot;,&quot;6:00 am&quot;,&quot;&quot;,&quot;0x7fffffffffffffff&quot;]}}]</em></p>
<p align="left">or as visualized by <em>Fiddler</em>:</p>
<p align="left"><a href="http://pholpar.files.wordpress.com/2013/03/image28.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb24.png?w=155&#038;h=484" width="155" height="484" /></a></p>
<p>Parameters sent to the <em>CalendarService.ashx</em> should be straightforward. The parameter <em>entity</em> is the key of the entity (in this case <em>1;#CONTOSO\administrator;Administrator@contoso.com</em>) to be resolved, we have this value from the <em>People Picker</em>. I don’t discuss now the process<em>, </em>how the <em>People Picker</em> gets this values when resolving users asynchronously, it would worth another post.</p>
<p>See the <em>get_key</em> function of the <em>ResolveEntity</em> object to understand how the key for different entity types are built up. For example, in case of a user having an e-mail address the key (<em>$8_0</em> property of the <em>ResolveEntity</em>) looks like this:</p>
<p align="left"><em>this.$8_0 = &#8217;1;#&#8217; + this.accountName + &#8216;;&#8217; + this.email;</em></p>
<p align="left">Compare this pattern with the value we used above for <em>CONTOSO\administrator</em>.</p>
<p align="left">The <em>entityType</em> property of the <em>ResolveEntity</em> defines the type of entity. Supported values are:</p>
<p><em>SP.UI.ApplicationPages.ResolveEntity.typE_EVENT = &#8217;0&#8242;;     <br />SP.UI.ApplicationPages.ResolveEntity.typE_USER = &#8217;1&#8242;;      <br />SP.UI.ApplicationPages.ResolveEntity.typE_RESOURCE = &#8217;2&#8242;;      <br />SP.UI.ApplicationPages.ResolveEntity.typE_EXCHANGE = &#8217;3&#8242;;</em></p>
<p align="left">The value <em>typE_USER</em> means either a user or a group, the <em>isGroup </em>property of the <em>ResolveEntity</em> object makes a difference between user and group subtypes.</p>
<h5 align="left">How to add entities to the calendar?</h5>
<p align="left">We should use the <em>SP.UI.ApplicationPages.CalendarSelector </em>(defined in <em>SP.js</em> / <em>SP.debug.js</em>) and the <em>SP.UI.ApplicationPages.RibbonCalendarSelector</em> (defined in <em>SP.UI.ApplicationPages.Calendar.js</em> / <em>SP.UI.ApplicationPages.Calendar.debug.js</em>) objects to achieve this goal. </p>
<p><em>// calSel is of tpye SP.UI.ApplicationPages.CalendarSelector     <br />var calSel = SP.UI.ApplicationPages.CalendarSelector.instance();      <br />// sel is of tpye SP.UI.ApplicationPages.RibbonCalendarSelector      <br />var sel = calSel.getSelector(1, scopeKey);      <br />sel.selectEntities(entitiesXml, false);</em></p>
<p>By calling the <em>getSelector </em>function the the fix value of <em>1</em> means a user entity type, and <em>scopeKey</em> is the context identifier for the calendar, and can be extracted from the page content when working with <em>jQuery</em>:</p>
<p><em>var calRootDiv = jQuery(&quot;.ms-acal-rootdiv&quot;);     <br />var scopeKey = jQuery(calRootDiv).attr(&#8216;ctxid&#8217;);</em></p>
<p>The entities defined by the <em>entitiesXml</em> will be appended to the existing list of items in the calendar. The format of the <em>XML</em> is shown for resources in the <a href="http://zepeda-mcmillan.blogspot.co.at/2011/03/displaying-default-resources-on-group.html">original post from Thomas Zepeda McMillan</a>, and will be further investigated for user entities in my forthcoming post.</p>
<h5>How to remove entities from the calendar?</h5>
<p>You can think that setting the <em>Append</em> attribute of the <em>Entities</em> node of the <em>XML</em> we pass as parameter to the <em>selectEntities</em> function to a value to <em>False</em> has the effect that the new entities would be not appended to the existing list of entities, but the former entities would be cleared first, however, based on my experience, that is not the case. So we have to find a way to remove existing entities first.</p>
<p>As a first step, we could lookup the <em>SP.UI.ApplicationPages.CalendarContainer</em> for the specific scope (the <em>SP.UI.ApplicationPages.CalendarInstanceRepository</em> object is defined in <em>SP.js</em> / <em>SP.debug.js</em>):</p>
<p><em>var calCont = SP.UI.ApplicationPages.CalendarInstanceRepository.lookupInstance(scopeKey);</em></p>
<p>Using this <em>CalendarContainer</em> we can get a reference to the <em>SP.UI.ApplicationPages.EntityPaginator</em>:</p>
<p><em>var entPag = calCont.$a_1;</em></p>
<p>Entities displayed on the calendar are stored as an&#160; <em>Array</em> of <em>SP.UI.ApplicationPages.ResolveEntity</em> objects:</p>
<p><em>var arr = entPag.$1y_1;      <br /></em><em>// just test: display some of the properties     <br />alert(arr[0].entityType + &#8216;, &#8216; + arr[0].get_key() + &#8216;, &#8216; + arr[0].displayName + &#8216;, &#8216; + arr[0].accountName);</em></p>
<p align="left">The <em>$AH </em>function of the <em>EntityPaginator</em> removes the item with the specified index from the array plus refreshes the <em>UI</em>. For example, to remove first entity we should call:</p>
<p align="left"><em>entPag.$AH(0);</em></p>
<p>To remove all of the items, we should iterate through the array:</p>
<p> <em>while(arr.length &gt; 0) {    <br />&#160; entPag.$AH(0);     <br />}</em>
<p>The <em>$5P_1</em> method of <em>EntityPaginator</em> notifies all event handlers of &quot;<em>pagechanged</em>&quot; to force a control refresh. We should be able to remove all of the entities via clearing the <em>Array</em> content and call the <em>$5P_1</em> method to refresh the <em>UI</em> directly as:</p>
<p> <em>Array.clear(arr); // or <em>Array.clear(<em>entPag.$AH</em>); </em>    <br />entPag.$5P_1();</em>
<p>however I found that this method – although might seem OK at first sight – is not working perfectly, especially when one would like to page in calendar between weeks.</p>
<h5>Handling calendar paging / refresh events</h5>
<p>Although not strictly related to the topic, it may be useful to know, that we can subscribe our custom event handlers for such events.</p>
<p>Using the <em>add_$9x</em> and the <em>remove_$9x</em> functions of the <em>EntityPaginator</em> can we inject (and remove) our event handlers for calendar refresh events (like paging):</p>
<p><em>entPag.add_$9x(Function.createDelegate(null, function() { alert(&#8216;paged&#8217;); } )); </em></p>
<p>or alternatively we can apply a direct approach like this one:</p>
<p> <em>function pageChanged() {    <br />&#160; alert(&#8216;page changed&#8217;);     <br />}</em>
<p><em>entPag.get_events().addHandler(&#8216;pagechanged&#8217;, pageChanged);</em> </p>
<h5>Next steps</h5>
<p>In this post I discussed the fundamentals we need to fulfill the original goal to create a dynamic group calendar view. In the next post I show you how to develop the ribbon extension that utilizes the methods described now.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pholpar.wordpress.com/1097/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pholpar.wordpress.com/1097/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1097&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pholpar.wordpress.com/2013/03/28/dynamically-populating-group-calendars-part-i-the-basics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/31db6921f6eddb38f5f86b0a220dbd58?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pholpar</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb22.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb23.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb24.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Limitations of the $expand REST query option when working with Project Server OData services</title>
		<link>http://pholpar.wordpress.com/2013/03/28/limitations-of-the-expand-rest-query-option-when-working-with-project-server-odata-services/</link>
		<comments>http://pholpar.wordpress.com/2013/03/28/limitations-of-the-expand-rest-query-option-when-working-with-project-server-odata-services/#comments</comments>
		<pubDate>Thu, 28 Mar 2013 12:43:22 +0000</pubDate>
		<dc:creator>Peter Holpar</dc:creator>
				<category><![CDATA[Project Online]]></category>
		<category><![CDATA[PS 2013]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">https://pholpar.wordpress.com/?p=1089</guid>
		<description><![CDATA[Recently I prepared a REST request for the ProjectData service of Project Server. I assembled the following simple query using LINQPad : from a in Assignments select new { &#160; a.Resource.ResourceCanLevel, &#160; a.ProjectName, &#160; a.ResourceName } LINQPad sent the following query to the server: http://yourProjectSite/_api/ProjectData/Assignments()?$expand=Resource&#38;$select=Resource/ResourceCanLevel,ProjectName,ResourceName The server responded with: Unsupported query option encountered: $expand I [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1089&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Recently I prepared a <em>REST</em> request for the <em>ProjectData</em> service of <em>Project Server</em>. I assembled the following simple query using <em>LINQPad</em> :</p>
<p><em>from a in Assignments     <br />select new       <br />{      <br />&#160; a.Resource.ResourceCanLevel,      <br />&#160; a.ProjectName,      <br />&#160; a.ResourceName      <br />}</em></p>
<p><em>LINQPad </em>sent the following query to the server:</p>
<p><em><a href="http://yourProjectSite/_api/ProjectData/Assignments()" rel="nofollow">http://yourProjectSite/_api/ProjectData/Assignments()</a>?$expand=Resource&amp;$select=Resource/ResourceCanLevel,ProjectName,ResourceName</em></p>
<p>The server responded with:</p>
<p><em>Unsupported query option encountered: $expand</em></p>
<p>I tried to submit a similar query, but specified exactly the property I needed (used <em>Resource/ResourceCanLevel</em> in place of former value <em>Resource</em>) in the <em>$expand</em> option:</p>
<p><em><a href="http://yourProjectSite/_api/ProjectData/Assignments?$select=Resource/ResourceCanLevel,ResourceName,ProjectName&#038;$expand=Resource/ResourceCanLevel" rel="nofollow">http://yourProjectSite/_api/ProjectData/Assignments?$select=Resource/ResourceCanLevel,ResourceName,ProjectName&#038;$expand=Resource/ResourceCanLevel</a></em></p>
<p>The response did not change.</p>
<p>Then – as a last desperate try – I’ve tried to simply omit the <em>$expand</em> option, like this:</p>
<p><em><a href="http://yourProjectSite/_api/ProjectData/Assignments?$select=Resource/ResourceCanLevel,ResourceName,ProjectName" rel="nofollow">http://yourProjectSite/_api/ProjectData/Assignments?$select=Resource/ResourceCanLevel,ResourceName,ProjectName</a></em></p>
<p>Of course, I’ve received this message:</p>
<p><em>Only properties specified in $expand can be traversed in $select query options</em></p>
<p>The reason and explanation for this behavior I found as a note on <a href="http://msdn.microsoft.com/en-us/library/office/jj163015.aspx">MSDN</a>:</p>
<p><em>”<strong>The ProjectData service does not implement the $links query option or the $expand query option.</strong> Excel 2013 internally uses the Association elements and the AssociationSet elements in the entity data model to help create associations between entities, for pivot tables and other constructs.”</em></p>
<p>Bad enough… The good news: the <em>ProjectServer</em> service (<em>_api/ProjectServer</em>) has no such limitation.    </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pholpar.wordpress.com/1089/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pholpar.wordpress.com/1089/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1089&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pholpar.wordpress.com/2013/03/28/limitations-of-the-expand-rest-query-option-when-working-with-project-server-odata-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/31db6921f6eddb38f5f86b0a220dbd58?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pholpar</media:title>
		</media:content>
	</item>
		<item>
		<title>Accessing Office 365 REST services using LINQPad</title>
		<link>http://pholpar.wordpress.com/2013/03/08/accessing-office-365-rest-services-using-linqpad/</link>
		<comments>http://pholpar.wordpress.com/2013/03/08/accessing-office-365-rest-services-using-linqpad/#comments</comments>
		<pubDate>Fri, 08 Mar 2013 13:12:43 +0000</pubDate>
		<dc:creator>Peter Holpar</dc:creator>
				<category><![CDATA[Fiddler]]></category>
		<category><![CDATA[LINQPad]]></category>
		<category><![CDATA[OData]]></category>
		<category><![CDATA[Office 365]]></category>
		<category><![CDATA[Project Online]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Tips & Tricks]]></category>

		<guid isPermaLink="false">https://pholpar.wordpress.com/?p=1076</guid>
		<description><![CDATA[LINQPad is a great tool, even for a SharePoint developer when working with the RESTful web services. However, it does not provide an authentication mechanism against Office 365, a major issue when there is no on-premise SharePoint or Project Server at your hand to develop and test your queries (as suggested by Andrew Lavinsky in [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1076&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.linqpad.net/"><em>LINQPad</em></a> is a great tool, even for a <em>SharePoint</em> developer when working with the <a href="http://www.mssharepointtips.com/tip.asp?id=1179"><em>REST</em>ful web services</a>. However, it does not provide an authentication mechanism against <em>Office 365</em>, a major issue when there is no on-premise <em>SharePoint</em> or <em>Project Server </em>at your hand to develop and test your queries (as suggested by <em>Andrew Lavinsky</em> in <a href="http://azlav.umtblog.com/2012/10/21/first-look-querying-project-server-2013-odata-with-linqpad/">this post</a>), as illustrated by the figures below.</p>
<p>We add a new connection of type <em>WCF Data Service 5.1 (OData 3)</em> to <em>LINQPad</em>:</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image9.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb8.png?w=644&#038;h=441" width="644" height="441" /></a></p>
<p>Specify the <em>URI</em> of the <em>ListData.svc </em>at our&#160; <em>O365</em> tenant, and<em> Default (XML)</em> as <em>Formatter</em>.</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image10.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb9.png?w=644&#038;h=365" width="644" height="365" /></a></p>
<p>Then we receive the following error (you can try to specify username and password in the previous step, but it makes no difference):</p>
<p><em>Error: The remote server returned an error: (403) Forbidden.</em></p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image11.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb10.png?w=722&#038;h=93" width="722" height="93" /></a></p>
<p>I’ve found a <a href="http://swatipoint.blogspot.in/2013/01/linqpad-to-query-office-365-odata-rest.html">workaround</a> for this issue on the web, but for me it was so complex at the first sight (even though I later understood how it should work), so I decided to find another way, using my other favorite tool <a href="http://www.fiddler2.com"><em>Fiddler</em></a>.</p>
<p>Our “solution”: we will “cache” the authentication cookies from an <em>Internet Explorer</em> session, then inject the same cookies to the <em>LINQPad</em> sessions.</p>
<p>Start <em>Fiddler</em>, choose <em>Roles</em> / <em>Customize Rules…</em>, and edit the<em> CustomRules.js</em> file (don’t forget to create a backup!).</p>
<p>Before the <em>OnBeforeRequest</em> function add this code:</p>
<p><em>static var authCookies = &quot;&quot;;      <br />static var o365Site = &quot;yourO365Site.sharepoint.com&quot;; // modify this value!</em></p>
<p>At the beginning of the <em>OnBeforeRequest</em> function add this code:</p>
<p><em>if (oSession.HostnameIs(o365Site)) {      <br />&#160; var cookie = oSession.oRequest[&quot;Cookie&quot;];       <br />&#160; if ((cookie == &quot;&quot;) &amp;&amp; (authCookies != &quot;&quot;)) {       <br />&#160;&#160;&#160; //oSession.oRequest[&quot;Accept&quot;] = &quot;text/html, application/xhtml+xml, */*&quot;;       <br />&#160;&#160;&#160; oSession.oRequest[&quot;Cookie&quot;] = authCookies;       <br />&#160; }       <br />}</em></p>
<p>At the beginning of the <em>OnBeforeResponse</em> function add this code:</p>
<p><em>if (oSession.HostnameIs(o365Site)) {      <br />&#160; var cookie = oSession.oRequest[&quot;Cookie&quot;];       <br />&#160; if (cookie != &quot;&quot;) {       <br />&#160;&#160;&#160; authCookies = cookie;       <br />&#160; }       <br />}</em></p>
<p>Done! Save the changes of <em>CustomRules.js</em>. Then (having <em>Fiddler</em> running and capturing network traffic!) start <em>IE</em>, navigate to your <em>O365</em> site, and authenticate yourself when requested. Cookies are cached in <em>Fiddler</em> at this point.</p>
<p><strong>Note</strong>: In my development environment I always enable <em>Fiddler</em> to decrypt <em>HTTPS</em> traffic. I have not tested this solution with decryption disabled, and have doubts, if it should work. If you test it, please, leave us a comment with the results.</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image13.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb11.png?w=562&#038;h=375" width="562" height="375" /></a></p>
<p>In the next step (the same <em>Fiddler</em> instance is still running and capturing network traffic!), try to reconnect <em>LINQPad</em> to the same <em>O365</em> site. Cookies are replayed by <em>Fiddler</em>, authentication in <em>LINQPad</em> should work this time.</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image14.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb12.png?w=417&#038;h=454" width="417" height="454" /></a></p>
<p>To test the functionality, I submitted a simple query:</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image16.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb13.png?w=370&#038;h=363" width="370" height="363" /></a></p>
<p>So far the good news. After “solving” the authentication issue, let’s see a further problem, and that is bound to the <a href="http://sergeluca.wordpress.com/2013/01/20/sharepoint-2013-rest-odata-part-1-readingfetching-information-no-code/">(missing) <em>$metadata</em> support of Microsoft’s <em>OData</em> implementation in <em>SP 2013</em></a>.</p>
<p>As you might have noticed, in the example above I used the “old-style”, <em>SP 2010 </em>compatible version of the <em>REST API</em> (<em>_vti_bin/ListData.svc</em>), and not the “new-school” format, including <em>_api </em>(like <em>_api/web/</em>), and that is no just accidentally.</p>
<p>Since <em>LINQPad</em> needs the <em>$metadata</em> to build up the object structure, it simply does not work without that: </p>
<p>In <em>LINQPad</em>:</p>
<p><em>Error: The remote server returned an error: (404) Not Found.</em></p>
<p><em><a href="http://pholpar.files.wordpress.com/2013/03/image17.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb14.png?w=661&#038;h=43" width="661" height="43" /></a></em></p>
<p>In <em>Fiddler </em>(<em>HTTP </em>status <em>404</em>):</p>
<p><em>Cannot find resource for the request $metadata.</em></p>
<p>One of the workarounds may be (again with <em>Fiddler</em>) to use an existing beta installation of <em>SP 2013</em>, capture the response for the <em>$metadata</em> request to a file, then in the development environment send it as a response for the <em>$metadata</em> request from <em>LINQPad</em> automatically, but it is rather hacky, even for me. In my opinion it simply does not worth monkeying so much with that, we should rather learn and use the syntax of the <em>OData </em>requests.</p>
<p>Developers (including myself) who need to work against <em>Project Online</em> are luckier. Although the <em>OData</em> service of <em>PS</em> seems to be available only through the new <em>_api </em>interface, the <em>$metadata</em> support is still there in this case.</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image18.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb15.png?w=428&#038;h=327" width="428" height="327" /></a></p>
<p>And a sample query:</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image19.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb16.png?w=339&#038;h=342" width="339" height="342" /></a></p>
<p>Have fun using <em>LINQPad</em> against your <em>O365</em> site and <em>Project Online</em>!</p>
<p><strong>UPDATE</strong>: The same trick can be applied, when we would like to add a service reference to our <em>Visual Studio</em> project, referring to an <em>O365</em> / <em>Project Online</em> site (just like described <a href="http://msdn.microsoft.com/en-us/library/office/jj163048.aspx">here</a> for an on-premise <em>PS</em>). Although <em>VS 2012</em> displays an authentication dialog for my – in this case German – <em>O365</em> site (it is not the case with <em>VS 2010</em>), </p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image20.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb17.png?w=452&#038;h=430" width="452" height="430" /></a></p>
<p>it seems to have no effect (at least, not always?):</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image22.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb18.png?w=691&#038;h=289" width="691" height="289" /></a></p>
<p>Note, that based on the error details it is likely not just a simple authentication issue, as <em>VS</em> would like to append <em>/_vti_bin/ListData.svc</em> to the service <em>URL</em>.</p>
<p>In this case you can use <em>Fiddler</em> again to replay the cookies and authenticate on behalf of <em>VS</em>:</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image23.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb19.png?w=598&#038;h=484" width="598" height="484" /></a></p>
<p><strong>UPDATE 2 (3/22/2013)</strong>: I was wrong when I wrote that developers working against <em>Project Online</em> were much luckier. I’ve just realized, that although <em>$metadata</em> is really available for the <em>ProjectData</em> service, it is not supported for the <em>ProjectServer</em> service, that you should use to access entities like enterprise resources, calendars or custom fields (as illustrated by the next screenshot, requesting <em><a href="https://yourProjects.sharepoint.com/sites/pwa/_api/ProjectServer" rel="nofollow">https://yourProjects.sharepoint.com/sites/pwa/_api/ProjectServer</a></em>).</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image24.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb20.png?w=644&#038;h=221" width="644" height="221" /></a></p>
<p>In <em>LINQPad</em>:</p>
<p><em>Error: The remote server returned an error: (404) Not Found.</em></p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image25.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb21.png?w=718&#038;h=38" width="718" height="38" /></a></p>
<p>In <em>Fiddler </em>(<em>HTTP </em>status <em>404</em>):</p>
<p><em>Cannot find resource for the request $metadata.</em></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pholpar.wordpress.com/1076/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pholpar.wordpress.com/1076/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1076&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pholpar.wordpress.com/2013/03/08/accessing-office-365-rest-services-using-linqpad/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/31db6921f6eddb38f5f86b0a220dbd58?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pholpar</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb8.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb9.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb10.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb11.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb12.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb13.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb14.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb15.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb16.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb17.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb18.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb19.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb20.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb21.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Handling calendar exceptions with CSOM on Project Online</title>
		<link>http://pholpar.wordpress.com/2013/03/06/handling-calendar-exceptions-with-csom-on-project-online/</link>
		<comments>http://pholpar.wordpress.com/2013/03/06/handling-calendar-exceptions-with-csom-on-project-online/#comments</comments>
		<pubDate>Wed, 06 Mar 2013 14:28:06 +0000</pubDate>
		<dc:creator>Peter Holpar</dc:creator>
				<category><![CDATA[CSOM]]></category>
		<category><![CDATA[Project Online]]></category>
		<category><![CDATA[PS 2013]]></category>

		<guid isPermaLink="false">https://pholpar.wordpress.com/?p=1057</guid>
		<description><![CDATA[In the recent days I’m busy with Project Online and its CSOM API (if you would like to avoid some traps, see my first experiences with the Project 2013 SDK here). One of the tasks includes manipulating calendar exceptions for enterprise resources, like creating, listing and deleting calendar exceptions for our resources (I mean colleagues) [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1057&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In the recent days I’m busy with <em>Project Online </em>and its <em>CSOM API</em> (if you would like to avoid some traps, see my first experiences with the Project 2013 SDK <a href="http://pholpar.wordpress.com/2013/03/05/first-steps-with-the-project-2013-sdk-and-using-the-new-csom-of-project-server-2013/">here</a>). One of the tasks includes manipulating calendar exceptions for enterprise resources, like creating, listing and deleting calendar exceptions for our resources (I mean colleagues) as their holiday requests get approved / rejected.</p>
<p>I should note, that editing calendar exceptions seems to be not available on the <em>Project Server</em> user interface, only using the desktop client <em>Project Professional</em>. As far as I see (using <em>Fiddler</em>), <em>Project Professional</em> still uses the <em>Project Server Interface (PSI) </em>web services, although it is officially not the way we have to choose when working against <em>Project Online</em>:</p>
<p><em>“To develop applications for Project Online, you must use the Microsoft.ProjectServer.Client namespace instead of the PSI.” </em>(source: <a href="http://msdn.microsoft.com/en-us/library/office/ms488627.aspx"><em>MSDN</em></a>)</p>
<p>I made some quick checks, and technically (with some minor hacks) it still seems to be possible to use <em>PSI</em> with <em>Project Online</em>, but let’s try to keep with <em>CSOM</em> this time, at least as long as it covers our needs.</p>
<p>Before delving deeper into code details, you can find some useful links about authentication against <em>O365</em> in <a href="http://pholpar.wordpress.com/2013/01/09/using-ie-as-a-local-host-for-sharepoint-ecmascript-client-object-model-the-office-365-version/">my former post</a>, that I suggest to read as we apply a similar technique in this case.</p>
<p>I’ve created a new console application (<em>C#,</em> Target framework: <em>.NET framework 4</em>, Platform target: <em>x86</em>), and added some assembly references as shown below. To have <em>Microsoft.IdentityModel</em>, you should download the <a href="http://www.microsoft.com/en-us/download/details.aspx?id=4451"><em>Windows Identity Foundation SDK 3.5</em></a>.</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image7.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb6.png?w=267&#038;h=348" width="267" height="348" /></a></p>
<p>I borrowed the helper classes <em>Office365ClaimsHelper</em> and <em>WcfClientContracts</em> from <a href="http://msmvps.com/blogs/sundar_narasiman/archive/2012/11/18/manipulate-taxonomy-objects-using-sharepoint-2013-client-object-model.aspx">this post</a> of <em>Sundararajan Narasiman</em>. The link to the source code of those classes can be found at the bottom of that post. You should alter the namespace of the classes to match the one of your application.</p>
<p>I’ve created an internal static <em>ProjectOnlineTest </em>class to wrap the functionality, with the following namespaces imported:</p>
<p><em>using System;     <br />using System.Collections.Generic;      <br />using System.Linq;      <br />using System.Text;      <br />using System.Net;      <br />using Microsoft.ProjectServer.Client;</em></p>
<p>The most important values are declared first, you should edit them to match your own site and user credentials.</p>
<p>
<div style="margin:0;display:inline;float:none;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:dff8e0a7-cd0a-4ef4-86cb-bf1569a620a5" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:300px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">private</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">readonly</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;"> projName;</span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">private</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">readonly</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;"> connectUserName;</span></li>
<li><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">private</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">readonly</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;"> connectPwd;  </span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">private</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">readonly</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;"> pwaPath;</span></li>
<li><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">private</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">readonly</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;"> projDomain;</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> ProjectOnlineTest()</span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;">{</span></li>
<li>    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#008000;">// update the values here</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">projName = </span><span style="background:#ffffff;color:#a31515;">&quot;YourProjSite&quot;</span><span style="background:#ffffff;color:#000000;">;</span></li>
<li>    <span style="background:#ffffff;color:#000000;">connectUserName = </span><span style="background:#ffffff;color:#a31515;">&quot;john.smith&quot;</span><span style="background:#ffffff;color:#000000;">;</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">connectPwd = </span><span style="background:#ffffff;color:#a31515;">&quot;password&quot;</span><span style="background:#ffffff;color:#000000;">;</span></li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">projDomain= </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;">.Format(</span><span style="background:#ffffff;color:#a31515;">&quot;{0}.onmicrosoft.com&quot;</span><span style="background:#ffffff;color:#000000;">, projName);</span></li>
<li>    <span style="background:#ffffff;color:#000000;">pwaPath = </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;">.Format(</span><span style="background:#ffffff;color:#a31515;">&quot;<a href="https://" rel="nofollow">https://</a>{0}.sharepoint.com/sites/pwa&quot;</span><span style="background:#ffffff;color:#000000;">, projName);</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li><span style="background:#ffffff;color:#000000;">}</span></li>
</ol></div>
</p></div>
</p></div>
</p>
<p>I added some helper properties and a method to make my code a bit simpler to read and modify. Note the format of the <em>Project Online</em> user name in the <em>GetFullUserName</em> method.</p>
<div style="margin:0;display:inline;float:none;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:539a1c77-e10d-4300-9944-5043faea1018" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:300px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">private</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#2b91af;">ProjectContext</span><span style="background:#ffffff;color:#000000;"> ProjectContext</span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;">{</span></li>
<li>    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">get</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">{</span></li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> pc = </span><span style="background:#ffffff;color:#0000ff;">new</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#2b91af;">ProjectContext</span><span style="background:#ffffff;color:#000000;">(pwaPath);</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> claimsHelper = ClaimsHelper;</span></li>
<li>        <span style="background:#ffffff;color:#000000;">pc.ExecutingWebRequest += claimsHelper.clientContext_ExecutingWebRequest;</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">return</span><span style="background:#ffffff;color:#000000;"> pc;</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">}</span></li>
<li><span style="background:#ffffff;color:#000000;">}</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">private</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#2b91af;">Office365ClaimsHelper</span><span style="background:#ffffff;color:#000000;"> ClaimsHelper</span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;">{</span></li>
<li>    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">get</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">{</span></li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">return</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">new</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#2b91af;">Office365ClaimsHelper</span><span style="background:#ffffff;color:#000000;">(</span><span style="background:#ffffff;color:#0000ff;">new</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#2b91af;">Uri</span><span style="background:#ffffff;color:#000000;">(pwaPath),</span></li>
<li style="background:#f3f3f3;">                                            <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;">.Format(</span><span style="background:#ffffff;color:#a31515;">&quot;{0}@{1}&quot;</span><span style="background:#ffffff;color:#000000;">, connectUserName, projDomain),</span></li>
<li>                                            <span style="background:#ffffff;color:#000000;">connectPwd);</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">}</span></li>
<li><span style="background:#ffffff;color:#000000;">}</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">private</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;"> GetFullUserName(</span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;"> userName)</span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;">{</span></li>
<li>    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">return</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;">.Format(</span><span style="background:#ffffff;color:#a31515;">&quot;i:0#.f|membership|{0}@{1}&quot;</span><span style="background:#ffffff;color:#000000;">, userName, projDomain);</span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;">}</span></li>
</ol></div>
</p></div>
</p></div>
<p>The <em>CreateCalendarException</em> method creates a new calendar exception for the resource (user). The key is to use the <em>CalendarExceptionCreationInformation </em>class and calling the <em>Update </em>method of the <em>EnterpriseResourceCollection </em>class. Credits go for the latter one again to <a href="http://social.msdn.microsoft.com/profile/jim%20%20corbin/?ws=usercard-mini"><em>Jim Corbin</em></a>, the member of the <em>Microsoft Project SDK </em>team:</p>
<p>“<em>When you make a change to one of the properties, and then save the change, Project Server automatically checks out the resource, make the change, and checks the resource back in &#8212; similar to the process of getting an enterprise resource in Project Pro, editing it, and then saving.</em>” (source: <a href="http://social.msdn.microsoft.com/Forums/en-US/project2010custprog/thread/a2852b09-90b9-40ad-bb06-8131cc3c05fb"><em>MSDN Forum</em> thread</a>)</p>
<div style="margin:0;display:inline;float:none;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b29ea8f9-4222-41fc-83ed-264ce2b98c8f" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:400px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">internal</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">void</span><span style="background:#ffffff;color:#000000;"> CreateCalendarException(</span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;"> userName, </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;"> exceptionName, </span><span style="background:#ffffff;color:#2b91af;">DateTime</span><span style="background:#ffffff;color:#000000;"> exceptionStart, </span><span style="background:#ffffff;color:#2b91af;">DateTime</span><span style="background:#ffffff;color:#000000;"> exceptionFinish)</span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;">{            </span></li>
<li>    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">using</span><span style="background:#ffffff;color:#000000;"> (</span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> projContext = ProjectContext)</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">{</span></li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> ers = projContext.EnterpriseResources;</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> usrs = projContext.Web.SiteUsers;</span></li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> usr = </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;">.IsNullOrEmpty(userName) ? projContext.Web.CurrentUser : usrs.GetByLoginName(GetFullUserName(userName));</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> er = ers.GetByUser(usr);</span></li>
<li>        <span style="background:#ffffff;color:#000000;">projContext.Load(ers);</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">projContext.Load(usrs);</span></li>
<li>        <span style="background:#ffffff;color:#000000;">projContext.Load(usr);</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">projContext.Load(er);</span></li>
<li>        <span style="background:#ffffff;color:#000000;">projContext.ExecuteQuery();</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> rcExs = er.ResourceCalendarExceptions;</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#2b91af;">CalendarExceptionCreationInformation</span><span style="background:#ffffff;color:#000000;"> cexCI = </span><span style="background:#ffffff;color:#0000ff;">new</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#2b91af;">CalendarExceptionCreationInformation</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">{</span></li>
<li>            <span style="background:#ffffff;color:#000000;">Name = exceptionName,</span></li>
<li style="background:#f3f3f3;">            <span style="background:#ffffff;color:#000000;">Start = exceptionStart,</span></li>
<li>            <span style="background:#ffffff;color:#000000;">Finish = exceptionFinish</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">};</span></li>
<li>        <span style="background:#ffffff;color:#000000;">rcExs.Add(cexCI);</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>        <span style="background:#ffffff;color:#000000;">ers.Update();</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">projContext.ExecuteQuery();</span></li>
<li>    <span style="background:#ffffff;color:#000000;">}</span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;">}</span></li>
</ol></div>
</p></div>
</p></div>
<p><strong>Note</strong>: The <em>Associate resource with a user account</em> option for your resource should be checked (or if no user name is specified, your authenticated user should have a resource mapped to) to successfully lookup an enterprise resource by the user (e.g. <em>GetByUser </em>method). Otherwise, you should iterate through the resources and find the one with the specified name, or use a <em>Guid</em> if you know one.</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image8.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb7.png?w=583&#038;h=78" width="583" height="78" /></a></p>
<p>The <em>DeleteCalendarException</em> method deletes the calendar exceptions of the selected user (resource) with the specified name.</p>
<div style="margin:0;display:inline;float:none;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:82a68255-b7fb-43a7-9dfb-c732165d57c5" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:400px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">internal</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">void</span><span style="background:#ffffff;color:#000000;"> DeleteCalendarException(</span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;"> userName, </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;"> exceptionName)</span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;">{</span></li>
<li>    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">using</span><span style="background:#ffffff;color:#000000;"> (</span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> projContext = ProjectContext)</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">{</span></li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> ers = projContext.EnterpriseResources;</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> usrs = projContext.Web.SiteUsers;</span></li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> usr = </span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;">.IsNullOrEmpty(userName) ? projContext.Web.CurrentUser : usrs.GetByLoginName(GetFullUserName(userName));</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> er = ers.GetByUser(usr);</span></li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> rcExs = er.ResourceCalendarExceptions;</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">projContext.Load(ers);</span></li>
<li>        <span style="background:#ffffff;color:#000000;">projContext.Load(usrs);</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">projContext.Load(usr);</span></li>
<li>        <span style="background:#ffffff;color:#000000;">projContext.Load(er);</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">projContext.Load(rcExs);</span></li>
<li>        <span style="background:#ffffff;color:#000000;">projContext.ExecuteQuery();</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">foreach</span><span style="background:#ffffff;color:#000000;"> (</span><span style="background:#ffffff;color:#2b91af;">CalendarException</span><span style="background:#ffffff;color:#000000;"> ce </span><span style="background:#ffffff;color:#0000ff;">in</span><span style="background:#ffffff;color:#000000;"> rcExs)</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">{</span></li>
<li>            <span style="background:#ffffff;color:#000000;">rcExs.Remove(ce);</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">}</span></li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">ers.Update();</span></li>
<li>        <span style="background:#ffffff;color:#000000;">projContext.ExecuteQuery();</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">}</span></li>
<li><span style="background:#ffffff;color:#000000;">}</span></li>
</ol></div>
</p></div>
</p></div>
<p>The <em>DumpCalendarExceptions</em> method simply dumps the existing resources and their calendar exceptions to the console.</p>
<div style="margin:0;display:inline;float:none;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:af910729-14f7-4963-bffe-050b69505b59" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:400px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">internal</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">void</span><span style="background:#ffffff;color:#000000;"> DumpCalendarExceptions()</span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;">{</span></li>
<li>    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">using</span><span style="background:#ffffff;color:#000000;"> (</span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> projContext = ProjectContext)</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">{</span></li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> ers = projContext.EnterpriseResources;</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">projContext.Load(ers);</span></li>
<li>        <span style="background:#ffffff;color:#000000;">projContext.ExecuteQuery();</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#2b91af;">Console</span><span style="background:#ffffff;color:#000000;">.WriteLine(</span><span style="background:#ffffff;color:#a31515;">&quot;&#092;nResource ID : Resource name&quot;</span><span style="background:#ffffff;color:#000000;">);</span></li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>        <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">foreach</span><span style="background:#ffffff;color:#000000;"> (</span><span style="background:#ffffff;color:#2b91af;">EnterpriseResource</span><span style="background:#ffffff;color:#000000;"> res </span><span style="background:#ffffff;color:#0000ff;">in</span><span style="background:#ffffff;color:#000000;"> ers)</span></li>
<li style="background:#f3f3f3;">        <span style="background:#ffffff;color:#000000;">{</span></li>
<li>            <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#2b91af;">Console</span><span style="background:#ffffff;color:#000000;">.WriteLine(</span><span style="background:#ffffff;color:#a31515;">&quot;&#092;n&#092;t{0}&#092;n&#092;t{1}&quot;</span><span style="background:#ffffff;color:#000000;">, res.Id, res.Name);</span></li>
<li style="background:#f3f3f3;">            <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">var</span><span style="background:#ffffff;color:#000000;"> rcExs = res.ResourceCalendarExceptions;</span></li>
<li>            <span style="background:#ffffff;color:#000000;">projContext.Load(rcExs);</span></li>
<li style="background:#f3f3f3;">            <span style="background:#ffffff;color:#000000;">projContext.ExecuteQuery();</span></li>
<li>            <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">foreach</span><span style="background:#ffffff;color:#000000;"> (</span><span style="background:#ffffff;color:#2b91af;">CalendarException</span><span style="background:#ffffff;color:#000000;"> ce </span><span style="background:#ffffff;color:#0000ff;">in</span><span style="background:#ffffff;color:#000000;"> rcExs)</span></li>
<li style="background:#f3f3f3;">            <span style="background:#ffffff;color:#000000;">{</span></li>
<li>                <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#2b91af;">Console</span><span style="background:#ffffff;color:#000000;">.WriteLine(</span><span style="background:#ffffff;color:#a31515;">&quot;&#092;n&#092;t{0}&#092;n&#092;t{1}&#092;t{2}&#092;t{3}&quot;</span><span style="background:#ffffff;color:#000000;">, ce.Id, ce.Name, ce.Start, ce.Finish);</span></li>
<li style="background:#f3f3f3;">            <span style="background:#ffffff;color:#000000;">}</span></li>
<li>        <span style="background:#ffffff;color:#000000;">}</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;">}</span></li>
<li><span style="background:#ffffff;color:#000000;">}</span></li>
</ol></div>
</p></div>
</p></div>
<p>And here is a sample usage of the methods above:</p>
<p>
<div style="margin:0;display:inline;float:none;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1bf97123-7dbc-487e-9bb5-7f3b297e11ce" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:200px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#0000ff;">static</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#0000ff;">void</span><span style="background:#ffffff;color:#000000;"> Main(</span><span style="background:#ffffff;color:#0000ff;">string</span><span style="background:#ffffff;color:#000000;">[] args)</span></li>
<li style="background:#f3f3f3;"><span style="background:#ffffff;color:#000000;">{</span></li>
<li>    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#2b91af;">ProjectOnlineTest</span><span style="background:#ffffff;color:#000000;">.DeleteCalendarException(</span><span style="background:#ffffff;color:#a31515;">&quot;project.user&quot;</span><span style="background:#ffffff;color:#000000;">, </span><span style="background:#ffffff;color:#a31515;">&quot;Test exception X&quot;</span><span style="background:#ffffff;color:#000000;">);</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#2b91af;">ProjectOnlineTest</span><span style="background:#ffffff;color:#000000;">.CreateCalendarException(</span><span style="background:#ffffff;color:#a31515;">&quot;another.user&quot;</span><span style="background:#ffffff;color:#000000;">, </span><span style="background:#ffffff;color:#a31515;">&quot;Test exception A&quot;</span><span style="background:#ffffff;color:#000000;">, </span><span style="background:#ffffff;color:#0000ff;">new</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#2b91af;">DateTime</span><span style="background:#ffffff;color:#000000;">(2013, 3, 5), </span><span style="background:#ffffff;color:#0000ff;">new</span><span style="background:#ffffff;color:#000000;"> </span><span style="background:#ffffff;color:#2b91af;">DateTime</span><span style="background:#ffffff;color:#000000;">(2013, 3, 15));</span></li>
<li>    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#2b91af;">ProjectOnlineTest</span><span style="background:#ffffff;color:#000000;">.DumpCalendarExceptions();</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;"></span></li>
<li>    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#2b91af;">Console</span><span style="background:#ffffff;color:#000000;">.WriteLine(</span><span style="background:#ffffff;color:#a31515;">&quot;Press a key to exit: &quot;</span><span style="background:#ffffff;color:#000000;">);</span></li>
<li style="background:#f3f3f3;">    <span style="background:#ffffff;color:#000000;"></span><span style="background:#ffffff;color:#2b91af;">Console</span><span style="background:#ffffff;color:#000000;">.ReadKey(</span><span style="background:#ffffff;color:#0000ff;">false</span><span style="background:#ffffff;color:#000000;">);</span></li>
<li><span style="background:#ffffff;color:#000000;">}</span></li>
</ol></div>
</p></div>
</p></div>
</p>
<p>I hope this sample makes it easier to work with <em>Project Online </em>using <em>CSOM</em>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pholpar.wordpress.com/1057/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pholpar.wordpress.com/1057/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1057&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pholpar.wordpress.com/2013/03/06/handling-calendar-exceptions-with-csom-on-project-online/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/31db6921f6eddb38f5f86b0a220dbd58?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pholpar</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb6.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb7.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Deleting files from the IE cache as part of the Visual Studio deployment process</title>
		<link>http://pholpar.wordpress.com/2013/03/05/deleting-files-from-the-ie-cache-as-part-of-the-visual-studio-deployment-process/</link>
		<comments>http://pholpar.wordpress.com/2013/03/05/deleting-files-from-the-ie-cache-as-part-of-the-visual-studio-deployment-process/#comments</comments>
		<pubDate>Tue, 05 Mar 2013 20:44:29 +0000</pubDate>
		<dc:creator>Peter Holpar</dc:creator>
				<category><![CDATA[CKS.Dev]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[SP 2010]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[VSX]]></category>

		<guid isPermaLink="false">https://pholpar.wordpress.com/?p=1051</guid>
		<description><![CDATA[In the past months I had again a lot to do with client side SharePoint development, that means in practice mainly projects including ribbon extensions and tons of JavaScript files. One of the issues with that type of development is the bad habit of Internet Explorer called caching. For example, when you make modifications to [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1051&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In the past months I had again a lot to do with client side SharePoint development, that means in practice mainly projects including ribbon extensions and tons of <em>JavaScript</em> files. One of the issues with that type of development is the bad habit of <em>Internet Explorer </em>called caching. For example, when you make modifications to the <em>.js </em>files, and re-deploy your project, it is rather common, that <em>IE</em> executes the former versions of the scripts, that I find pretty annoying.</p>
<p>Some of the workarounds I found for that issue in the past years:</p>
<p><strong>Option Nr.1</strong>: Disable caching in <em>IE</em> (<em>Internet options</em> / <em>General</em> / <em>Browsing history</em> / <em>Settings</em>). It is OK if you use your environment only for development (like a Dev-VM), but not optimal if you should use the same browser to fulfill your other daily tasks.</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image4.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb4.png?w=383&#038;h=484" width="383" height="484" /></a></p>
<p><strong>Option Nr.2</strong>: Type the full <em>URL</em> of the script in the address text box of <em>IE</em>, download a local copy of the script to a temporary folder, and refresh the page with <em>Ctrl+F5</em>. Rather cumbersome method, especially if you have to refresh several scripts .</p>
<p><strong>Option Nr.3</strong>: Open the location of the cache (<em>Internet options</em> / <em>General</em> / <em>Browsing history</em> / <em>Settings </em>/ <em>View files</em>, marked with blue on the screenshot above), and delete the file(s) manually. The location in the file system is typically <em>C:\Users\UserName\AppData\Local\Microsoft\Windows\Temporary Internet Files</em>. Works quite good, but it takes some time and is still something you can forget.</p>
<p>Wouldn’t it be more comfortable to automate the process, for example, as a deployment step in <em>Visual Studio</em>? Definitely, but how to achieve that? Well, deleting files from the <em>IE</em> cache programmatically is far from being straightforward, but fortunately I found a nice <a href="http://support.microsoft.com/kb/326201">example on MSDN</a> for a sample wrapper class in C#, including a lot of <em>PInvoke </em>calls. Having this solution, the <em>Visual Studio Extensibility</em> part of the exercise was a routine task.</p>
<p>My first idea was to contribute this <em>VS</em> extension to the <a href="http://cksdev.codeplex.com"><em>CKS.Dev</em></a> project on <em>CodePlex</em> (see some posts on my other contributions to <em>CKS.Dev </em><a href="http://pholpar.wordpress.com/tag/cks-dev/">here</a>), but the project is just being upgraded to <em>SharePoint 2013</em> / <em>Visual Studio 2012</em>, so I extended my own <a href="http://spvsext.codeplex.com/">extension</a> (documented <a href="http://pholpar.wordpress.com/2010/05/20/visual-studio-2010-extension-for-helping-sharepoint-2010-debugging/">here</a>) instead.</p>
<p>Expected functionality:</p>
<p>I would like to specify through <em>Visual Studio</em> project properties, which files should be deleted from the cache (e.g. from the <em>Temporary Internet Files </em>folder). </p>
<p>First, I introduce a new property called <em>IE cache delete rule</em> that determines the scope of the action and has the following possible values:</p>
<p><em>Only from current site</em> – only matching files cached from the active SharePoint site (the one you specified as the target of the deployment in <em>VS</em>) are deleted.</p>
<p><em>All from current sites</em> – all files cached from the active SharePoint site are deleted, other filters are ignored.</p>
<p><em>No site specific</em> – all cached files that fulfill the filters are deleted, independently from the origin <em>URL</em>.</p>
<p>Filters (there is a logical <em>OR</em> between the filters that means a cached file should fulfill at least one of the conditions to be deleted):</p>
<p><em>IE cache file list</em> – It is a list of the names of the files to be deleted from the cache.</p>
<p><em>IE cache file pattern</em> – It is a regular expression pattern. All files matching the pattern will be deleted from the cache, as long as it also matches the scope of the action (see <em>IE cache delete rule</em> property above)</p>
<p>Let’s have a look at the implementation!</p>
<p>My original <em>SPVSProjectProps</em> class was extended with the new properties:</p>
<div style="margin:0;display:inline;float:none;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:61633447-56c9-4ad4-b063-95041c874c38" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:400px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="color:#008000;">// IECacheFilePattern property related members</span></li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">const</span> <span style="color:#0000ff;">string</span> IECacheFilePatternPropertyId = <span style="color:#a31515;">&quot;IECacheFilePattern&quot;</span>;</li>
<li><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">const</span> <span style="color:#0000ff;">string</span> IECacheFilePatternPropertyDefaultValue = <span style="color:#a31515;">&quot;&quot;</span>;</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>[<span style="color:#2b91af;">DisplayName</span>(<span style="color:#a31515;">&quot;IE cache file pattern&quot;</span>)]</li>
<li style="background:#f3f3f3;">[<span style="color:#2b91af;">DescriptionAttribute</span>(<span style="color:#a31515;">&quot;This property specifies a regular expression pattern to determine which files should be deleted from the IE cache when the Clear IE cache deployment step is activated&quot;</span>)]</li>
<li>[<span style="color:#2b91af;">DefaultValue</span>(IECacheFilePatternPropertyDefaultValue)]</li>
<li style="background:#f3f3f3;"><span style="color:#008000;">// we want our custom property to show up in the SharePoint section in the project properties property grid</span></li>
<li>[<span style="color:#2b91af;">Category</span>(<span style="color:#a31515;">&quot;SharePoint&quot;</span>)]</li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">string</span> IECacheFilePattern</li>
<li>{</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">get</span></li>
<li>    {</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">string</span> propertyValue;</li>
<li>        <span style="color:#0000ff;">int</span> hr = projectStorage.GetPropertyValue(IECacheFilePatternPropertyId, <span style="color:#0000ff;">string</span>.Empty,</li>
<li style="background:#f3f3f3;">            (<span style="color:#0000ff;">uint</span>)<span style="color:#2b91af;">_PersistStorageType</span>.PST_PROJECT_FILE, <span style="color:#0000ff;">out</span> propertyValue);</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="color:#008000;">// Try to get the current value from the project file; if it does not yet exist, return a default value. </span></li>
<li>        <span style="color:#0000ff;">if</span> (!<span style="color:#2b91af;">ErrorHandler</span>.Succeeded(hr) || <span style="color:#2b91af;">String</span>.IsNullOrEmpty(propertyValue))</li>
<li style="background:#f3f3f3;">        {</li>
<li>            propertyValue = IECacheFilePatternPropertyDefaultValue;</li>
<li style="background:#f3f3f3;">        }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">return</span> propertyValue;</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">set</span></li>
<li style="background:#f3f3f3;">    {</li>
<li>        projectStorage.SetPropertyValue(IECacheFilePatternPropertyId, <span style="color:#0000ff;">string</span>.Empty,</li>
<li style="background:#f3f3f3;">            (<span style="color:#0000ff;">uint</span>)<span style="color:#2b91af;">_PersistStorageType</span>.PST_PROJECT_FILE, <span style="color:#0000ff;">value</span>);</li>
<li>    }</li>
<li style="background:#f3f3f3;">}</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;"><span style="color:#008000;">// IECacheFileList property related members</span></li>
<li><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">const</span> <span style="color:#0000ff;">string</span> IECacheFileListPropertyId = <span style="color:#a31515;">&quot;IECacheFileList&quot;</span>;</li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">const</span> <span style="color:#0000ff;">string</span> IECacheFileListPropertyDefaultValue = <span style="color:#a31515;">&quot;&quot;</span>;</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">[<span style="color:#2b91af;">DisplayName</span>(<span style="color:#a31515;">&quot;IE cache file list&quot;</span>)]</li>
<li>[<span style="color:#2b91af;">Description</span>(<span style="color:#a31515;">&quot;This property specifies which files should be deleted from the IE cache when the Clear IE cache deployment step is activated&quot;</span>)]</li>
<li style="background:#f3f3f3;">[<span style="color:#2b91af;">DefaultValue</span>(RelatedTimerJobsPropertyDefaultValue)]</li>
<li><span style="color:#008000;">// we want our custom property to show up in the SharePoint section in the project properties property grid</span></li>
<li style="background:#f3f3f3;">[<span style="color:#2b91af;">Category</span>(<span style="color:#a31515;">&quot;SharePoint&quot;</span>)]</li>
<li><span style="color:#008000;">// use custom property editor to avoid &quot;Constructor on type &#039;System.String&#039; not found.&quot; error in design mode</span></li>
<li style="background:#f3f3f3;">[<span style="color:#2b91af;">Editor</span>(<span style="color:#a31515;">&quot;System.Windows.Forms.Design.StringArrayEditor, System.Design&quot;</span>, <span style="color:#0000ff;">typeof</span>(<span style="color:#2b91af;">UITypeEditor</span>))]</li>
<li>[<span style="color:#2b91af;">TypeConverter</span>(<span style="color:#0000ff;">typeof</span>(<span style="color:#2b91af;">CsvArrayConverter</span>))]</li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">public</span> <span style="color:#2b91af;">String</span>[] IECacheFileList</li>
<li>{</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">get</span></li>
<li>    {</li>
<li style="background:#f3f3f3;">        <span style="color:#2b91af;">String</span> propertyValue;</li>
<li>        <span style="color:#0000ff;">int</span> hr = projectStorage.GetPropertyValue(IECacheFileListPropertyId, <span style="color:#0000ff;">string</span>.Empty,</li>
<li style="background:#f3f3f3;">            (<span style="color:#0000ff;">uint</span>)<span style="color:#2b91af;">_PersistStorageType</span>.PST_PROJECT_FILE, <span style="color:#0000ff;">out</span> propertyValue);</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="color:#008000;">// Try to get the current value from the project file; if it does not yet exist, return a default value.</span></li>
<li>        <span style="color:#0000ff;">if</span> (!<span style="color:#2b91af;">ErrorHandler</span>.Succeeded(hr) || <span style="color:#2b91af;">String</span>.IsNullOrEmpty(propertyValue))</li>
<li style="background:#f3f3f3;">        {</li>
<li>            propertyValue = IECacheFileListPropertyDefaultValue;</li>
<li style="background:#f3f3f3;">        }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="color:#008000;">// remove accidental whitespaces</span></li>
<li>        <span style="color:#2b91af;">String</span>[] fileNames = propertyValue.Split(<span style="color:#0000ff;">new</span> <span style="color:#0000ff;">char</span>[] { <span style="color:#a31515;">&#039;|&#039;</span> }, <span style="color:#2b91af;">StringSplitOptions</span>.RemoveEmptyEntries);</li>
<li style="background:#f3f3f3;">        fileNames = <span style="color:#2b91af;">Array</span>.ConvertAll&lt;<span style="color:#2b91af;">String</span>, <span style="color:#2b91af;">String</span>&gt;(fileNames, fileName =&gt; fileName.Trim());</li>
<li>        <span style="color:#0000ff;">return</span> fileNames;</li>
<li style="background:#f3f3f3;">    }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">set</span></li>
<li>    {</li>
<li style="background:#f3f3f3;">        <span style="color:#2b91af;">String</span> propertyValue =</li>
<li>            (<span style="color:#0000ff;">value</span> == <span style="color:#0000ff;">null</span>) ?</li>
<li style="background:#f3f3f3;">            <span style="color:#2b91af;">String</span>.Empty :</li>
<li>            <span style="color:#008000;">// remove accidental whitespaces</span></li>
<li style="background:#f3f3f3;">            <span style="color:#2b91af;">String</span>.Join(<span style="color:#a31515;">&quot;|&quot;</span>, <span style="color:#2b91af;">Array</span>.ConvertAll&lt;<span style="color:#2b91af;">String</span>, <span style="color:#2b91af;">String</span>&gt;(<span style="color:#0000ff;">value</span>, fileName =&gt; fileName.Trim()));</li>
<li>        projectStorage.SetPropertyValue(IECacheFileListPropertyId, <span style="color:#0000ff;">string</span>.Empty,</li>
<li style="background:#f3f3f3;">            (<span style="color:#0000ff;">uint</span>)<span style="color:#2b91af;">_PersistStorageType</span>.PST_PROJECT_FILE, propertyValue);</li>
<li>    }</li>
<li style="background:#f3f3f3;">}</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;"><span style="color:#008000;">// IECacheDeleteRule property related members</span></li>
<li><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">const</span> <span style="color:#0000ff;">string</span> IECacheDeleteRulePropertyId = <span style="color:#a31515;">&quot;IECacheDeleteRule&quot;</span>;</li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">const</span> <span style="color:#2b91af;">IECacheDeleteRules</span> IECacheDeleteRulePropertyDefaultValue = <span style="color:#2b91af;">IECacheDeleteRules</span>.OnlyCurrentSite;</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">[<span style="color:#2b91af;">DisplayName</span>(<span style="color:#a31515;">&quot;IE cache delete rule&quot;</span>)]</li>
<li>[<span style="color:#2b91af;">Description</span>(<span style="color:#a31515;">&quot;This property specifies the relation between the current SharePoint site and files to be deleted from IE cache&quot;</span>)]</li>
<li style="background:#f3f3f3;">[<span style="color:#2b91af;">DefaultValue</span>(IECacheDeleteRulePropertyDefaultValue)]</li>
<li><span style="color:#008000;">// we want our custom property to show up in the SharePoint section in the project properties property grid</span></li>
<li style="background:#f3f3f3;">[<span style="color:#2b91af;">Category</span>(<span style="color:#a31515;">&quot;SharePoint&quot;</span>)]</li>
<li>[<span style="color:#2b91af;">TypeConverter</span>(<span style="color:#0000ff;">typeof</span>(<span style="color:#2b91af;">IECacheDeleteRuleConverter</span>))]</li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">public</span> <span style="color:#2b91af;">IECacheDeleteRules</span> IECacheDeleteRule</li>
<li>{</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">get</span></li>
<li>    {</li>
<li style="background:#f3f3f3;">        <span style="color:#008000;">// set default value</span></li>
<li>        <span style="color:#2b91af;">IECacheDeleteRules</span> propertyValue = IECacheDeleteRulePropertyDefaultValue;</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">string</span> propertyValueString;</li>
<li>        <span style="color:#0000ff;">int</span> hr = projectStorage.GetPropertyValue(IECacheDeleteRulePropertyId, <span style="color:#0000ff;">string</span>.Empty,</li>
<li style="background:#f3f3f3;">            (<span style="color:#0000ff;">uint</span>)<span style="color:#2b91af;">_PersistStorageType</span>.PST_PROJECT_FILE, <span style="color:#0000ff;">out</span> propertyValueString);</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="color:#008000;">// Try to get the current value from the project file; if it does not yet exist, return a default value. </span></li>
<li>        <span style="color:#0000ff;">if</span> (<span style="color:#2b91af;">ErrorHandler</span>.Succeeded(hr) &amp;&amp; !<span style="color:#2b91af;">String</span>.IsNullOrEmpty(propertyValueString))</li>
<li style="background:#f3f3f3;">        {</li>
<li>            <span style="color:#2b91af;">Enum</span>.TryParse&lt;<span style="color:#2b91af;">IECacheDeleteRules</span>&gt;(propertyValueString, <span style="color:#0000ff;">out</span> propertyValue);</li>
<li style="background:#f3f3f3;">        }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">return</span> propertyValue;</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">set</span></li>
<li style="background:#f3f3f3;">    {</li>
<li>        projectStorage.SetPropertyValue(IECacheDeleteRulePropertyId, <span style="color:#0000ff;">string</span>.Empty,</li>
<li style="background:#f3f3f3;">            (<span style="color:#0000ff;">uint</span>)<span style="color:#2b91af;">_PersistStorageType</span>.PST_PROJECT_FILE, <span style="color:#0000ff;">value</span>.ToString());</li>
<li>    }</li>
<li style="background:#f3f3f3;">}</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">enum</span> <span style="color:#2b91af;">IECacheDeleteRules</span></li>
<li>{</li>
<li style="background:#f3f3f3;">    [<span style="color:#2b91af;">Description</span>(<span style="color:#a31515;">&quot;Only from current site&quot;</span>)]</li>
<li>    OnlyCurrentSite,</li>
<li style="background:#f3f3f3;">    [<span style="color:#2b91af;">Description</span>(<span style="color:#a31515;">&quot;All from current site&quot;</span>)]</li>
<li>    AllFromCurrentSite,</li>
<li style="background:#f3f3f3;">    [<span style="color:#2b91af;">Description</span>(<span style="color:#a31515;">&quot;No site specific&quot;</span>)]</li>
<li>    NoSiteSpecific</li>
<li style="background:#f3f3f3;">}</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;"><span style="color:#008000;">// based on EnumConverter example from</span></li>
<li><span style="color:#008000;">// <a href="http://www.c-sharpcorner.com/uploadfile/witnes/using-propertygrid-in-net/" rel="nofollow">http://www.c-sharpcorner.com/uploadfile/witnes/using-propertygrid-in-net/</a></span></li>
<li style="background:#f3f3f3;"><span style="color:#0000ff;">class</span> <span style="color:#2b91af;">IECacheDeleteRuleConverter</span> : <span style="color:#2b91af;">EnumConverter</span></li>
<li>{</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">private</span> <span style="color:#2b91af;">Type</span> enumType;</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">public</span> IECacheDeleteRuleConverter(<span style="color:#2b91af;">Type</span> type) : <span style="color:#0000ff;">base</span>(type)</li>
<li>    {</li>
<li style="background:#f3f3f3;">        enumType = type;</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">bool</span> CanConvertTo(<span style="color:#2b91af;">ITypeDescriptorContext</span> context, <span style="color:#2b91af;">Type</span> destType)</li>
<li style="background:#f3f3f3;">    {</li>
<li>        <span style="color:#0000ff;">return</span> destType == <span style="color:#0000ff;">typeof</span>(<span style="color:#0000ff;">string</span>);</li>
<li style="background:#f3f3f3;">    }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">object</span> ConvertTo(<span style="color:#2b91af;">ITypeDescriptorContext</span> context, <span style="color:#2b91af;">CultureInfo</span> culture, <span style="color:#0000ff;">object</span> value, <span style="color:#2b91af;">Type</span> destType)</li>
<li>    {</li>
<li style="background:#f3f3f3;">        <span style="color:#2b91af;">FieldInfo</span> fi = enumType.GetField(<span style="color:#2b91af;">Enum</span>.GetName(enumType, value));</li>
<li>        <span style="color:#2b91af;">DescriptionAttribute</span> dna = (<span style="color:#2b91af;">DescriptionAttribute</span>)<span style="color:#2b91af;">Attribute</span>.GetCustomAttribute(fi, <span style="color:#0000ff;">typeof</span>(<span style="color:#2b91af;">DescriptionAttribute</span>));</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">if</span> (dna != <span style="color:#0000ff;">null</span>)</li>
<li>            <span style="color:#0000ff;">return</span> dna.Description;</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">else</span></li>
<li>            <span style="color:#0000ff;">return</span> value.ToString();</li>
<li style="background:#f3f3f3;">    }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">bool</span> CanConvertFrom(<span style="color:#2b91af;">ITypeDescriptorContext</span> context, <span style="color:#2b91af;">Type</span> srcType)</li>
<li>    {</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">return</span> srcType == <span style="color:#0000ff;">typeof</span>(<span style="color:#0000ff;">string</span>);</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">override</span> <span style="color:#0000ff;">object</span> ConvertFrom(<span style="color:#2b91af;">ITypeDescriptorContext</span> context, <span style="color:#2b91af;">CultureInfo</span> culture, <span style="color:#0000ff;">object</span> value)</li>
<li style="background:#f3f3f3;">    {</li>
<li>        <span style="color:#0000ff;">foreach</span> (<span style="color:#2b91af;">FieldInfo</span> fi <span style="color:#0000ff;">in</span> enumType.GetFields())</li>
<li style="background:#f3f3f3;">        {</li>
<li>            <span style="color:#2b91af;">DescriptionAttribute</span> dna =</li>
<li style="background:#f3f3f3;">            (<span style="color:#2b91af;">DescriptionAttribute</span>)<span style="color:#2b91af;">Attribute</span>.GetCustomAttribute(fi, <span style="color:#0000ff;">typeof</span>(<span style="color:#2b91af;">DescriptionAttribute</span>));</li>
<li>            <span style="color:#0000ff;">if</span> ((dna != <span style="color:#0000ff;">null</span>) &amp;&amp; ((<span style="color:#0000ff;">string</span>)value == dna.Description))</li>
<li style="background:#f3f3f3;">                <span style="color:#0000ff;">return</span> <span style="color:#2b91af;">Enum</span>.Parse(enumType, fi.Name);</li>
<li>        }</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">return</span> <span style="color:#2b91af;">Enum</span>.Parse(enumType, (<span style="color:#0000ff;">string</span>)value);</li>
<li>    }</li>
<li style="background:#f3f3f3;">}</li>
</ol></div>
</p></div>
</p></div>
<p>We have two new methods to the static <em>ExtensionHelper</em> class. The <em>ShouldDeleteIECacheFile</em> method encapsulates the logic of cache file deletion as function of our new project properties. The <em>ClearIECacheFile</em> method calls the core cache file deletion (see <em>ClearIEFiles</em> method of the <em>DeleteIECache</em> class below) with this logic injected as a parameter. We do some logging in both of these methods to inform users in the <em>Output</em> window of <em>VS</em> about the progress and result of the deployment. We should keep the list of deleted files in the local <em>filesDeleted </em>variable, otherwise each files would be listed twice due to the logic implemented in the <em>ClearIEFiles</em> method.</p>
<div style="margin:0;display:inline;float:none;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:68de5da6-7d58-4cc6-9e6e-2740b1890d4f" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:400px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li><span style="color:#0000ff;">internal</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> ClearIECacheFile(<span style="color:#2b91af;">ISharePointProject</span> project)</li>
<li style="background:#f3f3f3;">{</li>
<li>    <span style="color:#0000ff;">try</span></li>
<li style="background:#f3f3f3;">    {</li>
<li>        LogToOutputWindows(project, <span style="color:#a31515;">&quot;Clearing files from IE cache&quot;</span>);</li>
<li style="background:#f3f3f3;">        <span style="color:#2b91af;">SPVSProjectProps</span> propertiesObject;</li>
<li>        <span style="color:#0000ff;">if</span> (project.Annotations.TryGetValue&lt;<span style="color:#2b91af;">SPVSProjectProps</span>&gt;(<span style="color:#0000ff;">out</span> propertiesObject))</li>
<li style="background:#f3f3f3;">        {</li>
<li>            <span style="color:#2b91af;">String</span> ieCacheFilePattern = propertiesObject.IECacheFilePattern;</li>
<li style="background:#f3f3f3;">            <span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">String</span>&gt; ieCacheFileList = propertiesObject.IECacheFileList;</li>
<li>            <span style="color:#2b91af;">SPVSProjectProps</span>.<span style="color:#2b91af;">IECacheDeleteRules</span> ieCacheDeleteRule = propertiesObject.IECacheDeleteRule;</li>
<li style="background:#f3f3f3;">            <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">String</span>&gt; filesDeleted = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">String</span>&gt;();</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">            <span style="color:#2b91af;">Func</span>&lt;<span style="color:#2b91af;">Uri</span>, <span style="color:#0000ff;">bool</span>&gt; shouldDelete = <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">Func</span>&lt;<span style="color:#2b91af;">Uri</span>, <span style="color:#0000ff;">bool</span>&gt;(u =&gt; ShouldDeleteIECacheFile(u,</li>
<li>                                                                                        ieCacheFilePattern,</li>
<li style="background:#f3f3f3;">                                                                                        ieCacheFileList,</li>
<li>                                                                                        ieCacheDeleteRule,</li>
<li style="background:#f3f3f3;">                                                                                        filesDeleted,</li>
<li>                                                                                        project));</li>
<li style="background:#f3f3f3;">            <span style="color:#2b91af;">DeleteIECache</span>.ClearIEFiles(shouldDelete);</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">            LogToOutputWindows(project, <span style="color:#2b91af;">String</span>.Format(<span style="color:#a31515;">&quot;Number of files deleted from IE cache: {0}&quot;</span>, filesDeleted.Count));</li>
<li>        }</li>
<li style="background:#f3f3f3;">    }</li>
<li>    <span style="color:#0000ff;">catch</span> (<span style="color:#2b91af;">Exception</span> ex)</li>
<li style="background:#f3f3f3;">    {</li>
<li>        LogToOutputWindows(project, <span style="color:#2b91af;">String</span>.Format(<span style="color:#a31515;">&quot;Clearing files from IE cache failed. Exception: {0}&quot;</span>, ex.Message));</li>
<li style="background:#f3f3f3;">    }</li>
<li>}</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li><span style="color:#0000ff;">internal</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">bool</span> ShouldDeleteIECacheFile(<span style="color:#2b91af;">Uri</span> uri, <span style="color:#2b91af;">String</span> filePattern, <span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">String</span>&gt; fileList,</li>
<li style="background:#f3f3f3;">    <span style="color:#2b91af;">SPVSProjectProps</span>.<span style="color:#2b91af;">IECacheDeleteRules</span> ieCacheDeleteRule, <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">String</span>&gt; filesDeleted, <span style="color:#2b91af;">ISharePointProject</span> project)</li>
<li>{</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">bool</span> result = <span style="color:#0000ff;">false</span>;</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#2b91af;">Uri</span> siteUrl = project.SiteUrl;</li>
<li>    <span style="color:#2b91af;">Regex</span> filePatternRegex = <span style="color:#0000ff;">string</span>.IsNullOrEmpty(filePattern) ? <span style="color:#0000ff;">null</span> : <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">Regex</span>(filePattern);</li>
<li style="background:#f3f3f3;">    <span style="color:#2b91af;">List</span>&lt;<span style="color:#0000ff;">string</span>&gt; fileListEx = (fileList == <span style="color:#0000ff;">null</span>) ? <span style="color:#0000ff;">new</span> <span style="color:#2b91af;">List</span>&lt;<span style="color:#0000ff;">string</span>&gt;() : fileList.ToList();</li>
<li>    <span style="color:#0000ff;">string</span> fileName = uri.Segments[uri.Segments.Length - 1];</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">bool</span> isFromCurrentSite = uri.AbsoluteUri.IndexOf(siteUrl.AbsoluteUri, <span style="color:#2b91af;">StringComparison</span>.InvariantCultureIgnoreCase) == 0;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">if</span> (ieCacheDeleteRule == <span style="color:#2b91af;">SPVSProjectProps</span>.<span style="color:#2b91af;">IECacheDeleteRules</span>.AllFromCurrentSite)</li>
<li>    {</li>
<li style="background:#f3f3f3;">        result = isFromCurrentSite;</li>
<li>    }</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">else</span></li>
<li>    {</li>
<li style="background:#f3f3f3;">        result = ((fileListEx.Any(f =&gt; (f.ToUpper() == fileName.ToUpper()))) ||</li>
<li>                (filePatternRegex != <span style="color:#0000ff;">null</span>) &amp;&amp; (filePatternRegex.IsMatch(fileName)));</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">if</span> (ieCacheDeleteRule == <span style="color:#2b91af;">SPVSProjectProps</span>.<span style="color:#2b91af;">IECacheDeleteRules</span>.OnlyCurrentSite)</li>
<li>        {</li>
<li style="background:#f3f3f3;">            result = result &amp;&amp; isFromCurrentSite;</li>
<li>        }</li>
<li style="background:#f3f3f3;">    }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">if</span> ((result) &amp;&amp; (!filesDeleted.Contains(uri.AbsoluteUri)))</li>
<li>    {</li>
<li style="background:#f3f3f3;">        filesDeleted.Add(uri.AbsoluteUri);</li>
<li>        LogToOutputWindows(project, <span style="color:#2b91af;">String</span>.Format(<span style="color:#a31515;">&quot;Deleting file from IE cache: &#039;{0}&#039;&quot;</span>, uri));</li>
<li style="background:#f3f3f3;">    }</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">return</span> result;</li>
<li>}</li>
</ol></div>
</p></div>
</p></div>
<p>I kept the <em>DeleteIECache</em> class and its <em>ClearIEFiles</em> method as it was published on <a href="http://support.microsoft.com/kb/326201">MSDN</a>, except this method has a <em>Func&lt;Uri, bool&gt; shouldDelete</em> parameter that we use to decide if a specific file should be deleted from the <em>IE </em>cache:</p>
<p><em>returnValue = shouldDelete(uri) ? DeleteUrlCacheEntry(internetCacheEntry.lpszSourceUrlName) : false;</em></p>
<p>The code for the deployment step is pretty straightforward, it simply calls the <em>ClearIECacheFile</em> method of our <em>ExtensionHelper</em> class. Since we don’t have to call any <em>SharePoint</em>-specific code on the server side (that means no <em>x64 </em>process), there is no need for <a href="http://msdn.microsoft.com/en-us/library/ee471447.aspx"><em>SharePoint commands</em></a> in this case. That makes our life easier.</p>
<div style="margin:0;display:inline;float:none;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:997c7ade-89d4-4ea2-b413-7ff667d3eea9" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;">Code Snippet</div>
<div style="background:#fff;max-height:400px;overflow:auto;">
<ol style="background:#ffffff;margin:0;padding:0 0 0 5px;">
<li>[<span style="color:#2b91af;">DeploymentStep</span>(<span style="color:#a31515;">&quot;PHolpar.ClearIECache&quot;</span>)]</li>
<li style="background:#f3f3f3;">[<span style="color:#2b91af;">Export</span>(<span style="color:#0000ff;">typeof</span>(<span style="color:#2b91af;">IDeploymentStep</span>))]</li>
<li><span style="color:#0000ff;">internal</span> <span style="color:#0000ff;">class</span> <span style="color:#2b91af;">ClearIECacheDeployStep</span> : <span style="color:#2b91af;">IDeploymentStep</span></li>
<li style="background:#f3f3f3;">{</li>
<li>&nbsp;</li>
<li style="background:#f3f3f3;">    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">bool</span> CanExecute(<span style="color:#2b91af;">IDeploymentContext</span> context)</li>
<li>    {</li>
<li style="background:#f3f3f3;">        <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">true</span>;</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Execute(<span style="color:#2b91af;">IDeploymentContext</span> context)</li>
<li style="background:#f3f3f3;">    {</li>
<li>        <span style="color:#2b91af;">ISharePointProject</span> project = context.Project;</li>
<li style="background:#f3f3f3;">        <span style="color:#2b91af;">ExtensionHelper</span>.ClearIECacheFile(project);</li>
<li>    }</li>
<li style="background:#f3f3f3;">&nbsp;</li>
<li>    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span> Initialize(<span style="color:#2b91af;">IDeploymentStepInfo</span> stepInfo)</li>
<li style="background:#f3f3f3;">    {</li>
<li>        stepInfo.Name = <span style="color:#a31515;">&quot;Clear IE cache&quot;</span>;</li>
<li style="background:#f3f3f3;">        stepInfo.Description = <span style="color:#a31515;">&quot;This step deletes the specified files from the Internet Explorer cache of the current user.&quot;</span>;</li>
<li>        stepInfo.StatusBarMessage = <span style="color:#a31515;">&quot;IE cache is being cleared&#8230;&quot;</span>;</li>
<li style="background:#f3f3f3;">    }</li>
<li>}</li>
</ol></div>
</p></div>
</p></div>
<p>To test the new extension, I’ve created a deployment configuration called <em>Clear IE cache</em>.</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image31.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image3_thumb.png?w=592&#038;h=266" width="592" height="266" /></a></p>
<p>This DC has only a single deployment step, our new <em>Clear IE cache</em> DS.</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image5.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image_thumb5.png?w=470&#038;h=484" width="470" height="484" /></a></p>
<p>Using the following project properties (reg. exp. used: <em>^.*\.(js|JS)$</em>) we can delete all <em>.js</em> files that were cached from the active SharePoint site:</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image6.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image6_thumb.png?w=341&#038;h=62" width="341" height="62" /></a></p>
<p>We can specify the files to be deleted explicitly in the <em>IE cache file list </em>property:</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image12.png"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image12_thumb.png?w=391&#038;h=258" width="391" height="258" /></a></p>
<p>In this case these files would be deleted from the cache independently from the <em>URL </em>they were downloaded from:</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image15.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image15_thumb.png?w=509&#038;h=57" width="509" height="57" /></a></p>
<p>The next screenshot displays a sample deployment for the previous configuration:</p>
<p><a href="http://pholpar.files.wordpress.com/2013/03/image21.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:inline;border-top:0;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://pholpar.files.wordpress.com/2013/03/image21_thumb.png?w=666&#038;h=164" width="666" height="164" /></a></p>
<p>Using the <em>All from current sites</em> value of <em>IE cache delete rule</em> (not illustrated here) the deployment process clears all files cached from the active <em>SharePoint </em>site, filtering properties (<em>IE cache file list</em> and <em>IE cache file pattern</em>) are ignored.</p>
<p>You can download the updated version (v 1.1) of my <em>VS</em> extension from the <a href="http://spvsext.codeplex.com/">original location</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pholpar.wordpress.com/1051/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pholpar.wordpress.com/1051/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pholpar.wordpress.com&#038;blog=10111481&#038;post=1051&#038;subd=pholpar&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pholpar.wordpress.com/2013/03/05/deleting-files-from-the-ie-cache-as-part-of-the-visual-studio-deployment-process/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/31db6921f6eddb38f5f86b0a220dbd58?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pholpar</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb4.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image3_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image_thumb5.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image6_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image12_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image15_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://pholpar.files.wordpress.com/2013/03/image21_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
	</channel>
</rss>
