<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Relationship Experience Group</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/rxg/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/rxg/feed.xml</link>
    <description>RXG is responsible for building common, reusable architecture components for our Relationship Management solutions</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:27:47 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Implementing a Multi-tenant Windows Azure Application</title>
      <link>https://docs.microsoft.com/archive/blogs/rxg/implementing-a-multi-tenant-windows-azure-application</link>
      <pubDate>Thu, 04 Jun 2009 20:51:35 GMT</pubDate>
      <dc:creator><![CDATA[bartr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rxg/2009/06/04/implementing-a-multi-tenant-windows-azure-application/</guid>
      <description><![CDATA[We are nearing the completion of our multi-tenant Azure incubation project. I blogged in March about...]]></description>
      <content:encoded><![CDATA[<p>We are nearing the completion of our multi-tenant Azure incubation project. I <a href="https://blogs.msdn.com/rxg/archive/2009/03/09/azure-multi-tenant-addressing.aspx">blogged</a> in March about our plans for the addressing scheme.&#160; Quite a bit has changed since then.</p>  <h2>URL Rewriting Revisited</h2>  <p>For many of our scenarios, URL Rewriting works very well.&#160; Since my last blog post, Azure has added the <a href="https://learn.iis.net/page.aspx/460/using-url-rewrite-module/">URL Rewriting module</a> to the web role, so, for many scenarios, this is a great solution.</p>  <p>Where we ran into issues in our scenario is that we did not know the type or number of pages that could be created in advance.&#160; If a tenant creates a PageZZZ url, where do we route the request?&#160; In many scenarios, you know the set of pages in advance, so this isn’t an issue.&#160;&#160; </p>  <h2>Enter the HTTP Handler</h2>  <p>Our first attempt at handling this issue was to implement an HTTP Handler.&#160; We used the MVC pattern and the implementation was surprisingly straight forward and easy.&#160; The hardest part was getting the web.config exactly right.</p>  <p>Because of some other things we were doing, we ended up with quite a bit of code in global.asax. We also ran into a requirement to host URLs that didn’t have an extension. It became difficult to work around IIS’ “helpfulness” and we had a lot more code than it felt like we should.</p>  <h2>HTTP Module to the Rescue</h2>  <p>Having built a number of ISAPI extensions and filters, I was not looking forward to implementing an HTTP Module. Fortunately, IIS has come a long way and the module really wasn’t any harder than the handler.</p>  <p>The module cleaned up (ie removed) global.asax.cs. The module also gave us a very nice encapsulation and deployment story.</p>  <p>Later in the process, we decided that we wanted to instrument our code and log some results to Azure tables.&#160; The module made this easy to do as we didn’t have to modify any page level code.&#160; You could accomplish the same thing from global.asax, but it wouldn’t be as nicely encapsulated or as easy to reuse.</p>  <p>I have never been a huge MVC fan, but after implementing an HTTP Module using MVC, there are some problems that are much easier to solve and the code is much cleaner.</p>  <h2>Azure Peculiarities</h2>  <p>We are storing all of our data in Azure Tables (anxiously awaiting the next version of SDS).&#160; One of the key things our code does is break the URL into pieces (i.e. Tenant ID and Page ID).&#160; Once it does this, it checks an Azure table to determine if the page exists (remember, we don’t know the set of pages in advance) and if we have rights to the page.&#160; Most of us are used to case-insensitive URLs and Azure tables are case-sensitive.&#160; Another issue is that many pages have an extension (i.e. rss.xml).&#160; Azure doesn’t like special characters in the key or the search fields, so this needs to be handled.&#160; Obviously it’s not difficult, if you know the issues in advance.</p>  <p>We chose to store the Tenant ID and Page ID natively – in our case using proper case and allowing file extensions.&#160; The partition key is the escaped, lowercase of the Tenant ID and the row key is the same for the Page ID.</p>  <p>We embedded these rules in the SitePage class and created a constructor that takes Tenant ID and Page ID.&#160; We then use the partition key and row key as our parameters.&#160; The code looks something like this:</p> <code>SitePage sp = new SitePage(“BartsWeb”, “rss.xml”)    <br />ValidatePage(sp.PartitionKey, sp.RowKey)</code>   <br />  <p>We decided on this approach as we use the entity classes in multiple layers of the app.&#160; This approach gives us good encapsulation and forces the user making the call to pass the right parameters.&#160; There may also be scenarios in the future where we don’t want to enforce these rules.</p>  <h2>Mapping the Request</h2>  <p>The HTTP Module also gives us the best of both worlds when handling a request.&#160; Depending on the type of request (retrieved from the Azure table), we can use URL Rewrite to send the request to an existing ASPX page or we can invoke one or the custom handlers to process the code.</p>  <p>Our original intent was to process all of the requests with custom handlers and this worked really well for read pages.&#160; When it came time to build forms for updating, the ASPX model really made development and debugging easier.&#160; Once debugged, if we choose, we can move the code into a custom handler and change the mapping in the table.</p>  <h2>Performance of the HTTP Module</h2>  <p>We had plans to implement caching for our June release, but decided to postpone the feature to a later release as our performance was more than adequate.&#160; I was amazed at how few lines of code it took to build a custom controller.&#160; The IIS team did a great job building a platform.</p>  <h2>Packaging the Sample</h2>  <p>I’m in the process of packaging a simple HTTP Module that handles a multi-tenant mapping strategy and implements custom asynchronous logging to Azure tables.&#160; We have a June 30 ship date, so it may take a couple of weeks for me to get the sample cleaned up and posted.</p>]]></content:encoded>
    </item>
    <item>
      <title>Using LINQ to XML with Azure Tables</title>
      <link>https://docs.microsoft.com/archive/blogs/rxg/using-linq-to-xml-with-azure-tables</link>
      <pubDate>Mon, 01 Jun 2009 00:04:00 GMT</pubDate>
      <dc:creator><![CDATA[bartr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rxg/2009/06/01/using-linq-to-xml-with-azure-tables/</guid>
      <description><![CDATA[In a previous post, I implemented the Azure Table REST APIs as a starting point for testing...]]></description>
      <content:encoded><![CDATA[<FONT size=3 face=Calibri></FONT><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><FONT size=3 face=Calibri><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">In a previous <A href="https://blogs.msdn.com/rxg/archive/2009/04/06/accessing-azure-tables-and-blobs-via-rest.aspx" mce_href="https://blogs.msdn.com/rxg/archive/2009/04/06/accessing-azure-tables-and-blobs-via-rest.aspx"><SPAN style="COLOR: #009933">post</SPAN></A>, I implemented the Azure Table REST APIs as a starting point for testing without having to use the Storage Client sample that ships in the Azure SDK.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The Azure Storage REST API is documented <A href="https://msdn.microsoft.com/en-us/library/dd179355.aspx" mce_href="https://msdn.microsoft.com/en-us/library/dd179355.aspx"><SPAN style="COLOR: #009933">here</SPAN></A>.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Instructions and the updated code that demonstrates processing Azure table data with LINQ to XML are at the bottom of this post.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Version 3</SPAN></B><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">After&nbsp;using the original code in a few prototype projects, I&nbsp;very quickly got tired of writing XML parsing code.&nbsp; I tried several different methods, including using LINQ to XML.&nbsp; After getting the code debugged, LINQ to XML is definitely my preferred approach for parsing XML data.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">&nbsp;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Getting LINQ to XML Working<o:p></o:p></SPAN></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Step one to getting LINQ to XML to work on the Azure table data is adding the two XML Namespaces that correspond to the "m:" and "d:" prefixes on the properties and data elements in the XML.<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt">XNamespace</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"> xnD = <SPAN style="COLOR: #a31515">"<A href="https://schemas.microsoft.com/ado/2007/08/dataservices" mce_href="https://schemas.microsoft.com/ado/2007/08/dataservices"><FONT color=#0000ff>https://schemas.microsoft.com/ado/2007/08/dataservices</FONT></A>"</SPAN>;<BR><SPAN style="COLOR: #2b91af">XNamespace</SPAN> xnM = <SPAN style="COLOR: #a31515">"<A href="https://schemas.microsoft.com/ado/2007/08/dataservices/metadata" mce_href="https://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><FONT color=#0000ff>https://schemas.microsoft.com/ado/2007/08/dataservices/metadata</FONT></A>"</SPAN>;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">The next step is to get the results into an XDocument so that LINQ can parse the data.&nbsp; It is very simple to use the HttpWebResponse ResponseStream as the source for the XDocument.<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt">using</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"> (<SPAN style="COLOR: #2b91af">HttpWebResponse</SPAN> res ...<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt">XDocument</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: black; FONT-SIZE: 10pt"> xDoc = </SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt">XDocument</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">.Parse(<SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">StreamReader</SPAN>(res.GetResponseStream()).ReadToEnd());<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Now that we have an XDocument, we can write LINQ queries to process the data.&nbsp; For this example, assume the simple Contact class.&nbsp; Notice that there is nothing special about this class, it's&nbsp;just an&nbsp;entity class.<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt">public</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"> <SPAN style="COLOR: blue">class</SPAN> <SPAN style="COLOR: #4bacc6; mso-themecolor: accent5">Contact</SPAN><o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">{<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>public</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"> <SPAN style="COLOR: blue">string</SPAN> FirstName { <SPAN style="COLOR: blue">get</SPAN>; <SPAN style="COLOR: blue">set</SPAN>; }<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>public</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"> <SPAN style="COLOR: blue">string</SPAN> LastName { <SPAN style="COLOR: blue">get</SPAN>; <SPAN style="COLOR: blue">set</SPAN>; }<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>public</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt"> <SPAN style="COLOR: blue">string</SPAN> Phone { <SPAN style="COLOR: blue">get</SPAN>; <SPAN style="COLOR: blue">set</SPAN>; }<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">This LINQ query will get a list of all of the contacts from the XDocument:<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">var</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> list = (<SPAN style="COLOR: blue">from</SPAN> properties <SPAN style="COLOR: blue">in</SPAN> xDoc.Descendants(xnM + <SPAN style="COLOR: #a31515">"properties"</SPAN>)<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">select</SPAN> <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">Contact<o:p></o:p></SPAN></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>FirstName = <SPAN style="COLOR: #2b91af">XConvert</SPAN>.ToString(properties.Element(xnD + <SPAN style="COLOR: #a31515">"FirstName"</SPAN>)),<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>LastName = <SPAN style="COLOR: #2b91af">XConvert</SPAN>.ToString(properties.Element(xnD + <SPAN style="COLOR: #a31515">"LastName"</SPAN>)),<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Phone = <SPAN style="COLOR: #2b91af">XConvert</SPAN>.ToString(properties.Element(xnD + <SPAN style="COLOR: #a31515">"Phone"</SPAN>)),<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>});<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Notice the&nbsp;XML Namespace qualifiers.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">&nbsp;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Also notice the call to XConvert.ToString().&nbsp; XConvert is a helper class that I wrote to handle the results from LINQ.&nbsp; It is much like the built-in Convert class in that it has static methods for converting to a variety of types.&nbsp; The big difference is that it takes an XElement as a parameter.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">&nbsp;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">It turns out that simply checking <SPAN style="COLOR: #0000cc">Element("foo").Value</SPAN> for null isn't&nbsp;sufficient.&nbsp; If the source XML doesn't contain the element (i.e. a version change on the data), Element is actually null.&nbsp; The XConvert methods check that <SPAN style="COLOR: #0000cc">Element</SPAN> is not null and that <SPAN style="COLOR: #0000cc">Element.Value</SPAN> is not null.&nbsp; If either of these are null, the method returns the default value (<SPAN style="COLOR: #0000cc">string.empty</SPAN>).&nbsp; For non-string types, the methods use <SPAN style="COLOR: #0000cc">TryParse</SPAN> to convert the values and return the value or the default depending upon success.&nbsp; The XConvert class is included in the sample code.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">&nbsp;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">You can use a foreach loop to process the items in the list just like you would any IEnumerator.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">&nbsp;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">I like to use the generic List&lt;T&gt; data structure within my apps.&nbsp; It turns out that it is very easy to do this:<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt">List</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">&lt;<SPAN style="COLOR: #2b91af">Contact</SPAN>&gt; ContactList = list.ToList&lt;<SPAN style="COLOR: #2b91af">Contact</SPAN>&gt;();<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">You can also have LINQ create the strongly typed list for you.&nbsp; Replace the "var" on the first line of the query with the type (in this case, <SPAN style="COLOR: #0000cc">List&lt;Contact&gt;</SPAN>).&nbsp; On the last line, add the <SPAN style="COLOR: #0000cc">.ToList&lt;Contact&gt;()</SPAN> between the "})" and ";".<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">To determine if there are any results, you can use:<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt">list.Any&lt;<SPAN style="COLOR: #2b91af">Contact</SPAN>&gt;()<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">To get the first element in the list<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">if</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> (list.Any&lt;<SPAN style="COLOR: #2b91af">Contact</SPAN>&gt;())<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">Contact</SPAN> person = list.First&lt;<SPAN style="COLOR: #2b91af">Contact</SPAN>&gt;();<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">This is helpful when you're&nbsp;only retrieving a single item from the query&nbsp;vs. a list of items.&nbsp;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Although not related to Azure, LINQ also lets you easily sort and filter lists in memory.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Sort:<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">var</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> sortedlist = <SPAN style="COLOR: blue">from</SPAN> c <SPAN style="COLOR: blue">in</SPAN> list<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">orderby</SPAN> c.LastName <SPAN style="COLOR: blue">descending</SPAN>, c.FirstName <SPAN style="COLOR: blue">descending<o:p></o:p></SPAN></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">select</SPAN> c;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Filter:<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">var</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> filteredlist = <SPAN style="COLOR: blue">from</SPAN> c <SPAN style="COLOR: blue">in</SPAN> ContactList<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">where</SPAN> c.FirstName == <SPAN style="COLOR: #a31515">"Jane"<o:p></o:p></SPAN></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">select</SPAN> c;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">I expect to use SDS for most Azure data storage needs, but when I use Azure tables, I will probably continue to call the REST interface and process with LINQ.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">&nbsp;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Caveats<o:p></o:p></SPAN></B></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1; mso-add-space: auto" class=MsoListParagraphCxSpFirst><SPAN style="FONT-FAMILY: Symbol; FONT-SIZE: 11pt; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-bidi-theme-font: minor-latin; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin">The code still only works on Azure Storage, it does not work on development storage (see my reasoning in previous posts)<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1; mso-add-space: auto" class=MsoListParagraphCxSpMiddle><SPAN style="FONT-FAMILY: Symbol; FONT-SIZE: 11pt; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-bidi-theme-font: minor-latin; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin">The updated code is sample code quality with limited error handling, testing, and comments, so it’s only appropriate for experimentation and as a starting point.&nbsp; If you find bugs, please let me know.<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1; mso-add-space: auto" class=MsoListParagraphCxSpMiddle><SPAN style="FONT-FAMILY: Symbol; FONT-SIZE: 11pt; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-bidi-theme-font: minor-latin; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin">The code is still all in one file, which is easy to post and get running the first time, but not a best practice for a real app.<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1; mso-add-space: auto" class=MsoListParagraphCxSpLast><SPAN style="FONT-FAMILY: Symbol; FONT-SIZE: 11pt; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; FONT-SIZE: 11pt; mso-bidi-theme-font: minor-latin; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin">You still need to update the account / secret information in the RESTHelper class.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Using the Sample Code<o:p></o:p></SPAN></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Create a new console application named AzureLINQXMLSample, then replace the code in Program.cs with the code attached below.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN><o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">&nbsp;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Change the “accountN” and “secretN” references to your Azure credentials.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I decided to embed the storage account information in the code vs. reading it from a config file.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This implementation uses a helper class to allow you to specify the account in the constructor, which makes it easy to use different accounts simultaneously.&nbsp; This has worked out well in development.&nbsp; For production, we're storing the data in the Azure config files, which is read from the DAL (data access layer).<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">&nbsp;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin">Note that you do not have to&nbsp;install the Azure SDK to use the sample code.&nbsp; A vanilla install of .NET 3.5 will work.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><o:p>&nbsp;</o:p></SPAN></P></SPAN></FONT></SPAN>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/67/47/15/Program.cs" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-67-47-15/Program.cs">Program.cs</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Quickly Testing Access Control Service</title>
      <link>https://docs.microsoft.com/archive/blogs/rxg/quickly-testing-access-control-service</link>
      <pubDate>Thu, 16 Apr 2009 21:47:00 GMT</pubDate>
      <dc:creator><![CDATA[bartr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rxg/2009/04/16/quickly-testing-access-control-service/</guid>
      <description><![CDATA[A colleague was having trouble getting Access Control Service to work correctly, so I put together a...]]></description>
      <content:encoded><![CDATA[<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">A colleague was having trouble getting Access Control Service to work correctly, so I put together a simple test to see what was being returned.</SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">This code will work from a web project, or you can just put it directly into an IIS folder.&nbsp; I have the realm set to localhost/default.aspx, so adjust the instructions as necessary to point to the correct URL.&nbsp; All you need is the WebForm page and the code-behind file.&nbsp; The code doesn't use Geneva, so it will work on a normal ASP.NET 3.5 install.</SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><STRONG>Step 1</STRONG> - create a web project and delete everything from default.aspx except the first line.&nbsp; Add a ValidateRequest="false" attribute to the Page directive.&nbsp; It should look similar to this</SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">&lt;%<SPAN style="COLOR: blue">@</SPAN> <SPAN style="COLOR: #a31515">Page</SPAN> <SPAN style="COLOR: red">ValidateRequest</SPAN><SPAN style="COLOR: blue">="false"</SPAN> <SPAN style="COLOR: red">Language</SPAN><SPAN style="COLOR: blue">="C#"</SPAN> <SPAN style="COLOR: red">CodeFile</SPAN><SPAN style="COLOR: blue">="Default.aspx.cs"</SPAN> <SPAN style="COLOR: red">Inherits</SPAN><SPAN style="COLOR: blue">="_Default"</SPAN> %&gt;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><STRONG>Step 2</STRONG> - Paste the following code into the Page_Load event</SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">if</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> (Request[<SPAN style="COLOR: #a31515">"wresult"</SPAN>] == <SPAN style="COLOR: blue">null</SPAN>)<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>Response.Redirect(<SPAN style="COLOR: #a31515">"https://</SPAN><SPAN style="COLOR: #00b0f0">{{Account}}</SPAN><SPAN style="COLOR: #a31515">.accesscontrol.windows.net/passivests/LiveFederation.aspx?wa=wsignin1.0&amp;wtrealm=https://localhost/default.aspx&amp;whr=https://login.live.com"</SPAN>);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">else<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>Response.Write(Request[<SPAN style="COLOR: #a31515">"wresult"</SPAN>]);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>Response.ContentType = <SPAN style="COLOR: #a31515">"text/xml"</SPAN>;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">Make sure to replace <SPAN style="COLOR: #00b0f0">{{Account}}</SPAN> with your ACS account name.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">This code will automatically redirect you to the Live Federation page where you can login with your Live ID.&nbsp; Once you successfully login, the code pulls the SAML out of the wresult form variable and displays it as XML.&nbsp; This allows you to quickly test changes to ACS.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">If you would like to control the output, you can replace the two lines of code that display the SAML with the following code:<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes"></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">XmlDocument</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> d = <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">XmlDocument</SPAN>();<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">d.LoadXml(Request[<SPAN style="COLOR: #a31515">"wresult"</SPAN>]);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">Response.Write(<SPAN style="COLOR: #a31515">"&lt;table border=1&gt;\n&lt;tr&gt;&lt;td&gt;AttributeName&lt;/td&gt;&lt;td&gt;Value&lt;/td&gt;&lt;/tr&gt;\n"</SPAN>);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">foreach</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> (<SPAN style="COLOR: #2b91af">XmlNode</SPAN> node <SPAN style="COLOR: blue">in</SPAN> d.GetElementsByTagName(<SPAN style="COLOR: #a31515">"saml:Attribute"</SPAN>))<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">if</SPAN> (node.Attributes.GetNamedItem(<SPAN style="COLOR: #a31515">"AttributeName"</SPAN>) != <SPAN style="COLOR: blue">null</SPAN>)<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Response.Write(<SPAN style="COLOR: blue">string</SPAN>.Format(<SPAN style="COLOR: #a31515">"&lt;tr&gt;&lt;td&gt;{0}&lt;/td&gt;&lt;td&gt;{1}&lt;/td&gt;&lt;/tr&gt;\n"</SPAN>, node.Attributes.GetNamedItem(<SPAN style="COLOR: #a31515">"AttributeName"</SPAN>).Value, node.InnerText));<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">Response.Write(<SPAN style="COLOR: #a31515">"&lt;/table&gt;\n"</SPAN>);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">In my case, the display looks like this:<o:p></o:p></SPAN></P>
<P>
<TABLE style="mso-cellspacing: 1.5pt; mso-yfti-tbllook: 1184" class=MsoNormalTable border=1 cellPadding=0 class="MsoNormalTable">
<TBODY>
<TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<TD style="BORDER-BOTTOM: #f0f0f0; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0.75pt; BACKGROUND-COLOR: transparent; PADDING-LEFT: 0.75pt; PADDING-RIGHT: 0.75pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: #f0f0f0; PADDING-TOP: 0.75pt">
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">AttributeName<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-BOTTOM: #f0f0f0; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0.75pt; BACKGROUND-COLOR: transparent; PADDING-LEFT: 0.75pt; PADDING-RIGHT: 0.75pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: #f0f0f0; PADDING-TOP: 0.75pt">
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">Value<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 1">
<TD style="BORDER-BOTTOM: #f0f0f0; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0.75pt; BACKGROUND-COLOR: transparent; PADDING-LEFT: 0.75pt; PADDING-RIGHT: 0.75pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: #f0f0f0; PADDING-TOP: 0.75pt">
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">role<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-BOTTOM: #f0f0f0; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0.75pt; BACKGROUND-COLOR: transparent; PADDING-LEFT: 0.75pt; PADDING-RIGHT: 0.75pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: #f0f0f0; PADDING-TOP: 0.75pt">
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">Admin<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 2">
<TD style="BORDER-BOTTOM: #f0f0f0; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0.75pt; BACKGROUND-COLOR: transparent; PADDING-LEFT: 0.75pt; PADDING-RIGHT: 0.75pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: #f0f0f0; PADDING-TOP: 0.75pt">
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">emailaddress<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-BOTTOM: #f0f0f0; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0.75pt; BACKGROUND-COLOR: transparent; PADDING-LEFT: 0.75pt; PADDING-RIGHT: 0.75pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: #f0f0f0; PADDING-TOP: 0.75pt">
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">user@foo.com<o:p></o:p></SPAN></P></TD></TR>
<TR style="mso-yfti-irow: 3; mso-yfti-lastrow: yes">
<TD style="BORDER-BOTTOM: #f0f0f0; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0.75pt; BACKGROUND-COLOR: transparent; PADDING-LEFT: 0.75pt; PADDING-RIGHT: 0.75pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: #f0f0f0; PADDING-TOP: 0.75pt">
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">name<o:p></o:p></SPAN></P></TD>
<TD style="BORDER-BOTTOM: #f0f0f0; BORDER-LEFT: #f0f0f0; PADDING-BOTTOM: 0.75pt; BACKGROUND-COLOR: transparent; PADDING-LEFT: 0.75pt; PADDING-RIGHT: 0.75pt; BORDER-TOP: #f0f0f0; BORDER-RIGHT: #f0f0f0; PADDING-TOP: 0.75pt">
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">user@foo.com</SPAN></P></TD></TR></TBODY></TABLE></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><B><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; COLOR: red; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"></SPAN></B>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><B><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; COLOR: red; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt"></SPAN></B>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><B><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; COLOR: red; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt">This is NOT a secure implementation</SPAN></B><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"> - for that, use Geneva.&nbsp; However, this will help you quickly validate if you're getting what you expect from the Live ID Federation page.</SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" class=MsoNormal><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'"></SPAN></P>]]></content:encoded>
    </item>
    <item>
      <title>Accessing Azure Tables and Blobs via REST</title>
      <link>https://docs.microsoft.com/archive/blogs/rxg/accessing-azure-tables-and-blobs-via-rest</link>
      <pubDate>Mon, 06 Apr 2009 21:30:00 GMT</pubDate>
      <dc:creator><![CDATA[bartr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rxg/2009/04/06/accessing-azure-tables-and-blobs-via-rest/</guid>
      <description><![CDATA[In a previous post, I implemented a few of the Azure Table REST APIs as a starting point for...]]></description>
      <content:encoded><![CDATA[<FONT size=3 face=Calibri>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal>In a previous <A href="https://blogs.msdn.com/rxg/archive/2009/04/02/accessing-azure-tables-via-rest.aspx" mce_href="https://blogs.msdn.com/rxg/archive/2009/04/02/accessing-azure-tables-via-rest.aspx">post</A>, I implemented a few of the Azure Table REST APIs as a starting point for testing without having to use the Storage Client sample that ships in the Azure SDK.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The Azure Storage REST API is documented <A href="https://msdn.microsoft.com/en-us/library/dd179355.aspx" mce_href="https://msdn.microsoft.com/en-us/library/dd179355.aspx">here</A>.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Instructions and the updated code are at the bottom of this post.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p>&nbsp;</o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal">Version 2<o:p></o:p></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal>In this version of the code, I added support for<B style="mso-bidi-font-weight: normal"><I style="mso-bidi-font-style: normal"> </I></B>all of the Azure Table REST API as well as the Azure Blob API (minus the blob chunking).<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Based on the docs, the queue API looks very similar to the Blob API, so it shouldn't be difficult to implement.<o:p></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p>&nbsp;</o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal>For the entity insert and update table methods, I chose to use a simple entity class and use reflection to convert the properties into the appropriate XML payload.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I liked this better than using a dictionary type collection or hard coding the implementation.<o:p></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p>&nbsp;</o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal>My original goal was to have all of the REST functionality encapsulated in the RESTHelper class.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>After trying that for a while, I decided that there were enough differences to warrant different implementations for blobs and tables.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The account, secret, SharedKey generation, and exception handling are shared, but the signature creation and request execution are separate implementations.<o:p></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p>&nbsp;</o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal>To make the logic a little simpler, I implemented a “command” parameter in the Blob RESTExec method.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>For most requests, this is the HTTP Method, but for some requests additional headers have to be added.<SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>This seems simpler than using a combination of URI and Method or adding another parameter.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>There is code that uses the Command parameter to modify the URI, set the HTTP method, and add headers as appropriate.<o:p></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p>&nbsp;</o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal">Caveats<o:p></o:p></B></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class=MsoListParagraph><SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN>The code still only works on Azure Storage, it does not work on development storage (see my reasoning in the previous post).<o:p></o:p></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class=MsoListParagraph><SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN>I have only implemented / tested with string data.<o:p></o:p></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class=MsoListParagraph><SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN>The updated code is sample code quality with limited error handling, testing, and comments, so it’s only appropriate for experimentation and as a starting point.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN><o:p></o:p></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class=MsoListParagraph><SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN>The code is still all in one file, which is easy to post and get running the first time, but not a best practice for a real app.<o:p></o:p></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class=MsoListParagraph><SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN>You still need to update the account / secret information in the RESTHelper class.<o:p></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p>&nbsp;</o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal">Feedback<o:p></o:p></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal>One of the Azure developers clarified a comment I made in my original post about including query strings in the signature.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In his words:<SPAN style="mso-spacerun: yes">&nbsp; </SPAN><SPAN style="COLOR: #1f497d; mso-themecolor: text2">“For blobs, one must include only the ‘comp’ query parameter if it exists, not the entire query string.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The ‘comp’ query parameter identifies a sub-resource and hence is integral to the resource being operated on by the request.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This is the reason to include it in the signature.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Table storage doesn’t use the ‘comp’ query parameter, so we don’t include it there.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This can be simply said as “Include the ‘comp’ query parameter into the canonicalized resources if it exists.”<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This probably holds good for all services.”</SPAN><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This makes sense and helped me when I was implementing the Blob API.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Thanks Rags!<o:p></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p>&nbsp;</o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal>Another suggestion was to use the .NET ATOM classes to process the Table results.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I tried this, but chose to stick with direct XML instead.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>If you choose to use the Table REST API directly, you might want to look into the syndication classes.<o:p></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p>&nbsp;</o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal">Learnings<o:p></o:p></B></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l1 level1 lfo2" class=MsoListParagraph><SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN>Make sure to wrap all of your web calls with using or explicitly close the connections.<o:p></o:p></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l1 level1 lfo2" class=MsoListParagraph><SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN>Azure Blob containers don’t appear to support capital letters.<o:p></o:p></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l1 level1 lfo2" class=MsoListParagraph><SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN>Getting the signature exactly right is still the hardest part.<o:p></o:p></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 1in; mso-list: l1 level2 lfo2" class=MsoListParagraph><SPAN style="FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Courier New'"><SPAN style="mso-list: Ignore">o<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp; </SPAN></SPAN></SPAN>I now understand why the API forces resources and headers to be canonicalized.<o:p></o:p></P>
<P style="TEXT-INDENT: -0.25in; MARGIN: 0in 0in 0pt 0.5in; mso-list: l1 level1 lfo2" class=MsoListParagraph><SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"><SPAN style="mso-list: Ignore">·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN>The REST API is great for viewing arbitrary tables without knowing the structure in advance.<o:p></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p>&nbsp;</o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal">Using the Sample Code<o:p></o:p></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal>Create a new console application named AzureStorageConsole, then replace the code in Program.cs with the code attached below.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-spacerun: yes"></SPAN>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="mso-spacerun: yes"></SPAN>Change the “accountN” and “secretN” references to your Azure credentials.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I decided to embed the storage account information in the code vs. reading it from a config file.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This implementation uses a helper class to allow you to specify the account in the constructor, which makes it easy to use different accounts simultaneously.</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal mce_keep="true">&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal>Note that you do not have to&nbsp;install the Azure SDK to use the sample code.&nbsp; A vanilla install of .NET 3.5 will work.</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal mce_keep="true">&nbsp;</P></FONT>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/53/43/91/Program.cs" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-53-43-91/Program.cs">Program.cs</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Accessing Azure Tables via REST</title>
      <link>https://docs.microsoft.com/archive/blogs/rxg/accessing-azure-tables-via-rest</link>
      <pubDate>Thu, 02 Apr 2009 22:30:00 GMT</pubDate>
      <dc:creator><![CDATA[bartr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rxg/2009/04/02/accessing-azure-tables-via-rest/</guid>
      <description><![CDATA[Most of the Azure table samples that I can find use the Storage Client to access the tables, which...]]></description>
      <content:encoded><![CDATA[<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3 face=Calibri>Most of the Azure table samples that I can find use the Storage Client to access the tables, which in turn uses the ADO.NET Data Services.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>While this provides a rich set of functionality, I wanted to explore the simplicity and flexibility of calling the REST API directly.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The Azure table storage API is documented </FONT><A href="https://msdn.microsoft.com/en-us/library/dd179423.aspx" mce_href="https://msdn.microsoft.com/en-us/library/dd179423.aspx"><FONT color=#0000ff size=3 face=Calibri>here</FONT></A><FONT size=3><FONT face=Calibri>.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Using that, and the REST helpers in the Storage Client, I was able to create a simple console app that calls the Azure table API directly.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Instructions and a link to the code are at the bottom of this post.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri><STRONG>Development Storage</STRONG></FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Note that this code has not been tested on development storage, only on the Azure services.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I decided to quit using the development storage a couple of months ago and now only use Azure storage.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>My reasoning was simple:<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Azure storage is very similar to development storage, but it is not exact.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I didn’t want to have to understand or debug the nuances.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I also didn’t want to have to migrate the data every time I did a build.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>My experience also told me that it was very important to understand the performance of the data subsystem. <SPAN style="mso-spacerun: yes">&nbsp;</SPAN>Identifying data performance issues early is a lot better than staying up all night putting hot fixes into your latest release, and running the storage services remotely with the web server local is just about a worst case scenario.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>As a remote member of the team, it is also much easier to share code that talks to the same storage.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>You don’t have to worry about synching your tables every time you want to jointly debug an app.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Your mileage may vary, but I am very happy with the decision.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><FONT size=3><FONT face=Calibri>The Code<o:p></o:p></FONT></FONT></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>My goal for this exercise is pretty simple.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I want to list all of the tables in the storage account and I want to display all of the data within any one of those tables.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>While writing the code, I decided that I want to be able to limit the queries with a “where” clause (mainly because it was really easy to do).<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>With the goal of keeping it simple, I’m delaying table create and delete and entity insert, update, and delete until later.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3 face=Calibri>According to the </FONT><A href="https://msdn.microsoft.com/en-us/library/dd179405.aspx" mce_href="https://msdn.microsoft.com/en-us/library/dd179405.aspx"><FONT color=#0000ff size=3 face=Calibri>documents</FONT></A><FONT size=3 face=Calibri>, in order to get a list of tables, all one has to do is use HTTP GET to call </FONT><A href="https://myaccount.table.core.windows.net/Tables" mce_href="https://myaccount.table.core.windows.net/Tables"><FONT color=#0000ff size=3 face=Calibri>https://myaccount.table.core.windows.net/Tables</FONT></A><FONT size=3><FONT face=Calibri> making sure to replace myaccount with the correct storage account.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>After some more digging, it turns out that you have to add some headers to the request, including a signature header.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Figuring out exactly how to construct those headers was the only difficult part of the exercise.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Here is a walkthrough of the code.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><FONT size=3><FONT face=Calibri>Step 1 - Create the web request<o:p></o:p></FONT></FONT></B></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// Resource = “Tables”<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// _Account = your Azure Storage Account<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">string</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> uri = <SPAN style="COLOR: #a31515">@"https://"</SPAN> + _Account + <SPAN style="COLOR: #a31515">".table.core.windows.net/"</SPAN> + Resource;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">HttpWebRequest</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> request = (<SPAN style="COLOR: #2b91af">HttpWebRequest</SPAN>)<SPAN style="COLOR: #2b91af">HttpWebRequest</SPAN>.Create(uri);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">request.Method = <SPAN style="COLOR: #a31515">"GET"</SPAN>;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">request.ContentLength = 0;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><FONT size=3><FONT face=Calibri>Step 2 – Add a date header to the request<o:p></o:p></FONT></FONT></B></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">request.Headers.Add(<SPAN style="COLOR: #a31515">"x-ms-date"</SPAN>, <SPAN style="COLOR: #2b91af">DateTime</SPAN>.UtcNow.ToString(<SPAN style="COLOR: #a31515">"R"</SPAN>, System.Globalization.<SPAN style="COLOR: #2b91af">CultureInfo</SPAN>.InvariantCulture));<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><FONT size=3><FONT face=Calibri>Step 3 - Sign the request<o:p></o:p></FONT></FONT></B></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">For a table, you need to use this Canonical form:<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">VERB + "\n" +<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">Content - MD5 + "\n" +<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">Content - Type + "\n" +<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">Date + "\n" +<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">CanonicalizedResources<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>My first reaction to this was – huh?<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I pieced together the following code that implements the above.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// Verb<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">string</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> signature = <SPAN style="COLOR: #a31515">"GET\n"</SPAN>;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// Content-MD5<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">signature += <SPAN style="COLOR: #a31515">"\n"</SPAN>;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// Content-Type<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">signature += <SPAN style="COLOR: #a31515">"\n"</SPAN>;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// Date<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">signature += request.Headers[<SPAN style="COLOR: #a31515">"x-ms-date"</SPAN>] + <SPAN style="COLOR: #a31515">"\n"</SPAN>;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// remove the query string<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">int</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> q = Resource.IndexOf(<SPAN style="COLOR: #a31515">"?"</SPAN>);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">if</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> (q &gt; 0) Resource = Resource.Substring(0, q);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// Canonicalized Resource<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// Format is /{0}/{1} where 0 is name of the account and 1 is resources URI path<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">signature += <SPAN style="COLOR: #a31515">"/"</SPAN> + _Account + <SPAN style="COLOR: #a31515">"/"</SPAN> + Resource;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Note that for the table storage signature, you remove the query string from the resource but for blob storage you do not.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This is documented in the API, but I missed it and wasted a lot of debug cycles.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><FONT size=3><FONT face=Calibri>Step 4 - Hash the signature with the secret and add the result to the SharedKey header<o:p></o:p></FONT></FONT></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Replace _Secret with your Azure account secret.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Table Storage also supports SharedKeyLite, but Blobs don’t, so I decided to stick with SharedKey.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// Hash-based Message Authentication Code (HMAC) using SHA256 hash<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">System.Security.Cryptography.<SPAN style="COLOR: #2b91af">HMACSHA256</SPAN> hasher = <SPAN style="COLOR: blue">new</SPAN> System.Security.Cryptography.<SPAN style="COLOR: #2b91af">HMACSHA256</SPAN>(<SPAN style="COLOR: #2b91af">Convert</SPAN>.FromBase64String(<SPAN style="COLOR: #2b91af">_</SPAN>Secret));<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// Authorization header<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">string</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> authH = <SPAN style="COLOR: #a31515">"SharedKey "</SPAN> + _Account + <SPAN style="COLOR: #a31515">":"</SPAN> + System.<SPAN style="COLOR: #2b91af">Convert</SPAN>.ToBase64String(hasher.ComputeHash(System.Text.<SPAN style="COLOR: #2b91af">Encoding</SPAN>.UTF8.GetBytes(signature)));<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><FONT size=3><FONT face=Calibri>Step 5 - Getting the results<o:p></o:p></FONT></FONT></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">using</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> </SPAN><FONT size=3 face=Calibri>(</FONT><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">HttpWebResponse</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> response = (<SPAN style="COLOR: #2b91af">HttpWebResponse</SPAN>)request.GetResponse())<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">using</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> (System.IO.<SPAN style="COLOR: #2b91af">StreamReader</SPAN> r = <SPAN style="COLOR: blue">new</SPAN> System.IO.<SPAN style="COLOR: #2b91af">StreamReader</SPAN>(response.GetResponseStream()))<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">string xml = r.ReadToEnd();<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">int ret</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> = response.StatusCode;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN><o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><FONT face=Calibri><FONT size=3>Step 6 – Processing the results<o:p></o:p></FONT></FONT></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3 face=Calibri>According to the Azure Table API </FONT><A href="https://msdn.microsoft.com/en-us/library/dd179405.aspx" mce_href="https://msdn.microsoft.com/en-us/library/dd179405.aspx"><FONT color=#0000ff size=3 face=Calibri>document</FONT></A><FONT size=3><FONT face=Calibri>,<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>“The <STRONG><SPAN style="FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi">Query Tables</SPAN></STRONG> operation returns the list of tables in the account as an ADO.NET entity set, which is an Atom feed.”<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The documentation shows the XML results returned.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In this case, all we care about is the “d:TableName” repeating element.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">if</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> (ret == 200)<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">XmlDocument</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> doc = <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">XmlDocument</SPAN>();<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">doc.LoadXml(xml);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">XmlNodeList</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> nodes = doc.GetElementsByTagName(<SPAN style="COLOR: #a31515">"d:TableName"</SPAN>);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">Console</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">.WriteLine(<SPAN style="COLOR: #a31515">"Tables in Account: "</SPAN> + _Account);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">foreach</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> (<SPAN style="COLOR: #2b91af">XmlNode</SPAN> n <SPAN style="COLOR: blue">in</SPAN> nodes)<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">Console</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">.WriteLine(n.InnerText);<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">else<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">Console</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">.WriteLine(xml);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">Console</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">.WriteLine();<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>That’s all there is to it.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Once you get this code working, it’s pretty easy to modify the URIs for other calls.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Simply change the Resource.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Here are some examples queries:<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Customers – returns all rows from the Customers table (assuming that table actually exists)<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Customers?$filter=state eq TX<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Songs?$filter=rating ge 3<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3 face=Calibri>The general format to retrieve data from a table is “mytable$filter=&lt;query-expression&gt;”.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>More information is available </FONT><A href="https://msdn.microsoft.com/en-us/library/dd179421.aspx" mce_href="https://msdn.microsoft.com/en-us/library/dd179421.aspx"><FONT color=#0000ff size=3 face=Calibri>here</FONT></A><FONT size=3><FONT face=Calibri>.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>The following code will process the results from the table, displaying each field of each row.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">if</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> (status == 200)<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">XmlDocument</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> doc = <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">XmlDocument</SPAN>();<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">doc.LoadXml(xml);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">XmlNodeList</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> nodes = doc.GetElementsByTagName(<SPAN style="COLOR: #a31515">"m:properties"</SPAN>);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// process each row<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">foreach</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> (<SPAN style="COLOR: #2b91af">XmlNode</SPAN> n <SPAN style="COLOR: blue">in</SPAN> nodes)<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: green; FONT-SIZE: 10pt; mso-no-proof: yes">// process each column<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">foreach</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> (<SPAN style="COLOR: #2b91af">XmlNode</SPAN> n2 <SPAN style="COLOR: blue">in</SPAN> n.ChildNodes)<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt 1in; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">Console</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">.Write(n2.Name + <SPAN style="COLOR: #a31515">": " + </SPAN>n2.InnerText);<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">Console</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">.WriteLine();<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}</SPAN><o:p></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><FONT size=3><FONT face=Calibri>Sample Console App Code<o:p></o:p></FONT></FONT></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>If you create a new console application named AzureStorageConsole, you can replace the code in Program.cs with the code attached below.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>You will also need to change the “accountN” and “secretN” references to your Azure credentials.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I decided to embed the storage account information in the code vs. reading it from a config file.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This implementation uses a helper class to allow you to specify the account in the constructor, which makes it easy to use different accounts.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Lastly, you will need to replace the Customer table queries with existing tables in your storage account.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>The next steps are to add support for creating and deleting tables as well as insert, edit, and delete capabilities to individual tables.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I am also going to play around with the REST APIs for Blobs and Queues.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>They appear to be quite a bit simpler than the Table API.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/53/00/09/Program.cs" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-53-00-09/Program.cs">Program.cs</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Using Azure Storage Outside of Azure Hosting</title>
      <link>https://docs.microsoft.com/archive/blogs/rxg/using-azure-storage-outside-of-azure-hosting</link>
      <pubDate>Mon, 30 Mar 2009 22:20:00 GMT</pubDate>
      <dc:creator><![CDATA[bartr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rxg/2009/03/30/using-azure-storage-outside-of-azure-hosting/</guid>
      <description><![CDATA[Azure provides a set of storage services – blob, queue, and table – that are accessed via REST...]]></description>
      <content:encoded><![CDATA[<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Azure provides a set of storage services – blob, queue, and table – that are accessed via REST interfaces.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The Azure SDK provides a sample .Net library that wraps the REST API to make Azure Storage easy to consume.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>As long as you have Internet connectivity, these services are available to your application anywhere.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I have a hosting account at GoDaddy and wanted to check the feasibility of storing data in Azure while hosting outside of the Azure data center.<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;</SPAN></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri><SPAN style="mso-spacerun: yes"></SPAN></FONT></FONT><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>To accomplish this, I simply copied the Lib folder from the Azure Storage Client sample in the Azure SDK.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This contains all of the helper functions that make accessing Azure storage from .Net simple.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>To help me keep things clear, I renamed the project and the folder StorageLibNoDepend.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Next I created a console solution in Visual Studio and added the StorageLibNoDepend project to the solution.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>A quick compile verified that everything works.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><FONT size=3><FONT face=Calibri>Now to break it …<o:p></o:p></FONT></FONT></B></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>I removed the reference to Microsoft.ServiceHosting.ServiceRuntime from the StorageLib project and let the compiler find the dependencies.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The first dependency was a using statement in StorageAccountInfo.cs (it turns out that all of the changes are in this one file).<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>All of the other changes had to do with reading configuration settings from the Azure config service rather than the config files.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I simply deleted these large blocks of code (5 or 6 of them) and the system compiled.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Next I added an app.config file with the following settings:<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">&lt;</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes">configuration</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">&gt;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>&lt;</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes">appSettings</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">&gt;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>&lt;</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes">add</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"> </SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes">key</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">=</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">"<SPAN style="COLOR: blue">AccountName</SPAN>"<SPAN style="COLOR: blue"> </SPAN><SPAN style="COLOR: red">value</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">youraccountname</SPAN>"<SPAN style="COLOR: blue">/&gt;<o:p></o:p></SPAN></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>&lt;</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes">add</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"> </SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes">key</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">=</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">"<SPAN style="COLOR: blue">AccountSharedKey</SPAN>"<SPAN style="COLOR: blue"> </SPAN><SPAN style="COLOR: red">value</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">yourkey</SPAN>"<SPAN style="COLOR: blue">/&gt;<o:p></o:p></SPAN></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>&lt;</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes">add</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"> </SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes">key</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">=</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">"<SPAN style="COLOR: blue">BlobStorageEndpoint</SPAN>"<SPAN style="COLOR: blue"> </SPAN><SPAN style="COLOR: red">value</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">https://blob.core.windows.net</SPAN>"<SPAN style="COLOR: blue">/&gt;<o:p></o:p></SPAN></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>&lt;</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes">add</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"> </SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes">key</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">=</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">"<SPAN style="COLOR: blue">QueueStorageEndpoint</SPAN>"<SPAN style="COLOR: blue"> </SPAN><SPAN style="COLOR: red">value</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">https://queue.core.windows.net</SPAN>"<SPAN style="COLOR: blue">/&gt;<o:p></o:p></SPAN></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>&lt;</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes">add</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"> </SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes">key</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">=</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">"<SPAN style="COLOR: blue">TableStorageEndpoint</SPAN>"<SPAN style="COLOR: blue"> </SPAN><SPAN style="COLOR: red">value</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">https://table.core.windows.net</SPAN>"<SPAN style="COLOR: blue">/&gt;<o:p></o:p></SPAN></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>&lt;</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes">add</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"> </SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes">key</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">=</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">"<SPAN style="COLOR: blue">UsePathStyleUris</SPAN>"<SPAN style="COLOR: blue"> </SPAN><SPAN style="COLOR: red">value</SPAN><SPAN style="COLOR: blue">=</SPAN>"<SPAN style="COLOR: blue">false</SPAN>"<SPAN style="COLOR: blue">/&gt;<o:p></o:p></SPAN></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>&lt;/</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes">appSettings</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">&gt;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">&lt;/</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes">configuration</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">&gt;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>You will need to update the AccountName and AccountSharedKey values appropriately.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Next, add a reference to the StorageLibNoDepend project to the console application.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Also add the following using statement to the console app.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">using</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> Microsoft.Samples.ServiceHosting.StorageClient;<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>Paste the following code into the Main method of the console application.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">BlobStorage</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> blobStorage = <SPAN style="COLOR: #2b91af">BlobStorage</SPAN>.Create(<SPAN style="COLOR: #2b91af">StorageAccountInfo</SPAN>.GetDefaultBlobStorageAccountFromConfiguration());<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes">foreach</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"> (<SPAN style="COLOR: #2b91af">BlobContainer</SPAN> b <SPAN style="COLOR: blue">in</SPAN> blobStorage.ListBlobContainers())<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P style="TEXT-INDENT: 0.5in; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">Console</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">.WriteLine(b.ContainerName);<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-no-proof: yes">Console</SPAN><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes">.ReadLine();<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>When you press F5, the application should run and display a list of all of the blob containers in your account.<o:p></o:p></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri>With this library, you can use Azure storage from any application, not just an app running in the Azure hosted environment.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>So far, the performance has been quite good as has the availability of Azure Storage.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I currently have three different applications – a web app hosted at GoDaddy, a web app hosted in Azure, and a console app – accessing the same database tables – no replication, synchronization, or conflict management to deal with!<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri><SPAN style="mso-spacerun: yes"></SPAN></FONT></FONT>&nbsp;</P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri><SPAN style="mso-spacerun: yes">Obviously, there are some performance implications to this model, but so far, the performance has been very good.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The key is limiting the amount of data returned whenever possible.&nbsp; <o:p></o:p></SPAN>The possibilities enabled by this type of cloud database are very exciting and the Azure Storage Library makes it very simple to consume.</FONT></FONT></P>
<P style="MARGIN: 0in 0in 0pt" class=MsoNormal><FONT size=3><FONT face=Calibri><o:p></o:p></FONT></FONT>&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Azure Multi-Tenant Addressing</title>
      <link>https://docs.microsoft.com/archive/blogs/rxg/azure-multi-tenant-addressing</link>
      <pubDate>Mon, 09 Mar 2009 02:20:00 GMT</pubDate>
      <dc:creator><![CDATA[bartr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rxg/2009/03/09/azure-multi-tenant-addressing/</guid>
      <description><![CDATA[There is a great thread on the MSDN forums about single-tenant vs. multi-tenant.&nbsp; It’s...]]></description>
      <content:encoded><![CDATA[<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>There is a great <A class="" href="https://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/5a6c0ff0-67b9-4bc3-8fbc-e07f00c9e51e" mce_href="https://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/5a6c0ff0-67b9-4bc3-8fbc-e07f00c9e51e">thread</A> on the MSDN forums about single-tenant vs. multi-tenant.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>It’s definitely worth the read.&nbsp; There is also a multi-tenant Azure sample available <A class="" href="https://azureissuetracker.codeplex.com/" mce_href="https://azureissuetracker.codeplex.com/">here</A>.&nbsp; Thanks to <A class="" href="https://blog.smarx.com/" mce_href="https://blog.smarx.com/">smarx</A> for helping me think through some of this.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>We are building an Azure-based, multi-tenant web prototype and came across an issue that is worth considering.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In particular, how do you address the website based on your tenancy?<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>We identified four ways to accomplish this – I would be interested if you know of other good techniques.<o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>The first one that came to mind was to use a sub-domain to specify the tenant (tenant1.azureapp.com, tenant2.azureapp.com, etc).<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I have done systems like this in the past and it worked very well.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>However, Azure complicates things a little bit.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Currently, Azure does not give you a specific IP address, but rather gives you an FQDN like coolapp.cloudapp.net.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I was not able to figure out a way to automatically map all hosts to this address as the A record is expecting an IP address.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Assuming I didn’t miss something, this means that you have to create a CNAME DNS entry for each tenant.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This isn’t a big deal for a “small” number of tenants, and there are use cases where the CNAME will actually be in the tenant’s domain.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>However, for a “large” number of tenants, this seems like additional management and could perhaps cause DNS issues (imagine 10K CNAMES in a domain).</FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>The next option I explored, and ultimately decided on, was to use the tenant name in the url (coolapp.cloudapp.net/tenant1/default.aspx, coolapp.cloudapp.net/tenant2/profile.aspx, etc.)<SPAN style="mso-spacerun: yes">&nbsp; </SPAN><o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>Another option thrown out was to map the tenant based on the Live ID.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This became very complex in scenarios where a Live ID was valid in multiple tenants, so it didn’t work for us, but this could be a good option for some.<o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>Another option was to specify the tenant name or ID in the query string.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This works fine, but didn’t seem as user friendly as the first two options.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>It turns out that this is exactly how we are implementing it under the covers, but&nbsp;I wanted to provide a more user friendly method.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>This is by far the easiest implementation.<o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><B style="mso-bidi-font-weight: normal"><FONT size=3><FONT face=Calibri>URL Rewriting<o:p></o:p></FONT></FONT></B></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>The option I ended up choosing basically maps a URL from coolapp.cloudapp.net/tenant1/default.aspx to coolapp.cloudapp.net/app/default.aspx?tenant=tenant1.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The initial plan was to use the IIS URL rewriting module to implement this feature.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Unfortunately, Azure doesn’t currently run this module, but since&nbsp;this is a commonly requested feature, hopefully it will make it into a future version of Azure.<o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>There are several page frameworks, including the <A class="" href="https://www.microsoft.com/downloads/details.aspx?familyid=a24d1e00-cd35-4f66-baa0-2362bdde0766&amp;displaylang=en" mce_href="https://www.microsoft.com/downloads/details.aspx?familyid=a24d1e00-cd35-4f66-baa0-2362bdde0766&amp;displaylang=en">ASP.NET MVC framework</A> that provide URL rewriting capabilities.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>It is also easy to implement URL re-writing in code.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In the Application_BeginRequest method in global.asax, use the HTTPContext.Current.RewritePath method to do the mapping for you.<o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri><STRONG>Our logic is pretty straight forward:<o:p></o:p></STRONG></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>If the request begins with “/app/”, redirect to “/”.<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;</SPAN>I don't&nbsp;want people accessing our app pages directly, which&nbsp;gives us the freedom to version and change&nbsp;the mappings later.&nbsp; </FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>If the request is in the root web folder or in the images web folder, ignore it.<o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>Otherwise, extract the tenant id and the page from the URL.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The URL is in the format coolapp.cloudapp.net/{tenant}/{page}.&nbsp; Make sure to deal with the coolapp.cloudapp.net/{tenant}/ request.<o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>Look the tenant id up in a database, and, if the id is valid and the page exists in the app folder, map to /app/{page}?tenantID={tenant}</FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>If the tenant id is not valid or if the page doesn’t exist, just let the request pass through and IIS will return a 404 error.<o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><B style="mso-bidi-font-weight: normal"><FONT size=3><FONT face=Calibri>Two Things I Learned<o:p></o:p></FONT></FONT></B></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>In general, this was a pretty simple task to implement.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>It isn’t fully tested yet, but so far, I’ve only hit two snags.<o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>The first, mentioned above,&nbsp;is to make sure to explicitly deal with the coolapp.cloudapp.net/{tenant}/ URL.&nbsp; </FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>The second, and maybe there’s a way to fix this, is to adjust the form Action property to point to the friendly URL instead of the actual URL.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>I used this piece of code in the Page_Load event of all of the ASPX files in the /app/ folder:<o:p></o:p></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri>form1.Action = "/" + Request.QueryString["tenantID"] </FONT></FONT><FONT size=3><FONT face=Calibri>+ Request.Path.Substring(Request.Path.LastIndexOf("/"));</FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT face=Calibri size=3></FONT>&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><FONT size=3><FONT face=Calibri><o:p></o:p></FONT></FONT>&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Access Control Service Sample v3</title>
      <link>https://docs.microsoft.com/archive/blogs/rxg/access-control-service-sample-v3</link>
      <pubDate>Tue, 24 Feb 2009 12:40:00 GMT</pubDate>
      <dc:creator><![CDATA[bartr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rxg/2009/02/24/access-control-service-sample-v3/</guid>
      <description><![CDATA[In a previous post, I wrote about a very simple Access Control Service example that I assembled...]]></description>
      <content:encoded><![CDATA[<P>In a previous <A title="ACS Sample" href="https://blogs.msdn.com/rxg/archive/2009/02/20/access-control-service-sample.aspx" mce_href="https://blogs.msdn.com/rxg/archive/2009/02/20/access-control-service-sample.aspx"><FONT color=#555555>post</FONT></A>, I wrote about a very simple Access Control Service example that I assembled during our investigation of ACS and the cloud in general.&nbsp; The sample uses the Application_AuthenticateRequest event in global.asax to validate the security using the Geneva framework.</P>
<P>In a follow up <A title="ACS Sample v2" href="https://blogs.msdn.com/rxg/archive/2009/02/24/access-control-services-sample-v2.aspx" mce_href="https://blogs.msdn.com/rxg/archive/2009/02/24/access-control-services-sample-v2.aspx">post</A>, I modified the example to require no code by using the Geneva provider and the standard ASP.NET authorize configuration.</P>
<P>In this example, I am going to show a couple of different ways to implement an Admin role using ASP.NET and the Geneva provider.</P>
<P>After you get the second sample running correctly, add the following to the end of the web.config file just before the configuration close tag.</P><FONT color=#0000ff size=2><FONT color=#0000ff size=2>
<P></FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>location</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> </FONT></FONT><FONT color=#ff0000 size=2><FONT color=#ff0000 size=2>path</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>=</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>admin</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp; &lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>system.web</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>authorization</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;<FONT color=#a31515 size=2><FONT color=#a31515 size=2>deny</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> </FONT></FONT><FONT color=#ff0000 size=2><FONT color=#ff0000 size=2>users</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> =</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>*</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> /&gt;<BR></FONT></FONT></FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;<FONT color=#a31515 size=2><FONT color=#a31515 size=2>allow</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&nbsp;</FONT></FONT><FONT color=#ff0000 size=2><FONT color=#ff0000 size=2>roles</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> =</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>Admin</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> /&gt;<BR></FONT></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>authorization</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp; &lt;/</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>system.web</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&lt;/</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>location</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR><BR></FONT></FONT></P>
<P>This config param overrides the main authorization config and&nbsp;restricts access to all files in the admin folder to users in the admin role.</P>
<P>To test this, create a new folder named Admin.&nbsp; Copy Page2.aspx and past into the admin folder.&nbsp; Rename Page2.aspx to default.aspx (in the Admin folder).</P>
<P>Now you need to add your user id to the admin role.&nbsp; There are a few different ways to do this.&nbsp; One way, which *should* work (in other words, I haven't tested it) is to create an ASP.NET role provider, create the Admin role,&nbsp;and add your Live ID to the Admin role.</P>
<P>Geneva also provides a way to achieve this.&nbsp; Paste the following code into global.asax.cs:</P><FONT color=#0000ff size=2><FONT color=#0000ff size=2>
<P>void</FONT></FONT><FONT size=2> WSFederationAuthenticationModule_SessionSecurityTokenCreated(</FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>Object</FONT></FONT><FONT size=2> sender, </FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>SessionSecurityTokenCreatedEventArgs</FONT></FONT><FONT size=2> e)</P>
<P>{</P>
<P></FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>IClaimsIdentity</FONT></FONT><FONT size=2> id = (</FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>IClaimsIdentity</FONT></FONT><FONT size=2>)e.SessionToken.ClaimsPrincipal.Identity;</P>
<P></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>if</FONT></FONT><FONT size=2> (id != </FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>null</FONT></FONT><FONT size=2> &amp;&amp; id.IsAuthenticated &amp;&amp; id.Name.EndsWith(</FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>"@microsoft.com"</FONT></FONT><FONT size=2>, </FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>StringComparison</FONT></FONT><FONT size=2>.OrdinalIgnoreCase))</P>
<P>{</P>
<P>id.Claims.Add(</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>new</FONT></FONT><FONT size=2> </FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>Claim</FONT></FONT><FONT size=2>(</FONT></P>
<P><FONT size=2>System.Web.Configuration.</FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>WebConfigurationManager</FONT></FONT><FONT size=2>.AppSettings[</FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>"RoleClaim"</FONT></FONT><FONT size=2>].ToString(), </FONT></P>
<P><FONT color=#a31515 size=2><FONT color=#a31515 size=2>"Admin"</FONT></FONT><FONT size=2>));</P>
<P>}</P>
<P>}</P></FONT>
<P>The <FONT size=2>SessionSecurityTokenCreated event is a new Geneva event that gets called when the token is first created.&nbsp; This code checks a condition - in this case, that the Live ID email is in the microsoft.com domain - and, adds the user to the Admin role if appropriate.&nbsp; Make sure to modify the if condition so that it returns the correct value.</FONT></P>
<P><FONT size=2>Geneva handles everything from there, including storing the claim in the cookie so that it gets passed from page to page.&nbsp; This allows the developer to simply use the IsInRole() method to determine if a user is in a particular role.&nbsp; ASP.NET uses this method under the covers to authorize access to pages based on the authorization configured in web.config.</FONT></P>
<P><FONT size=2>Once Active Directory domains get federated with Live ID (or if you use this code to call a different STS), you will get additional claims from the STS.&nbsp; In AD's case, you will get some Group membership claims.&nbsp; It is very simple within the event to map the Group claims to Role claims.&nbsp; This will allow the web developer to use the familiar IsInRole() method vs. having to check the claims.</FONT></P>
<P><FONT size=2><STRONG>Using ACS to manage roles</STRONG></FONT></P>
<P><FONT size=2>Another way to accomplish this is to use Access Control Service to provide role membership information.&nbsp; When you go to the ACS section on the&nbsp;Azure Services Platform <A title="Azure Services Platform Portal" href="https://portal.ex.azure.microsoft.com/" mce_href="https://portal.ex.azure.microsoft.com/">portal</A>, you need to click the Advanced button and the localhost Scope URI&nbsp;so that&nbsp;you can configure roles.</FONT></P>
<P>Once on the advanced scope management page, click the Claim Types "tab".&nbsp; You will notice several claim types defined, including UserName, Windows Live ID, Group, etc.</P>
<P>One option is to add users to an Admin group and then use code in the SessionSecurityTokenCreated event to add the user to the role that each group represents.</P>
<P>Another option is to add a Role claim type to ACS.&nbsp; To do this, click the Add Claim Types button.</P>
<P>On the Add Claim Types page, enter Role into the Display Name input box&nbsp;and enter <SPAN id=ctl00_ContentPlaceHolder_Main_gvClaimTypes_ctl10_lblClaimType>h<WBR>t<WBR>t<WBR>p<WBR>:<WBR>/<WBR>/<WBR>s<WBR>c<WBR>h<WBR>e<WBR>m<WBR>a<WBR>s<WBR>.<WBR>m<WBR>i<WBR>c<WBR>r<WBR>o<WBR>s<WBR>o<WBR>f<WBR>t<WBR>.<WBR>c<WBR>o<WBR>m<WBR>/<WBR>w<WBR>s<WBR>/<WBR>2<WBR>0<WBR>0<WBR>8<WBR>/<WBR>0<WBR>6<WBR>/<WBR>i<WBR>d<WBR>e<WBR>n<WBR>t<WBR>i<WBR>t<WBR>y<WBR>/<WBR>c<WBR>l<WBR>a<WBR>i<WBR>m<WBR>s<WBR>/<WBR>r<WBR>o<WBR>l<WBR>e</SPAN> into the Claim Type input box, then click Save.</P>
<P>You should now see a Role claim type displayed on the Claim Types page.</P>
<P>Next, click on the Rules tab, then click the Add Rule button.</P>
<P>In the Input Claims section, set the type dropdown to Windows Live ID, enter your Windows Live ID into the Value field, and set the Issuer to live.com.&nbsp; You can add as many Windows Live IDs as you wish, just make sure to set the input claims type combo box to Any.</P>
<P>In the Output Claims section, select Role from the Type dropdown, enter Admin into the Value field, and click Save.</P>
<P>Now run the sample, click on the Live ID Login button, login with a Live ID that you added to the Admin role, and you should see the Admin role displayed on the home page.&nbsp; You should also be able to access the pages in the Admin folder.</P>
<P mce_keep="true">All without any code!</P>
<P mce_keep="true">I didn't mention this in my earlier posts, but this code won't currently run on Azure.&nbsp; It also won't work on shared hosting at GoDaddy. It works great at GoGrid.</P>]]></content:encoded>
    </item>
    <item>
      <title>Access Control Services Sample v2</title>
      <link>https://docs.microsoft.com/archive/blogs/rxg/access-control-services-sample-v2</link>
      <pubDate>Tue, 24 Feb 2009 10:48:00 GMT</pubDate>
      <dc:creator><![CDATA[bartr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rxg/2009/02/24/access-control-services-sample-v2/</guid>
      <description><![CDATA[In a previous post, I wrote about a very simple Access Control Service example that I assembled...]]></description>
      <content:encoded><![CDATA[<P>In a previous <A class="" title="ACS Sample" href="https://blogs.msdn.com/rxg/archive/2009/02/20/access-control-service-sample.aspx" mce_href="https://blogs.msdn.com/rxg/archive/2009/02/20/access-control-service-sample.aspx">post</A>, I wrote about a very simple Access Control Service example that I assembled during our investigation of ACS and the cloud in general.&nbsp; The sample uses the Application_AuthenticateRequest event in global.asax to validate the security using the Geneva framework.</P>
<P>Geneva also&nbsp;enhances the standard ASP.NET authorization capabilities available via web.config.&nbsp; To use this example, follow the instructions for the previous post and, once it is running, do the following:</P>
<P>Use web.config to prevent anonymous access to the entire site.&nbsp; To do this, uncomment the authorization block at lines 60 - 62 so that it looks like this:</P><FONT color=#0000ff size=2><FONT color=#0000ff size=2>
<P>&lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>authorization</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>deny</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> </FONT></FONT><FONT color=#ff0000 size=2><FONT color=#ff0000 size=2>users</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>=</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>?</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>/&gt;<BR>&lt;/</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>authorization</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;</FONT></FONT></P>
<P>Also in web.config, just before the configuration close tag on the last line, insert the following configuration information:</P><FONT color=#0000ff size=2>
<P>&lt;</FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>location</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> </FONT></FONT><FONT color=#ff0000 size=2><FONT color=#ff0000 size=2>path</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>=</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>default.aspx</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp; &lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>system.web</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>authorization</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>allow</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> </FONT></FONT><FONT color=#ff0000 size=2><FONT color=#ff0000 size=2>users</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> =</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>*</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>authorization</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp; &lt;/</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>system.web</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&lt;/</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>location</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR><BR>&lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>location</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> </FONT></FONT><FONT color=#ff0000 size=2><FONT color=#ff0000 size=2>path</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>=</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>images</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp; &lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>system.web</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>authorization</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>allow</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> </FONT></FONT><FONT color=#ff0000 size=2><FONT color=#ff0000 size=2>users</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> =</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>*</FONT></FONT><FONT size=2>"</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2> /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>authorization</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&nbsp;&nbsp; &lt;/</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>system.web</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR>&lt;/</FONT></FONT><FONT color=#a31515 size=2><FONT color=#a31515 size=2>location</FONT></FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>&gt;<BR><BR></FONT></FONT></P>
<P>These config params override the main authorization config and&nbsp;allow anonymous access to default.aspx and everything in the images folder.</P>
<P>Lastly, comment all of the code in global.asax.cs.</P>
<P>Press F5 and the default page will display.&nbsp; When you click on the Page 2 link, you will be redirected to the Live login page.</P>
<P>Unfortunately, there is a bug in the CTP and you will get a 400 error.&nbsp; Simply add the line below to the end of the url in the address bar and press enter, and you will be correctly redirected to the login page.</P>
<P><FONT color=red size=2>&amp;whr=https://login.live.com</FONT></P>
<P>In a future post, I will explain a few different ways to&nbsp;integrate role support to the web application via ACS.</P>
<P mce_keep="true">&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Access Control Service Sample</title>
      <link>https://docs.microsoft.com/archive/blogs/rxg/access-control-service-sample</link>
      <pubDate>Fri, 20 Feb 2009 23:35:00 GMT</pubDate>
      <dc:creator><![CDATA[bartr]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/rxg/2009/02/20/access-control-service-sample/</guid>
      <description><![CDATA[Microsoft .NET Services are part of the Azure Services Platform.&nbsp; The Microsoft .NET Access...]]></description>
      <content:encoded><![CDATA[<P><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt"><A href="https://www.microsoft.com/azure/netservices.mspx">Microsoft .NET Services</A> are part of the <A title=Azure href="https://www.microsoft.com/azure" mce_href="https://www.microsoft.com/azure">Azure Services Platform</A>.&nbsp; The Microsoft .NET <A href="https://www.microsoft.com/azure/accesscontrol.mspx" mce_href="https://www.microsoft.com/azure/accesscontrol.mspx">Access Control Service</A> provides an easy way to control web applications and services while integrating with standards-based identity providers, including enterprise directories and web identity systems such as Windows Live ID.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt">ACS is currently available as a CTP.&nbsp; The CTP provides federation with Live IDs and is the easiest way I've found to integrate Live ID into a web site.&nbsp; Even though there are some CTP maturity issues, you can still do quite a lot with the CTP and we are very excited about the direction ACS is headed.&nbsp; While investigating&nbsp;ACS for RXG, I put together&nbsp;a simple example that shows how to integrate ACS into a web app.&nbsp; The Visual Studio 2008 sample code is available below.&nbsp; Many thanks to&nbsp;<A href="https://blogs.msdn.com/justinjsmith/" mce_href="https://blogs.msdn.com/justinjsmith/">Justin</A> for providing most of the code and answering my questions.<o:p></o:p></SPAN></P>
<P><STRONG><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt">Before you download the code ...</SPAN></STRONG><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt"><o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt">There are a couple of things you need to do in order to get the sample to work.&nbsp; The first is to&nbsp;<A href="https://www.microsoft.com/azure/register.mspx" mce_href="https://www.microsoft.com/azure/register.mspx">register</A> for&nbsp;the .NET Services CTP, install the SDKs, and setup a .NET Services solution.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></SPAN><SPAN style="mso-no-proof: yes"><FONT size=3 face=Calibri>You will also need to install the </FONT><A href="https://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=1e3c3efc-e980-4895-9095-86e51c1cd9d8"><FONT size=3 face=Calibri>Geneva</FONT></A><FONT size=3><FONT face=Calibri> beta.<o:p></o:p></FONT></FONT></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt">Next, go to the <A href="https://portal.ex.azure.microsoft.com/" mce_href="https://portal.ex.azure.microsoft.com/">portal</A> and setup ACS by signing in then clicking on Getting Started then "Access Control Service" on the getting started page.<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt">Once on the ACS page, click the Basic button.<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt">On the Basic View page, click the Next button<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt">On the Wizard page, enter https://localhost into the Application URL field, leave the certificate field blank, and click next.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>In a production app, you would want to supply a certificate for security reasons.<o:p></o:p></SPAN></P>
<P><SPAN style="FONT-FAMILY: 'Arial','sans-serif'; FONT-SIZE: 10pt">On the Access Control Rules page, change the type of the claim to Windows Live ID.&nbsp; Enter an * in the value field and change the issuer to live.com.&nbsp; Change the output claim type to e-mail, check the copy input value box, and click save.<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3 face=Calibri>You should end up on the Rules page with a single rule that looks like this:</FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3 face=Calibri>&nbsp;</FONT><SPAN style="mso-no-proof: yes"><FONT size=3><FONT face=Calibri><o:p><IMG title="ACS Rules Screenshot" alt="ACS Rules Screenshot" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/55/19/83/ACS-Rules.png" original-url="https://blogs.msdn.com/photos/rxg/images/9551983/original.aspx" mce_src="https://blogs.msdn.com/photos/rxg/images/9551983/original.aspx"></o:p></FONT></FONT></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><SPAN style="mso-no-proof: yes"><FONT size=3><FONT face=Calibri>Download the sample code from <A title="ACS Sample Code" href="https://blogs.msdn.com/rxg/attachment/9436956.ashx" mce_href="https://blogs.msdn.com/rxg/attachment/9436956.ashx">here</A>, unzip, and open the solution.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Make sure to stop IIS if it’s running as the sample requires port 80 on localhost.<o:p></o:p></FONT></FONT></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><SPAN style="mso-no-proof: yes"><FONT size=3><FONT face=Calibri>Open web.config and change the [[solution]] value in the Issuer url to the correct solution name (it’s displayed on the ACS portal pages).</FONT></FONT></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><SPAN style="mso-no-proof: yes"><FONT size=3><FONT face=Calibri><o:p></o:p></FONT></FONT></SPAN>&nbsp;<SPAN style="mso-no-proof: yes"><FONT size=3><FONT face=Calibri>Open global.asax.cs and set a breakpoint in the Application_AuthenticateRequest event.<o:p></o:p></FONT></FONT></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><SPAN style="mso-no-proof: yes"><FONT size=3><FONT face=Calibri>Press F5 and you will hit the breakpoint.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Press F5 again time and the default page will load.<o:p></o:p></FONT></FONT></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><SPAN style="mso-no-proof: yes"><FONT size=3><FONT face=Calibri>Click on the Page 2 link and you will be redirected to the live.com login page.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>After logging in with a valid Live ID, you should see your authentication information on the default page.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Click on the Page 2 link again and you should be taken to Page2.aspx.<o:p></o:p></FONT></FONT></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><FONT size=3><FONT face=Calibri><B style="mso-bidi-font-weight: normal"><SPAN style="mso-no-proof: yes">What just happened?</SPAN></B><SPAN style="mso-no-proof: yes"><o:p></o:p></SPAN></FONT></FONT></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><SPAN style="mso-no-proof: yes"><FONT size=3><FONT face=Calibri>The Application_AuthenticateRequest event redirects to live.com to get the token which is automatically handled by the Geneva provider.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The rediretion code in the AuthenticateRequest event is exactly the same as the code in the btnFederate_Click event.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>The code is very simple as it just gets a reference to the WSFederationAuthenticationModule in ApplicationInstance.Modules, creates a SignInRequestMessage, then redirects.<o:p></o:p></FONT></FONT></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><SPAN style="mso-no-proof: yes"><FONT size=3><FONT face=Calibri>Geneva is configured with the &lt;microsoft.identityModel&gt; section in web.config.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>As mentioned above, make sure to modify the issuer value to point to your solution.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Also note that authentication mode is set to None.&nbsp; Most of the Geneva magic happens because of the web.config values.&nbsp; I still don't fully understand all of the options, but the basics make sense once you play around with it a little.</FONT></FONT></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><B style="mso-bidi-font-weight: normal"><SPAN style="mso-no-proof: yes"><FONT size=3><FONT face=Calibri>Keep it simple<o:p></o:p></FONT></FONT></SPAN></B></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><SPAN style="mso-no-proof: yes"><FONT size=3><FONT face=Calibri>I tried to keep this as simple as possible as I found it difficult to get everything setup correctly the first time.</FONT></FONT></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><o:p><FONT size=3 face=Calibri>&nbsp;</FONT></o:p></P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/43/69/56/ACSSample.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-43-69-56/ACSSample.zip">ACSSample.zip</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>