Share Point Sample Code

  • Published on
    14-Nov-2014

  • View
    1

  • Download
    0

Embed Size (px)

Transcript

<p>SharePoint Tips &amp; Code 1.Here is a bit of code to retrieve the list items from a list: SPList list = web.Lists["MyLibrary"]; if (list != null) { var results = from SPListItem listItem in list.Items select new { xxx = (string)listItem["FieldName"]), yyy = (string)listItem["AnotherField"], zzz = (string)listItem["Field"] }; } To retrieve a file you could also use this method on SPWeb: GetFileAsString Without linq: int itemId = getItemId(); SPWeb currentWeb = SPContext.Current.Web; SPList list = currentWeb.Lists["MyList"]; if ( list != null ) { SPListItem theItem = list.Items.GetItemById(itemId); doWork(theItem); } The SPWeb can be retrieved in numerous ways, using the SPContext will work if the code is called from SharePoint. To get an SPWeb object from a URL you can use SPSite object i.e. using ( SPSite site = new SPSite(urlToWeb) ) { using (SPWeb web = site.OpenWeb()) { doWork(web); } } the 'using' statement ensures non-managed resources are reclaimed in a timely manner, by calling 'Dispose()' on the relevant objects. Effective as that may be, you should really look into best practices as they relate to storing documents in the 12 hive versus the content database. private static string getXsl() { string xslString = null; using (StreamReader streamReader = new StreamReader(File.Open(HttpContext.Current.Server.MapPath(@"~_layouts\theXSL.xslt"), FileMode.Open))) { xslString = streamReader.ReadToEnd(); } Page | 1</p> <p>SharePoint Tips &amp; Code return xslString; }</p> <p>2.Using linq with Sharepoint and disposing of objects</p> <p>The technical answer to your original question is a qualified "No": all SPWeb objects opened from an SPSite are automatically disposed when the SPSite is disposed. However, in practice it is a good idea to dispose an SPWeb as soon as you're done with it to reduce memory pressure, especially when working with code like this that opens several SPWeb objects. Implementing this dispose-safe behavior for LINQ is actually quite simple in C#. You can find full details in this post, but the short version is that a C# iterator can handle disposal for you. Using my AsSafeEnumerable() extension method, your code is relatively safe written like this: using (SPSite spSite = Utility.GetElevatedSite(_rootUrl)) { var sw = from SPWeb web in spSite.AllWebs.AsSafeEnumerable() where web.ServerRelativeUrl.ToLower() == path from SPWeb subWeb in web.Webs.AsSafeEnumerable() select subWeb; foreach(SPWeb aSubWeb in sw) { // Do something } } Now the result of your query, which I've assigned to sw, is a lazy iterator of type IEnumerable. As you enumerate over that result, each SPWeb will be disposed when the enumerator moves to the next item. This means that it is not safe to use that SPWeb reference, or any SP* object created from it (SPList, etc), outside of your foreach loop. Also sw would not be safe to use outside of that using block because the iterator's SPWebCollections will be tied to the now-disposed SPSite. That said, code like this that enumerates over all webs (twice!) is extremely expensive. There is almost certainly a more efficient way that this could be implemented, if only by using spSite.AllWebs[path] instead of your from/where. Regarding garbage collection, these objects require disposal because of unmanaged memory allocated that the GC doesn't even know about. Finally, a word of caution about your 'GetElevatedSite' utility. If you're using RunWithElevatedPrivileges in your helper method to get your elevated SPSite, there are a number of issues you could run into by returning your SPSite out of that elevated context. If possible, I would suggest using SPSite impersonation instead - my preferred method is described here. Q: When should you dispose SPWeb and SPSite objects? And even more important, when not?</p> <p>Page | 2</p> <p>SharePoint Tips &amp; Code A: You should always dispose them if you created them yourself, but not otherwise. You should never dispose SPContext.Current.Web/Site and you should normally not dispose SPWeb if IsRootWeb is true. More tricky constructs are things along the line of SPList.ParentWeb.</p> <p>3.Sharepoint API - How to Upload files to Sharepoint Doc Library from ASP.NET Web Application You can write some custom code to do it. You could use the SharePoint API if you are on the same server or use WebServices Here is the sample code assuming that you know the url of the document library and you are uploading the document to the root folder. You will have to add Microsoft.SharePoint.dll as reference to your ASP.NET project using (SPSite siteCollection = new SPSite(url)) { using (SPWeb spWeb = siteCollection.OpenWeb()) { SPList spList = spWeb.GetList(url); string fileName = "XXXX"; FileStream fileStream = null; Byte[] fileContent = null; try { string docPath = XXXX; //physical location of the file fileStream = File.OpenRead(docPath + fileName); fileContent = new byte[Convert.ToInt32(fileStream.Length)]; fileStream.Read(fileContent, 0, Convert.ToInt32(fileStream.Length)); spList.RootFolder.Files.Add(spList.RootFolder.Url + "/" + fileName, fileContent, true); spList.Update(); } catch(Exception ex) { } finally { if (fileStream != null) { fileStream.Close(); } } } } Page | 3</p> <p>SharePoint Tips &amp; Code</p> <p>4.SPSite, SPWeb and SPWebCollection http://www.sharepointblogs.com/mingssn/archive/2007/10/10/sharepoint-programming.aspx Sharepoint come with many class. Some class name is confusing. SPSite: Represents a collection of sites on a virtual server, including a top-level site and all its subsites. Each SPSite object, or site collection, is represented within an SPSiteCollection object that consists of the collection of all site collections on the virtual server. Note: SPSite is NOT a Collection, in another words, you can not use foreach to loop SPSite. To do this, you have to use SPWebCollection. SPWebCollection: Represents a collection of SPWeb objects. SPWeb: Represents a SharePoint Web site. SPFolder: Represents a folder on a SharePoint Web site. The following snipet is copy from a class: #region properties /// /// site collection url address /// public string _RootSiteUrl { get { return RootSiteUrl; } set { RootSiteUrl = value; } } /// /// Site collection, get SPSite object repsent a "collection" /// public SPSite _Sites { get { return new SPSite(this._RootSiteUrl); } set { Sites = value; } } /// /// Web collection, SPWebCollection, this is the real Collection /// public SPWebCollection _Webs { Page | 4</p> <p>SharePoint Tips &amp; Code get { return this._Sites.AllWebs; } } public string _PPMAspxPageSiteUrl { get { return this.PPMTargetSiteUrl; } set { PPMTargetSiteUrl = value; } } public SPWeb this[string SiteName] // indexer, represent a SPWeb { get { int i = 0; foreach (SPWeb web in this._Webs) { if (web.Url == SiteName) return this._Webs[ i ]; i++; } return null; } } #endregion The indexer is quite useful, to get a SPWeb object, simply use mySharePointClass["your site or subsite url"] to access!</p> <p>Sharepoint tips 5.Enable Sharepoint server side script</p> <p>By default, Sharepoint does not allow server side script for security reason. To get around this, you can modify your web.config to specify which page(s) you allow server side script. For example, you can add following code to your Sharepoint application web.config. ( I am using /en-ca/pages/* as example ) I found this is very useful during development if you are using in-line script for your aspx pages. Lets say you have a SP project including some customrized aspx pages. Youve created feature and a wsp file to install in your Sharepoint. Now you noticed you have to do some change to the in-line script of the aspx file. Of course, you could re-deploy the entire wsp again, but as a developer, you dont want do this because most likely you have to modify the aspx again and again Following is the steps I am using Page | 5</p> <p>SharePoint Tips &amp; Code 1. Load aspx pages from Sharepoint UI and publish it 2. Reset IIS 3. Load this aspx page from your browser Sharepoint will give you error message saying server script is not allowed. OK, thats fine, modify web.config add and reload the page. Yeah, everything is working and you can see your changes. Someting you should also know 1. It is better using code behind for the aspx pages in your SP project. By using code behind, when you change any logic of your aspx pages, you only rep-deploy dlls, not the page itself. You dont need modify web.config. 2. Why this does not happen before you change and load the aspx page to the SP? That page also contains script, but SP did not give any error at that time. I will explain this in my next post Sharepoint ghost</p> <p>6.Backup/restore sharepoint content database</p> <p>Ive read some articles of how to backup/restore Sharepoint application. Of course you can use stsadm -o backup&amp;restore to do the job but you can also backup/restore content database from sql server directly. Even this is not recommended by some Sharepoint guru but I believeit is good to know and it might work in your scenario (for example, move production/staging/QA envirnment to your dev envirnment). Ok, here are the steps. 1. Backup your sharepoint content database from sql server 2. Go to Sharepoint Centre Admin-&gt;Application Management-&gt;Content databases. Locate your sharepoint application and remove the content database. This will basically break the link between your sharepoint application and your content database. If you dont do this, the link always exists and you will not be able to restore the content database later because sql server thinks the content database is still in use, and you will find you cant kill that process in the sql server. 3. Delete and recreate you local sharepoint content database ( what? r u crazy? ) 4. Restore the content database you did in step 1 5. Go to same place as step 2 and attach the content database. Note, you might get a error message saying the sql database collation is not correct, it is because your sql server default collation is different than what sharepoint required. Go to step 3 and create the database as request by choosing collation Latin1_General_CI_AS_KS_WS. 6. Reset IIS 7. Its better re-deploy your sharepoint solution but this may not necessary 8. Dont forget reset sharepoint site collection administrator Few problems you might notice when you access your sharepoint application. 1. Make sure disgard checked out files, otherwise site collection adm will get error when visiting those pages. 2. Any search settings such as scope, managed property, keywords will not restore Page | 6</p> <p>SharePoint Tips &amp; Code 3. I dont have a chance to try this on multiple content database scenario, it might not work properly if that is the case. Thats it; this is just an alternative way to backup/restore your sharepoint content. 7.How to programmatically enable scheduling (part I) One of my current task is to enable scheduling for existing 44 document/list libraries. All of these document/list library has only one content type associated with and it was inherited from a base content type. However, Sharepoint default site column Scheduling Start Date and Scheduling End Date are not included in the base content type. To accomplete the task, you can use Sharepoint to configure this manually, steps as following 1. add Scheduling Start Date and Scheduling End Date to the library 2. enable versioning 3. enable scheduling 4. repeat 44 times Apparently, this is not a good idea. If we need rebuild the site from scratch, that means you have to repeat step 1-4 again. So, put on developers hat: My first thought is to add Sharepoint default Scheduling Start Date and Scheduling End Date site column to the base content type. I have my content type xml already, so I added the following The only trick is how to find the default guid. Go to site setting-&gt;content type-&gt;click any of the site content type include above fields (for example: Generic Content-&gt;Scheduling Start Date). The browser address bar ends like Fid=%7B51d39414%2D03dc%2D4bd0%2Db777%2Dd3e20cb350f7%7D, replace %7B with {, %2D with -, %7D with }, the guid is {51d39414-03dc-4bd0-b777-d3e20cb350f7}. Well, build and deploy, those 2 fields successfully added to my base content type. But wait.this does not solve my problem yet. Oops, those 44 document/list library does not change at all because they are there ALREADY.my changing of base content type only work for those NEW document/lists, not for the existing one. Rather than write your own code, Sharepoint actually has a option to let you update all inherited content types when you add/delete site column from its parent content type. You could go to site setting-&gt;modify site setting -&gt; content type -&gt; select the base content type -&gt; add fields from existing site column. Make sure update inheritate content type check box is checked. Also, do these manual steps before you install the solution. Ok, the 2 extra fields were added to the entire document library after this (In my case, all content library inherited from the base content type). But, to enable scheduling, you have to enable versioning and scheduling. Instead of do it manually, I decide create a feature to loop through all document library and enable scheduling. Page | 7</p> <p>SharePoint Tips &amp; Code 8.Organize your Sharepoint solution If you using Visual Studio to design/develop SharePoint solution, keep in mind you suppose using only ONE solution for your entire SharePoint project, that is, only ONE .wsp file will be created for your SharePoint deployment later. By doing this, usually more work for your team is required but will make your deployment much easier and you could also automate your Sharepoint deployment in the future. This article is about how to organize your Sharepoint solution based on my experience. Organize your SharePoint solution Sharepoint solution usually include A: Sharepoint base project Your Sharepoint solution is based on this project. This project will handle all the Sharepoint envirnoment. For example: Site column, content type, page layout, master page, list, document library, event handler, managed property, search scope, site definition. Be patient and be careful because this is the backbone your application will establish on. B: Sharepoint UI project This should include web parts, ASP.NET control, AJAX controls, delegate controls, css and resource files. I would also include any third party controls into this project if there is any. C: Sharepoint BI project This is business interface and logic project, including your business UI, logic and all your .aspx pages. In visual studio, you probably need separate this into several projects. For example: a database layer project, a business logic layer project, a user interface layer project, a workflow layer project C: Sharepoint support project This project is to support your solution. This maybe vary depend on what you need. For example, you may need a feature/function to import some data to the SharePoint list a function to help you manage users. a pag...</p>