<?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>BillGr's Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/billgr/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/billgr/feed.xml</link>
    <description>My blog about (mostly) SharePoint stuff.</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:39:48 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Sandboxed Web Service</title>
      <link>https://docs.microsoft.com/archive/blogs/billgr/sandboxed-web-service</link>
      <pubDate>Mon, 31 Jan 2011 15:07:34 GMT</pubDate>
      <dc:creator><![CDATA[Bill Griffin - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/billgr/2011/01/31/sandboxed-web-service/</guid>
      <description><![CDATA[SharePoint Extensibility  SharePoint has always had a variety of server-side extensibility points....]]></description>
      <content:encoded><![CDATA[<h1>SharePoint Extensibility</h1>  <p>SharePoint has always had a variety of server-side extensibility points. When a developer is creating a custom application or service there are many extensibility points that can be leveraged: event handlers, web parts, web pages, web services, workflow activities, InfoPath forms, and more. In previous versions of SharePoint, only a farm administrator had permissions to deploy new server-side functionality to the servers.</p>  <p>Beginning with the SharePoint 2010 release, we started allowing site administrators to deploy certain types of customizations and applications without requiring the involvement of a farm administrator. To protect all of the server-side resources from malicious code, inefficient code, and naive overconsumption of resources, we execute these types of solutions in the new Sandboxed Code Service. The sandbox provides a constrained, monitored, scalable runtime environment where code can be executed. Farm administrators get to choose what server(s) in the farm they want the Sandbox Code Service to run on. Site administrators get to choose what solution(s) they want to allow in their site collections.</p>  <p>Whenever code is executing within the sandbox, it is limited in the scope of what it can do. For example, the code will not have network access or direct SQL access. This is so that we can protect the rest of the servers in SharePoint farm as well as other non-SharePoint servers that may be on the same network. You can, of course, access and manipulate data stored within SharePoint from within the sandbox. In addition to that, we do allow code in the sandbox to access external data but it must do so using the Business Data Connectivity object model. This is so that farm administrators can still have control over what non-SharePoint enterprise data the sandboxed code can have access to.</p>  <p>In the 2010 release, many SharePoint extensibility points were upgraded to enable sandboxed execution: web parts, event handlers, workflow actions, and InfoPath forms. But there are still some extensibility points that a non-sandboxed solution can deploy to the server for which there is not yet a sandboxed equivalent: ASMX web services, ASPX page-level code-behind, ASP.Net request handlers, and more.</p>  <p>I could go on for some time talking about the sandbox (I was one of the primary architects) but that’s not my intention with this post. There are already many other articles out there that go into lots of detail describing the sandbox runtime environment and how to create solutions designed for sandboxed execution. <a href="https://msdn.microsoft.com/en-us/library/ff798382.aspx">This one</a> is a good starting point.</p>  <p>With this post, what I wanted to do was to demonstrate how you can, with some constraints, achieve sandboxed execution of a web service.</p>  <h1>Web Service</h1>  <p>When someone says “web service” what comes to mind? For many people, it’s a SOAP-based web service and an ASMX-based implementation that come to mind.</p>  <p>But that’s not what I think of when I think of a web service. To me, a web service is simply a service that does something remotely over the web. It is an http-based endpoint where I can send a request, have it do something, and get an answer back. There are so many options: the service could be SOAP-based; it could be REST-based; it could be a service that doesn’t conform to any industry standards; the data that is returned from the service could be XML, JSON, HTML, plain text; it could be encoded as ANSI, UTF-8, UCS-2; or it could be binary data like an image.</p>  <p>So, while it is certainly true that SharePoint 2010 does not support sandboxed execution of ASMX-based web services, that doesn’t mean that you can’t create sandboxed web services.</p>  <h1>Web Parts</h1>  <p>The approach that I’m taking here for a sandboxed web service is to leverage a sandboxed web part.</p>  <p>A web part is typically used to generate a fragment of a web page: a summary of recent changes in a document library, a sales forecast chart, some stock quotes, etc. With a web browser, users can add web parts to pages and drag them around within a variety of page layouts.</p>  <p>When a user is adding or editing a web part, there is generally no distinction made between full-trust and sandboxed web parts. There is a single web part selection and editing experience that hides the differences from the user. There are a few scenarios where there the differences are visible but these are not common so must users never know about the difference.</p>  <p>But when it comes to the underlying ASPX markup, they are actually quite different.</p>  <h1>Sandboxed Web Part</h1>  <p>In this example, you can see the markup where a full-trust web part is directly inserted into the page markup without using a web part zone.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:fba7e15f-3710-4734-bd82-bb22389d2dab" class="wlWriterEditableSmartContent"> <div class="pavsc-container"> <div class="pavsc-titleblock">Full-Trust Web Part Markup</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">&lt;</span><span style="color:#800000">div</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even">    <span style="color:#0000ff">&lt;</span><span style="color:#800000">Samples</span><span style="color:#0000ff">:</span><span style="color:#800000">HelloWorldWebPart</span> <span style="color:#ff0000">runat</span><span style="color:#0000ff">=&quot;server&quot;</span> <span style="color:#ff0000">id</span><span style="color:#0000ff">=&quot;TestControl&quot;</span> <span style="color:#0000ff">/&gt;</span></li> <li><span style="color:#0000ff">&lt;/</span><span style="color:#800000">div</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>  <p>A sandboxed web part can also be inserted into page markup, but the markup looks quite a bit different. The control that you are inserting through the page markup is actually an instance of the full-trust web part <strong>SPUserCodeWebPart</strong> and not the sandboxed web part itself. The <strong>SPUserCodeWebPart</strong> is as a wrapper for the sandboxed web part. As with any other page control, you configure the wrapper web part using properties. These properties allow you to specify which sandboxed web part should actually be rendered.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1e5e5ebc-2c06-40c6-aff6-008f550ce435" class="wlWriterEditableSmartContent"> <div class="pavsc-container"> <div class="pavsc-titleblock">Sandboxed Web Part Markup</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">&lt;</span><span style="color:#800000">WebPartPages</span><span style="color:#0000ff">:</span><span style="color:#800000">SPUserCodeWebPart</span> <span style="color:#ff0000">runat</span><span style="color:#0000ff">=&quot;server&quot;</span></li> <li class="pavsc-even">    <span style="color:#ff0000">SolutionId</span><span style="color:#0000ff">=&quot;78192f4e-fe57-4289-8cc0-f43f1c81b23b&quot;</span></li> <li>    <span style="color:#ff0000">AssemblyFullName</span><span style="color:#0000ff">=&quot;BillGr.Samples.SandboxedWebRequest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d8450410d7e9e6dc&quot;</span></li> <li class="pavsc-even">    <span style="color:#ff0000">TypeFullName</span><span style="color:#0000ff">=&quot;BillGr.Samples.SandboxedWebRequest.WebControls.SandboxedWebRequestWebPart&quot;</span></li> <li>    <span style="color:#ff0000">WebPart</span><span style="color:#0000ff">=&quot;true&quot;</span></li> <li class="pavsc-even">    <span style="color:#ff0000">FrameType</span><span style="color:#0000ff">=&quot;None&quot;</span></li> <li>    <span style="color:#ff0000">SuppressWebPartChrome</span><span style="color:#0000ff">=&quot;True&quot;</span></li> <li class="pavsc-even">    <span style="color:#ff0000">id</span><span style="color:#0000ff">=&quot;g_fdc562ed_ec2f_41db_bfd3_a8d5fd283619&quot;</span> <span style="color:#0000ff">/&gt;</span></li> </ol> </div> </div> </div>  <p>When the ASPX page is rendered, the <strong>SPUserCodeWebPart</strong> will activate an instance of the sandboxed web part over in the sandbox service and then ask the sandboxed web part to render its HTML output. When the wrapper web part receives the output back from the sandboxed web part, it inserts that output into the standard page response stream without any modification.</p>  <p>So, from what I’ve described so far, you should be able to see that if we were to create an ASPX page with a sandboxed web part then we would be able to send web requests to this page and get the sandboxed web part to do something on our behalf. Isn’t that the essence of a web service?</p>  <h1>Removing Extraneous Output</h1>  <p>Now, the web part is a control in an ASPX page. The output of the web part will coexist with:</p>  <ul>   <li>The static markup that is in the ASPX page</li>    <li>Output from other controls that are in the page</li>    <li>Static markup that is in the master page</li>    <li>Output from controls that are in the master page.</li> </ul>  <p>If I’m using this web page as a web service then how is my client supposed to know what part of the response is from the web part and what is from the various other things in the page?</p>  <p>You could have your web part output some unique tokens at the beginning and end of its output. The client could then search for these book-end tokens, extract the output in the middle, and then use it. But that is really cumbersome. You really want is to be able to call this sandboxed web service using the <strong>XMLHttpRequest</strong> object from some javascript and easily process the results.</p>  <p>So, what if we take our sandboxed web part and put it into an ASPX page that doesn’t have anything else in it. Instead of using a “normal” SharePoint ASPX page, let’s use a custom ASPX page that has no other controls, no web part zones, and does not use a master page. What would the server return back to the caller? Well, if we were careful with the whitespace in the ASPX page, we can setup the page so that every single character in the response would be output from the sandboxed web part itself.</p>  <p>Any whitespace that is between directive tags will not be included in the response. So these can each be on their own lines. However, any text or whitespace that exists after the last directive will be included. So if you do not want your web service response to start out with a newline then you’ll need to start the markup for your sandboxed web part on the same line and immediately after the final <font style="background-color: #ffff00">%&gt;</font>. You will also need to watch out that you do not add any extra text or whitespace after the web part definition because that will also be included in every response immediately following the output of your web part.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ba978fee-07d4-4a68-9dc8-15ead5bee685" class="wlWriterEditableSmartContent"> <div class="pavsc-container"> <div class="pavsc-titleblock">Sandboxed Web Service Markup</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffff00">&lt;%</span><span style="color:#0000ff">@</span> <span style="color:#800000">Page</span> <span style="color:#ff0000">Inherits</span><span style="color:#0000ff">=&quot;Microsoft.SharePoint.WebPartPages.WebPartPage&quot;</span> <span style="background:#ffff00">%&gt;</span></li> <li class="pavsc-even"><span style="background:#ffff00">&lt;%</span><span style="color:#0000ff">@</span> <span style="color:#800000">Register</span> <span style="color:#ff0000">Tagprefix</span><span style="color:#0000ff">=&quot;WebPartPages&quot;</span> </li> <li>    <span style="color:#ff0000">Assembly</span><span style="color:#0000ff">=&quot;Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c&quot;</span></li> <li class="pavsc-even">    <span style="color:#ff0000">Namespace</span><span style="color:#0000ff">=&quot;Microsoft.SharePoint.WebPartPages&quot;</span> <span style="background:#ffff00">%&gt;</span><span style="color:#0000ff">&lt;</span><span style="color:#800000">WebPartPages</span><span style="color:#0000ff">:</span><span style="color:#800000">SPUserCodeWebPart</span> <span style="color:#ff0000">runat</span><span style="color:#0000ff">=&quot;server&quot;</span></li> <li>    <span style="color:#ff0000">SolutionId</span><span style="color:#0000ff">=&quot;78192f4e-fe57-4289-8cc0-f43f1c81b23b&quot;</span></li> <li class="pavsc-even">    <span style="color:#ff0000">AssemblyFullName</span><span style="color:#0000ff">=&quot;BillGr.Samples.SandboxedWebRequest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d8450410d7e9e6dc&quot;</span></li> <li>    <span style="color:#ff0000">TypeFullName</span><span style="color:#0000ff">=&quot;BillGr.Samples.SandboxedWebRequest.WebControls.SandboxedWebRequestWebPart&quot;</span></li> <li class="pavsc-even">    <span style="color:#ff0000">WebPart</span><span style="color:#0000ff">=&quot;true&quot;</span></li> <li>    <span style="color:#ff0000">FrameType</span><span style="color:#0000ff">=&quot;None&quot;</span></li> <li class="pavsc-even">    <span style="color:#ff0000">SuppressWebPartChrome</span><span style="color:#0000ff">=&quot;True&quot;</span></li> <li>    <span style="color:#ff0000">id</span><span style="color:#0000ff">=&quot;g_fdc562ed_ec2f_41db_bfd3_a8d5fd283619&quot;</span> <span style="color:#0000ff">/&gt;</span></li> </ol> </div> </div> </div>  <h1>Simple Example</h1>  <p>Let’s look at a simple web part that returns plain text:</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:20f490a2-53bf-4808-891d-61922b77fe88" class="wlWriterEditableSmartContent"> <div class="pavsc-container"> <div class="pavsc-titleblock">Hello World Web Part</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">using</span> System;</li> <li class="pavsc-even"><span style="color:#0000ff">using</span> System.Collections.Generic;</li> <li><span style="color:#0000ff">using</span> System.Linq;</li> <li class="pavsc-even"><span style="color:#0000ff">using</span> System.Web;</li> <li><span style="color:#0000ff">using</span> System.Web.UI.WebControls.WebParts;</li> <li class="pavsc-even">&nbsp;</li> <li><span style="color:#0000ff">namespace</span> BillGr.Samples</li> <li class="pavsc-even">{</li> <li>&nbsp;</li> <li class="pavsc-even">    <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span></li> <li>    <span style="color:#808080">///</span><span style="color:#008000"> Sample web part that says &quot;Hello world.&quot;</span></li> <li class="pavsc-even">    <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span></li> <li>    <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">HelloWorldWebPart</span> : <span style="color:#2b91af">WebPart</span></li> <li class="pavsc-even">    {</li> <li>        <span style="color:#0000ff">protected</span> <span style="color:#0000ff">override</span> <span style="color:#0000ff">void</span> Render(System.Web.UI.<span style="color:#2b91af">HtmlTextWriter</span> writer)</li> <li class="pavsc-even">        {</li> <li>            writer.Write(<span style="color:#a31515">&quot;Hello world.&quot;</span>);</li> <li class="pavsc-even">        }</li> <li>    }</li> <li class="pavsc-even">&nbsp;</li> <li>}</li> </ol> </div> </div> </div>  <p>Now, why am I overriding the <strong>Render</strong> method? Aren’t all web parts supposed to override the <strong>RenderContents</strong> method? Well, think about what these two methods do. In a “normal” web part, the base class handles the <strong>Render</strong> method and its job is to spit out the chrome of the web part (title, frame, etc.) that goes around the body of the web part. After the <strong>Render</strong> method has generated the opening tags of the chrome, it will then call the <strong>RenderContents</strong> method in the child class to render the body of the web part. Once <strong>RenderContents</strong> is done, execution will return back to <strong>Render</strong> which will then generate the chrome’s closing tags. By overriding <strong>Render</strong>, we can ensure that no web part chrome is rendered and the only output that is generated comes from our child class.</p>  <p>Next, we will insert this plain text web part into an “empty” ASPX page as described above. This results in a page with no chrome and a web part with no chrome. If you navigate to the web page using a browser, you will get a simple plain text response. If you were to “view source”, you would see that every character in the response came from the web part’s Render method.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/40/60/metablogapi/2538.HelloWorldWebService-Response_0C50D76A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-40-60-metablogapi/2538.HelloWorldWebService_2D00_Response_5F00_0C50D76A.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="HelloWorldWebService-Response" border="0" alt="HelloWorldWebService-Response" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/40/60/metablogapi/4111.HelloWorldWebService-Response_thumb_0EAA5968.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-40-60-metablogapi/4111.HelloWorldWebService_2D00_Response_5F00_thumb_5F00_0EAA5968.png" width="504" height="398" /></a></p>  <p>Now, you should be able to use this new ASPX page as a web service from some other ASPX page:</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:dabde66e-2d2f-48a6-8fa1-e7615eaaf7e7" class="wlWriterEditableSmartContent"> <div class="pavsc-container"> <div class="pavsc-titleblock">Hello World Client</div> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">&lt;!</span><span style="color:#800000">DOCTYPE</span> <span style="color:#ff0000">html</span> <span style="color:#ff0000">PUBLIC</span> <span style="color:#0000ff">&quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span> <span style="color:#0000ff">&quot;https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span></li> <li class="pavsc-even"><span style="color:#0000ff">&lt;</span><span style="color:#800000">html</span> <span style="color:#ff0000">xmlns</span><span style="color:#0000ff">=&quot;https://www.w3.org/1999/xhtml&quot;&gt;</span></li> <li><span style="color:#0000ff">&lt;</span><span style="color:#800000">head</span> <span style="color:#ff0000">runat</span><span style="color:#0000ff">=&quot;server&quot;&gt;</span></li> <li class="pavsc-even">    <span style="color:#0000ff">&lt;</span><span style="color:#800000">title</span><span style="color:#0000ff">&gt;</span>Hello World Client<span style="color:#0000ff">&lt;/</span><span style="color:#800000">title</span><span style="color:#0000ff">&gt;</span></li> <li>    <span style="color:#0000ff">&lt;</span><span style="color:#800000">script</span> <span style="color:#ff0000">type</span><span style="color:#0000ff">=&quot;text/javascript&quot;&gt;</span></li> <li class="pavsc-even">    </li> <li>    <span style="color:#0000ff">function</span> callButton_OnClick()</li> <li class="pavsc-even">    {</li> <li>        <span style="color:#0000ff">var</span> request = getXMLHttpRequest();</li> <li class="pavsc-even">        request.open(<span style="color:#800000">&quot;GET&quot;</span>, <span style="color:#800000">&quot;HelloWorldWebService.aspx&quot;</span>, <span style="color:#0000ff">true</span>);</li> <li>        request.onreadystatechange = <span style="color:#0000ff">function</span> ()</li> <li class="pavsc-even">        {</li> <li>            <span style="color:#0000ff">if</span> (request.readyState == 4)</li> <li class="pavsc-even">            {</li> <li>                <span style="color:#0000ff">var</span> outputPanel = document.getElementById(<span style="color:#800000">&quot;outputPanel&quot;</span>);</li> <li class="pavsc-even">                outputPanel.innerHTML += <span style="color:#800000">&quot;Response received: &quot;</span> + request.responseText + <span style="color:#800000">&quot;&lt;br /&gt;&quot;</span>;</li> <li>            }</li> <li class="pavsc-even">        };</li> <li>        request.send();</li> <li class="pavsc-even">    }</li> <li>&nbsp;</li> <li class="pavsc-even">    <span style="color:#0000ff">&lt;/</span><span style="color:#800000">script</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">&lt;/</span><span style="color:#800000">head</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even"><span style="color:#0000ff">&lt;</span><span style="color:#800000">body</span><span style="color:#0000ff">&gt;</span></li> <li>    <span style="color:#0000ff">&lt;</span><span style="color:#800000">form</span> <span style="color:#ff0000">id</span><span style="color:#0000ff">=&quot;form1&quot;</span> <span style="color:#ff0000">runat</span><span style="color:#0000ff">=&quot;server&quot;&gt;</span></li> <li class="pavsc-even">    <span style="color:#0000ff">&lt;</span><span style="color:#800000">div</span><span style="color:#0000ff">&gt;</span></li> <li>        Click the button to call the web service:<span style="color:#0000ff">&lt;</span><span style="color:#800000">br</span> <span style="color:#0000ff">/&gt;</span></li> <li class="pavsc-even">        <span style="color:#0000ff">&lt;</span><span style="color:#800000">input</span> <span style="color:#ff0000">type</span><span style="color:#0000ff">=&quot;button&quot;</span> <span style="color:#ff0000">id</span><span style="color:#0000ff">=&quot;callButton&quot;</span> <span style="color:#ff0000">value</span><span style="color:#0000ff">=&quot;Call&quot;</span> <span style="color:#ff0000">onclick</span><span style="color:#0000ff">=&quot;callButton_OnClick()&quot;</span> <span style="color:#0000ff">/&gt;</span></li> <li>    <span style="color:#0000ff">&lt;/</span><span style="color:#800000">div</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even">    <span style="color:#0000ff">&lt;</span><span style="color:#800000">div</span> <span style="color:#ff0000">id</span><span style="color:#0000ff">=&quot;outputPanel&quot;</span> <span style="color:#0000ff">/&gt;</span></li> <li>    <span style="color:#0000ff">&lt;/</span><span style="color:#800000">form</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even"><span style="color:#0000ff">&lt;/</span><span style="color:#800000">body</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">&lt;/</span><span style="color:#800000">html</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>  <p>Clicking on the “Call” button a few times and, you’ll see.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/40/60/metablogapi/0878.HelloWorldWebClient-After_42724FB9.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-40-60-metablogapi/0878.HelloWorldWebClient_2D00_After_5F00_42724FB9.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="HelloWorldWebClient-After" border="0" alt="HelloWorldWebClient-After" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/40/60/metablogapi/7737.HelloWorldWebClient-After_thumb_13406422.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-40-60-metablogapi/7737.HelloWorldWebClient_2D00_After_5F00_thumb_5F00_13406422.png" width="504" height="379" /></a></p>  <h1>Response Format</h1>  <p>As I mentioned above, the full-trust wrapper web part simply takes the output string from the sandboxed web part and returns it to the client. This means that your web part can return data as XML, JSON, CSV, or any other text format that it wants.</p>  <p>However, you do not have complete control over the response. The web front end that is running the ASPX page is who owns the actual response stream that goes back to the client – not the sandboxed web part. The page also owns the content-type and encoding format of the response. This means that your sandboxed web part cannot alter these parameters of the response. Your web part will have to live with a text-only response stream. You can set the encoding format in the @Page directive (the default in SharePoint is UTF-8) but you can’t set the content type. The scenario where you want to return binary files (ex: images) remains a full-trust scenario only:</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7f3927bd-b261-47e8-9555-ed860a5d3335" class="wlWriterEditableSmartContent"> <div class="pavsc-container"> <div class="pavsc-titleblock">Full Trust Binary Response</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">protected</span> <span style="color:#0000ff">override</span> <span style="color:#0000ff">void</span> OnLoad(<span style="color:#2b91af">EventArgs</span> e)</li> <li class="pavsc-even">{</li> <li>    <span style="color:#0000ff">string</span> imageName = <span style="color:#0000ff">this</span>.Page.Request.QueryString[<span style="color:#a31515">&quot;Name&quot;</span>];</li> <li class="pavsc-even">    <span style="color:#0000ff">if</span> (!<span style="color:#0000ff">string</span>.IsNullOrEmpty(imageName))</li> <li>    {</li> <li class="pavsc-even">        <span style="color:#0000ff">string</span> contentType = <span style="color:#0000ff">null</span>;</li> <li>        <span style="color:#0000ff">byte</span>[] fileContents = <span style="color:#0000ff">this</span>.GetImageContents(imageName, <span style="color:#0000ff">out</span> contentType);</li> <li class="pavsc-even">&nbsp;</li> <li>        <span style="color:#2b91af">HttpResponse</span> response = <span style="color:#0000ff">this</span>.Page.Response;</li> <li class="pavsc-even">        response.ContentType = contentType;</li> <li>        response.BinaryWrite(fileContents);</li> <li class="pavsc-even">        response.Flush();</li> <li>        response.End();</li> <li class="pavsc-even">    }</li> <li>}</li> </ol> </div> </div> </div>  <h1>Sample Solution</h1>  <p>In this sample solution, I’ve included the following:</p>  <p><strong>Sandboxed web part</strong> – This web part returns SharePoint list items in JSON format. You can use the source code below and modify it to return XML or any other format that you want. The query string of the web part’s host page is used to send parameters to the web part. There are two input parameters: <strong>ListName</strong> is the name of the SharePoint list and <strong>ViewName</strong> is, optionally, the name of a view from that SharePoint list. The list that you specify must be in the same site as the ASPX page that is hosting the web part. <strong><em>Please Note: To discourage the use of this sample in production, the web part is limited to returning output for only the first ten items in the result set. Please get the source below and modify it for your specific scenario.</em></strong></p>  <p><strong>Host ASPX page</strong> – This is an “empty” ASPX page that hosts the sandboxed web part and acts as the endpoint of the web service. This page will be created at <em>&lt;YourSiteCollectionUrl&gt;</em>/AppPages/SandboxedWebService.aspx.</p>  <p><strong>Sample “client app” page</strong> – This is an ASPX page that acts as a sample “client app.” It prompts you for the list/view names and then navigates to the web service allowing the browser to display the response. If you were building this solution for production use you would probably want to leave this page out of your solution. This page will be created at <em>&lt;YourSiteCollectionUrl&gt;</em>/TestClient/TestSandboxedWebService.aspx. Sample results are shown below:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/40/60/metablogapi/3527.SandboxedWebService-Response_6B2DB502.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-40-60-metablogapi/3527.SandboxedWebService_2D00_Response_5F00_6B2DB502.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="SandboxedWebService-Response" border="0" alt="SandboxedWebService-Response" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/40/60/metablogapi/5353.SandboxedWebService-Response_thumb_25A8B4D7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-40-60-metablogapi/5353.SandboxedWebService_2D00_Response_5F00_thumb_5F00_25A8B4D7.png" width="504" height="408" /></a></p>  <h1>Steps To Create Your Own Solution</h1>  <p>For a solution like this, you should not start with the Visual Studio “Visual Web Part” solution template because it will take you down the ASCX path. Instead of an ASCX you want a code-based web part – but there isn’t a template for that. Instead, start out by creating a solution using the “Empty SharePoint Project” template. Set the trust level for this solution to be a sandboxed solution. In the empty solution, you should use “Add / New Item” and choose “Web Part” using whichever language you want to use. This will add a code-based web part to the solution.</p>  <p>By default, a .webpart file will also be added to your solution for this new web part. When developing a “normal” web part, this is likely a file that you want. It is needed for your web part to appear in the web part selection UI when a user chooses to add a web part to a page. However, there is only one page where we want this web part to be used and that is in the host ASPX page. We do not want users adding this web part to any other pages in the site . To prevent this, delete the .webpart file from the solution. The .webpart file does not need to be included in the solution in order for the web part to be used in a page. When you delete the .web part file in the Visual Studio solution, the corresponding changes to the feature/element manifests will be done for you automatically.</p>  <p>Next, you need to use “Add / New Item” and choose Module so that you can add the ASPX page that will host the sandboxed web part. A module lets you add any type of file to the SharePoint site. It comes with a default file named Sample.txt which you can rename to SandboxedWebRequest.aspx or whatever you desire. If you examine the Elements.xml file for this module, you will notice that, by default, the files for this module are automatically placed into a top-level folder of the site that has the same name as the module. This is advisable to keep the files from your solution separated from files in another solution. If common file names are used in the same directory by two different solutions then that will be a problem. One of the two solutions would be broken. Keeping things in solution-specific directories is advised.</p>  <p>Lastly, you’ll need to alter the markup in the ASPX page so that you have the minimalist markup described above. Note that in the markup for the SPUserCodeWebPart, the property AssemblyFullName contains the public key token of the assembly. If you sign your solution with a different key than I used (which I strongly suggest you do) and you cut-n-paste markup from my sample, then you will need to alter the public key token value to match whatever key you are using.</p>  <p>One other point, if you ever change the namespace or the class name of your web part, you will need to edit one of the files that drives the Visual Studio SharePoint build process. Unfortunately, there is no built-in UI for editing this file nor will you find the file in the Solution Explorer pane. You will need to either go to the file system or to the source browser (if you’ve got source control enabled). Look for the file SharePointProjectItem.spdata in the same directory as your web part source file and fix the SafeControl entry for your web part to have the right namespace and class name. Fortunately, this file leverages the build-time macro “$SharePoint.Project.AssemblyFullName$” to dynamically insert the strong name of the assembly. It will automatically get the public key token from your assembly so you do not have to futz with that part of this file if you change your key file.</p>  <h1>Downloading The Sample</h1>  <p>There are two downloads available from the <a href="https://code.msdn.microsoft.com/BillGrSandboxWebSvc/Release/ProjectReleases.aspx?ReleaseId=5417">MSDN Code Gallery for this sample</a>:</p>  <p><strong>SharePoint Solution</strong> – This is a working .WSP that you can upload to the Solution Gallery for your site collection and activate it. Once you do this, the sandboxed web part, the web service ASPX page, and the test client ASPX page will be added to the root site of your site collection. Again, to discourage the use of this sample in production, the web part is limited to returning output for only the first ten items in the result set. Please get the source below and modify it for your specific scenario.</p>  <p><strong>Visual Studio Project</strong> – This is a .ZIP file containing the VS 2010 SharePoint solution that was used to generate the WSP above. </p>  <p>As with any of my other samples, you are free to use the solution in your site or take the source code and leverage it in some other solution that you are working on. Just keep in mind that this is a sample and, as such, has no warranty, no guarantee that it will work in all environments, and no promise that a future version of SharePoint won't break it.</p>]]></content:encoded>
    </item>
    <item>
      <title>Enabling File Names In Lookup Fields</title>
      <link>https://docs.microsoft.com/archive/blogs/billgr/enabling-file-names-in-lookup-fields</link>
      <pubDate>Fri, 15 Oct 2010 09:16:00 GMT</pubDate>
      <dc:creator><![CDATA[Bill Griffin - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/billgr/2010/10/15/enabling-file-names-in-lookup-fields/</guid>
      <description><![CDATA[For my first post, I figured that I would leverage a prototype that I worked on last week. I was...]]></description>
      <content:encoded><![CDATA[<p>For my first post, I figured that I would leverage a prototype that I worked on last week. I was investigating some of the issues that one of the <a href="https://technet.microsoft.com/en-us/windowsserver/sharepoint/bb407286.aspx">Fab40 templates</a> has after you upgrade the server from 2007 to 2010. I learned that the Knowledge Base template has a novel way of solving one of the problems that lookup fields have when using a document library.</p>  <p>Before we dig into the solution to the problem, I should first spend some time describing the problem.</p>  <p>When you create a lookup field, you need to choose a field from the “other” list to be used as the display value. When you are editing an item from “this” list, you will be shown a drop-down list box that allows you to choose an item from the “other” list. When each of the items from the other list are added to the drop-down list, some text value from the other item needs to be displayed here that uniquely identifies the item. Some fields work better than other fields.</p>  <p>For example, let’s say that you are adding a lookup field that is going to be used to select someone from a list of contacts. Using the Zip Code as the field that is displayed in the drop-down list isn’t likely to be very helpful. It would be extremely common for you to have multiple contacts that are in the same zip code. You would then see the same zip code listed more than once in the drop-down list and you would have no idea which entry represents which contact. Choose a contact would be a pretty frustrating experience. Using a field like Name would be a lot better. Granted, the Name field could also contain duplicates. But it would still be a whole lot better than a field like Zip Code which is likely to contain many duplicates.</p>  <p>The problem we have is when the “other” list is a document library. Which field should you choose for the lookup field to display? You could use the Title field but it doesn’t always get populated. Upload some text files into a document library and they will all wind up with an empty value for the Title field. Even if a Title value is specified for each document, this field allows duplicates which, as described above, is not good. So, is there anything about the documents in the document library that is normally going to be unique? Well, the file name. Duh! However, try creating a lookup field to a document library and you’ll notice that there is no file name field to choose. Doh!</p>  <p>The file name is exposed through the object model as a field named FileLeafRef. So why isn't this field available to use in lookup fields? I’m still trying to find someone that can explain that to me. If I figure it out I’ll update this post.</p>  <p>Ok, so now we can (finally) get back to the Knowledge Base site template that I was looking into and how it solved this problem.</p>  <p>One of the features that the Knowledge Base site template has is that articles written in the wiki library can each have one or more related articles. This was accomplished using a multi-value lookup field. Now, multi-valued lookup fields don’t exactly have the greatest UI experience. But they do allow the KB article author to accomplish the scenario without the KB site template developer having to invest in custom (read: expensive) list item selection UI.</p>  <p>But if we're using a multi-value lookup field to choose a document from a document library, what was the field that was used as the lookup field? Well, what the KB site template did was to add a text field to the document library called “Name” in conjunction with an event handler that would ensure that the value of this field always contained the actual name of the file. As wiki articles were created or modified, the event handler would always ensure that the Name field contained the right value.</p>  <p>Now, the way that the KB site template did this was specific to this site template and isn’t really reusable in other site templates. The concept is reusable but the specific implementation in that site template isn’t. So I created a sandboxed solution that contains a reusable implementation of this concept.</p>  <p>Using this solution is pretty easy:</p>  <ul>   <li><strong>Upload the solution</strong> - Upload the solution to the Solution Gallery in your site collection and activate it. </li>    <li><strong>Activate the site feature</strong> - In each of the sites where you want to use this File Name field, activate the site feature named “BillGr's File Name Field”. </li>    <li><strong>Add the site column</strong> - In each document library where you want to use this field, add the site column named File Name to either the document library or the content types that are used in the document library. </li> </ul>  <p><strong>Solution Implementation</strong></p>  <p>In this solution, you’ll find three things:</p>  <ul>   <li>A site column that defines the File Name field. </li>    <li>An assembly that contains a sandboxed event handler. </li>    <li>A feature (which can be activated/deactivated) with two element manifests:      <ul>       <li>One that defines the File Name field.</li>        <li>One that wires-up the event handler to the ItemAdding and ItemUpdating events. </li>     </ul>   </li> </ul>  <p><strong>“File Name” Site Column Definition</strong></p>  <p>One thing to note about the site column is that it has been defined with a very unique internal name (the Name attribute). This is to deal with field name collisions. What if a user has already defined a File Name column? What if they already have other data in that column? What if they already have business logic that is driven by the value of that field. My event handler can’t simply look for the first field named “File Name” that it finds and blindly overwrite its value with the current file name. This is one of the reasons why a field definition has both an internal name and a display name. As an aside, the other main reason for internal names is so that compiled code doesn’t need to be changed when the name of a field is localized into another language. But that’s a subject for a different post.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0d24b5f2-cdf1-428c-bf94-de13654b8598" class="wlWriterEditableSmartContent"> <div class="pavsc-container"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"> <li><span style="color:#0000ff">&lt;?</span><span style="color:#a31515">xml</span><span style="color:#0000ff"> </span><span style="color:#ff0000">version</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">1.0</span>&quot;<span style="color:#0000ff"> </span><span style="color:#ff0000">encoding</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">utf-8</span>&quot;<span style="color:#0000ff">?&gt;</span></li> <li class="pavsc-even"><span style="color:#0000ff">&lt;</span><span style="color:#a31515">Elements</span><span style="color:#0000ff"> </span><span style="color:#ff0000">xmlns</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">https://schemas.microsoft.com/sharepoint/</span>&quot;<span style="color:#0000ff">&gt;</span></li> <li>&nbsp;</li> <li class="pavsc-even">  <span style="color:#0000ff">&lt;!--</span><span style="color:#008000"> NOTE: The Name attribute here must match the value of the FileNameFieldInternalName property</span></li> <li>       <span style="color:#008000">of the ListItemEvents class that is in ListItemEvents&#92;ListItemEvents.cs </span><span style="color:#0000ff">--&gt;</span></li> <li class="pavsc-even">  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Field</span><span style="color:#0000ff"> </span><span style="color:#ff0000">ID</span><span style="color:#0000ff">=</span>&quot;{<span style="color:#0000ff">1511BF28-A787-4061-B2E1-71F64CC93FD5}</span>&quot;</li> <li>       <span style="color:#0000ff"></span><span style="color:#ff0000">Name</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">BillGrFileNameField_FileName</span>&quot;</li> <li class="pavsc-even">       <span style="color:#0000ff"></span><span style="color:#ff0000">DisplayName</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">File Name</span>&quot;</li> <li>       <span style="color:#0000ff"></span><span style="color:#ff0000">Type</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">Text</span>&quot;</li> <li class="pavsc-even">       <span style="color:#0000ff"></span><span style="color:#ff0000">Required</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">FALSE</span>&quot;</li> <li>       <span style="color:#0000ff"></span><span style="color:#ff0000">Group</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">Custom Columns</span>&quot;<span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even">  <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Field</span><span style="color:#0000ff">&gt;</span></li> <li>&nbsp;</li> <li class="pavsc-even"><span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Elements</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>  <p>In this case, we’ve given our field an internal name that uses the solution name as a prefix. It is highly unlikely that another solution will define another field with this same internal name. Later, our event handler will use the same internal name when accessing the field value from the list item.</p>  <p><strong>Event Handler Wire-Up</strong></p>  <p>When a feature definition includes an event handler, usually the event handler has a ListTemplateId or ListUrl attribute. These attributes are normally used to narrow down the scope of the event handler to a specific list type. Since I haven’t included any of these attributes, my event handler will be globally registered. It will be called whenever any item in a list or document library is added or changed – anywhere in the site.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ede92995-d6dc-4462-afbb-7719874ce945" class="wlWriterEditableSmartContent"> <div class="pavsc-container"> <div style="background: #ddd; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"> <li><span style="color:#0000ff">&lt;?</span><span style="color:#a31515">xml</span><span style="color:#0000ff"> </span><span style="color:#ff0000">version</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">1.0</span>&quot;<span style="color:#0000ff"> </span><span style="color:#ff0000">encoding</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">utf-8</span>&quot;<span style="color:#0000ff">?&gt;</span></li> <li class="pavsc-even"><span style="color:#0000ff">&lt;</span><span style="color:#a31515">Elements</span><span style="color:#0000ff"> </span><span style="color:#ff0000">xmlns</span><span style="color:#0000ff">=</span>&quot;<span style="color:#0000ff">https://schemas.microsoft.com/sharepoint/</span>&quot;<span style="color:#0000ff">&gt;</span></li> <li>  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Receivers</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even">      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Receiver</span><span style="color:#0000ff">&gt;</span></li> <li>        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Name</span><span style="color:#0000ff">&gt;</span>ListItemEventsItemAdding<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Name</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even">        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Type</span><span style="color:#0000ff">&gt;</span>ItemAdding<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Type</span><span style="color:#0000ff">&gt;</span></li> <li>        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Assembly</span><span style="color:#0000ff">&gt;</span>$SharePoint.Project.AssemblyFullName$<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Assembly</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even">        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Class</span><span style="color:#0000ff">&gt;</span>BillGr.Samples.FileNameField.ListItemEvents<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Class</span><span style="color:#0000ff">&gt;</span></li> <li>        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">SequenceNumber</span><span style="color:#0000ff">&gt;</span>10000<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">SequenceNumber</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even">      <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Receiver</span><span style="color:#0000ff">&gt;</span></li> <li>      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Receiver</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even">        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Name</span><span style="color:#0000ff">&gt;</span>ListItemEventsItemUpdating<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Name</span><span style="color:#0000ff">&gt;</span></li> <li>        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Type</span><span style="color:#0000ff">&gt;</span>ItemUpdating<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Type</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even">        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Assembly</span><span style="color:#0000ff">&gt;</span>$SharePoint.Project.AssemblyFullName$<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Assembly</span><span style="color:#0000ff">&gt;</span></li> <li>        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Class</span><span style="color:#0000ff">&gt;</span>BillGr.Samples.FileNameField.ListItemEvents<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Class</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even">        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">SequenceNumber</span><span style="color:#0000ff">&gt;</span>10000<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">SequenceNumber</span><span style="color:#0000ff">&gt;</span></li> <li>      <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Receiver</span><span style="color:#0000ff">&gt;</span></li> <li class="pavsc-even">  <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Receivers</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Elements</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>  <p><strong>Event Handler Implementation</strong></p>  <p>The event handler simply ensures that the value of the File Name field is correct given the current name of the document. The code relatively simple. Whenever we’ve been notified that an item has changed, we first have to confirm that the item is in a document library. If it is a “regular” list item, then it won't have a file so there isn’t any file name to stay in sync with. Now, please, no arguments here about Attachments &lt;grin /&gt;. SharePoint treats the primary file stream of a document library item very differently from an attachment to a list item.</p>  <p>In addition to confirming that the item is in a document library, the event handler also needs to confirm that the item has a “File Name” field. If it doesn’t have the field then, again, there isn’t anything that we need to do.</p>  <p>Once we’ve ruled out these other scenarios, all that remains is to extract the file name from the URL and then ensure that the value of the “File Name” field contains this same file name.</p>  <p>   <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:31c3af8a-cd15-479d-ad03-e2281b6e6181" class="wlWriterEditableSmartContent"> <div class="pavsc-container"> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"> <li><span style="color:#0000ff">using</span> System;</li> <li class="pavsc-even"><span style="color:#0000ff">using</span> System.IO;</li> <li><span style="color:#0000ff">using</span> System.Security.Permissions;</li> <li class="pavsc-even"><span style="color:#0000ff">using</span> Microsoft.SharePoint;</li> <li><span style="color:#0000ff">using</span> Microsoft.SharePoint.Security;</li> <li class="pavsc-even"><span style="color:#0000ff">using</span> Microsoft.SharePoint.Utilities;</li> <li><span style="color:#0000ff">using</span> Microsoft.SharePoint.Workflow;</li> <li class="pavsc-even">&nbsp;</li> <li><span style="color:#0000ff">namespace</span> BillGr.Samples.FileNameField</li> <li class="pavsc-even">{</li> <li>    <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span></li> <li class="pavsc-even">    <span style="color:#808080">///</span><span style="color:#008000"> List Item Events</span></li> <li>    <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span></li> <li class="pavsc-even">    <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">ListItemEvents</span> : <span style="color:#2b91af">SPItemEventReceiver</span></li> <li>    {</li> <li class="pavsc-even">&nbsp;</li> <li>        <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span></li> <li class="pavsc-even">        <span style="color:#808080">///</span><span style="color:#008000"> Gets a string containing the internal name of the &quot;File Name&quot; field.</span></li> <li>        <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span></li> <li class="pavsc-even">        <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">string</span> FileNameFieldInternalName</li> <li>        {</li> <li class="pavsc-even">            <span style="color:#0000ff">get</span></li> <li>            {</li> <li class="pavsc-even">                <span style="color:#008000">// NOTE: The value used here has to match the value of the Name attribute in the field</span></li> <li>                <span style="color:#008000">// definition that is in FileNameSharedField&#92;Elements.xml.</span></li> <li class="pavsc-even">                <span style="color:#0000ff">return</span> <span style="color:#a31515">&quot;BillGrFileNameField_FileName&quot;</span>; <span style="color:#008000">// Ensure that this is globally unique by using a prefix that is not likely to be used by someone else.</span></li> <li>            }</li> <li class="pavsc-even">        }</li> <li>&nbsp;</li> <li class="pavsc-even">        <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span></li> <li>        <span style="color:#808080">///</span><span style="color:#008000"> An item is being added.</span></li> <li class="pavsc-even">        <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span></li> <li>        <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name=&quot;properties&quot;&gt;</span><span style="color:#008000">An SPItemEventProperties object that represents properties of the event.</span><span style="color:#808080">&lt;/param&gt;</span></li> <li class="pavsc-even">        <span style="color:#0000ff">public</span> <span style="color:#0000ff">override</span> <span style="color:#0000ff">void</span> ItemAdding(<span style="color:#2b91af">SPItemEventProperties</span> properties)</li> <li>        {</li> <li class="pavsc-even">            <span style="color:#2b91af">ListItemEvents</span>.UpdateFileNameField(properties);</li> <li>            properties.Status = <span style="color:#2b91af">SPEventReceiverStatus</span>.Continue;</li> <li class="pavsc-even">        }</li> <li>&nbsp;</li> <li class="pavsc-even">        <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span></li> <li>        <span style="color:#808080">///</span><span style="color:#008000"> An item is being updated.</span></li> <li class="pavsc-even">        <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span></li> <li>        <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name=&quot;properties&quot;&gt;</span><span style="color:#008000">An SPItemEventProperties object that represents properties of the event.</span><span style="color:#808080">&lt;/param&gt;</span></li> <li class="pavsc-even">        <span style="color:#0000ff">public</span> <span style="color:#0000ff">override</span> <span style="color:#0000ff">void</span> ItemUpdating(<span style="color:#2b91af">SPItemEventProperties</span> properties)</li> <li>        {</li> <li class="pavsc-even">            <span style="color:#2b91af">ListItemEvents</span>.UpdateFileNameField(properties);</li> <li>            properties.Status = <span style="color:#2b91af">SPEventReceiverStatus</span>.Continue;</li> <li class="pavsc-even">        }</li> <li>&nbsp;</li> <li class="pavsc-even">        <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span></li> <li>        <span style="color:#808080">///</span><span style="color:#008000"> Helper method that ensures that the &quot;File Name&quot; field contains the correct value for the specified list item.</span></li> <li class="pavsc-even">        <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span></li> <li>        <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name=&quot;properties&quot;&gt;</span><span style="color:#008000">An SPItemEventProperties object that represents properties of the event.</span><span style="color:#808080">&lt;/param&gt;</span></li> <li class="pavsc-even">        <span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> UpdateFileNameField(<span style="color:#2b91af">SPItemEventProperties</span> properties)</li> <li>        {</li> <li class="pavsc-even">            <span style="color:#008000">// We can only do this if the item is in some form of a doc-lib and the content type of</span></li> <li>            <span style="color:#008000">// the item includes the &quot;File Name&quot; field.</span></li> <li class="pavsc-even">            <span style="color:#0000ff">if</span> ((properties.ListItem == <span style="color:#0000ff">null</span>) ||</li> <li>                (properties.ListItem.File == <span style="color:#0000ff">null</span>) ||</li> <li class="pavsc-even">                (!properties.ListItem.Fields.ContainsField(<span style="color:#2b91af">ListItemEvents</span>.FileNameFieldInternalName)))</li> <li>            {</li> <li class="pavsc-even">                <span style="color:#0000ff">return</span>;</li> <li>            }</li> <li class="pavsc-even">&nbsp;</li> <li>            <span style="color:#008000">// Extract just the file name from the server-relative URL. Note: URLs with forward slashes</span></li> <li class="pavsc-even">            <span style="color:#008000">// are compatible with the System.IO.Path class. We are using that here so that we don&#39;t</span></li> <li>            <span style="color:#008000">// have to do any URL parsing. Any time that we try and do URL parsing on our own we</span></li> <li class="pavsc-even">            <span style="color:#008000">// eventually get into trouble beause of some corner case that wasn&#39;t accounted for in</span></li> <li>            <span style="color:#008000">// the parsing code. We&#39;ll avoid that problem if we leverage the Path class which has</span></li> <li class="pavsc-even">            <span style="color:#008000">// already been extensively tested.</span></li> <li>            <span style="color:#0000ff">string</span> fileNameWithoutExtension = <span style="color:#2b91af">Path</span>.GetFileNameWithoutExtension(properties.AfterUrl);</li> <li class="pavsc-even">&nbsp;</li> <li>            <span style="color:#008000">// Ensure that the &quot;File Name&quot; field contains the current file name.</span></li> <li class="pavsc-even">            properties.AfterProperties[<span style="color:#2b91af">ListItemEvents</span>.FileNameFieldInternalName] = fileNameWithoutExtension;</li> <li>        }</li> <li class="pavsc-even">&nbsp;</li> <li>    } <span style="color:#008000">// class ListItemEvents</span></li> <li class="pavsc-even">&nbsp;</li> <li>}</li> </ol> </div> </div> </div> </p>  <p><strong>Downloading The Sample</strong> </p>  <p>There are two downloads available from the <a href="https://code.msdn.microsoft.com/BillGrFileNameField/Release/ProjectReleases.aspx?ReleaseId=4964">MSDN Code Gallery for this sample</a>:</p>  <ul>   <li><strong>SharePoint Solution</strong> - This is a working .WSP that you can upload to the Solution Gallery for your site collection and activate it. Once you do this, the “BillGr's File Name Field” feature will be available to activate in all sites of your site collection. After activating the feature, you can add the site column named “File Name” to a document library to start getting updated file names. You'll find this site column in the “Custom Columns” group. </li>    <li><strong>Visual Studio Project</strong> - This is the VS 2010 SharePoint solution that was used to generate the solution above. </li> </ul>  <p>As with any of my other samples, you are free to use the solution in your site or take the source code and leverage it in some other solution that you are working on. Just keep in mind that this is a sample and, as such, has no warranty, no guarantee that it will work in all environments, and no promise that a future version of SharePoint won't break it.</p>]]></content:encoded>
    </item>
    <item>
      <title>Introduction</title>
      <link>https://docs.microsoft.com/archive/blogs/billgr/introduction</link>
      <pubDate>Fri, 17 Sep 2010 08:35:00 GMT</pubDate>
      <dc:creator><![CDATA[Bill Griffin - MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/billgr/2010/09/17/introduction/</guid>
      <description><![CDATA[I figured that in my first post to this blog I should probably introduce myself and set some context...]]></description>
      <content:encoded><![CDATA[<p>I figured that in my first post to this blog I should probably introduce myself and set some context for what I&rsquo;d like to accomplish here.</p>
<p>My name is Bill Griffin. I&rsquo;m a developer at Microsoft working on SharePoint. I&rsquo;ve worked on a variety of things since I started at Microsoft&nbsp;back in 1993. I was one of the original members of the team that started work in 1998 on the project codenamed Tahoe - which eventually went on to ship as SharePoint Portal Server 2001. Over the years, I&rsquo;ve held a variety of &ldquo;senior-dev-guy&rdquo; type roles on the SharePoint team. It&rsquo;s been a fun ride and I&rsquo;m still excited about the direction the SharePoint family of products are going and what the platform can do.</p>
<p>The features that are now available with the 2010 release are simply staggering. But one of the things that I&rsquo;ve noticed over the years is that some of the ways that product team members know how to stretch, bend, and contort SharePoint and make it do really cool stuff sometimes doesn't makes it out of the hallways of the product team.</p>
<p>Those are the kinds of things that I&rsquo;d like to post about here.</p>
<p>I&rsquo;m not trying to produce comprehensive documentation or sample code&nbsp;regarding every feature in the entire SharePoint product family. I&rsquo;ll leave that to others who are better at that than I am. I just wanted a place&nbsp;to share information about SharePoint and to be able to post samples that show novel ways of leveraging SharePoint as I run across them here in the product team.</p>]]></content:encoded>
    </item>
  </channel>
</rss>