I have a SharePoint solution which deploys an aspx page in a custom folder in the Layouts folder. I need to get this page in the Feature Event Receiver so I can add to it a WebPart.

In the FeatureActivated method when I am trying to use this code:

SPFile file = web.GetFile("_layouts/My Folder/MyPage.aspx");  

This code returns a File not found exception.

How can I get a reference to this page? Is this error occuring because the page has not been deployed yet?


Thanks for Spongeroberto Squarepantalones and SPArchaeologist help, I did the following:

  1. I created a Module in my SharePoint Solution and added to it an aspx page.
  2. In this aspx page I added an WebPartPages:SPWebPartManager and a WebPartPages:WebPartZone.
  3. I edited the Elements.xml file in the module to deploy the page in a Document Library. (I need to access this page from a specified site only).
  4. In the FeatureActivated method in the Feature Event Receiver I added code to create a WebPart, get this page as an SPFile and used an SPLimitedWebPartManager to add my created WebPart. (I did this and had not created a WepPart in the aspx page directly because the WebPart displays SharePoint items from a Document Library and use a SharePoint View that are deployed in the same solution, so their GUID allways change).
| improve this answer | |
  • Moussa, you can also accept your own answer if needed. That way, other people will know that your question contains an answer that resolved your problem - this can help people searching. No need to do that right now, but know it is an option. – BlueSoul Nov 29 '12 at 11:18
  • Thank you SPArchaeologist I will, but I need 2 days to be able to accept my own answer. – user3470 Nov 29 '12 at 11:44
  • Urgh, sorry, I was thinking they removed that limit when the "answer your question" option was implemented in questions. Seems it is not the case. My bad, disregard that comment – BlueSoul Nov 29 '12 at 11:56

Items are deployed before the event receiver. The problem is you're trying to read a hive file. That's not gonna work with the SPWeb.GetFile method. That method is meant for files that are stored in that web.

You can still read the file, however. I needed to do the same and wrote a method like this:

/// <summary>
/// get the proper path to the hive
/// </summary>
private static string GetUtilPath(string path)
    return SPUtility.GetGenericSetupPath(@"TEMPLATE\LAYOUTS\MyModule\" + path);

/// <summary>
/// Access a file in the SharePoint hive
/// </summary>    
/// <param name="path">the path relative to the layouts folder</param>   
private static byte[] GetHiveFile(string path)
    string utilPath = GetUtilPath(path);
    using(FileStream fs = new FileStream(utilPath, FileMode.Open, FileAccess.Read))
        BinaryReader br = new BinaryReader(fs);
        long numbytes = new FileInfo(utilPath).Length;
        return br.ReadBytes((int)numbytes);

Then you can read a file from the hive like this:

byte[] file = GetHiveFile(@"myfolder\myfile.txt");
| improve this answer | |
  • Thanks for this method. If I use it how can I create an SPFile object? Because I need an SPFile to be able to add a WebPart to the page. Or is there another way? – user3470 Nov 29 '12 at 7:56
  • If you want to add a web part to that specific page, I guess you would be better off copying the hive file to a document library on your web. You can use the byte[] to do that. Here's how you would add it to the site pages library: SPFolder sitePages = web.Lists["Site Pages"].RootFolder; sitePages.Files.Add("mypage.aspx", file); – Kenneth Van Coppenolle Nov 29 '12 at 8:05
  • +1 for pointing me in the right direction. Thanks for your efforts. – user3470 Nov 29 '12 at 9:58

Based on other answers (see this or this) SPFile.GetFile(string) cannot be used to get hold of a "SPFile" in the _layout folder. There are other way to read the page (like some answer suggested), but in the end you would just obtain a stream/bytearray or such - you are trying to add a web part, so I fear that wouldn't really help. That is because as far as SharePoint is concerned, _layout is a virtual IIS folder, and file inside it AREN'T seen as SPfile.

That said, adding a web part to an application page as far as I known isn't even supported: if you try to add a web part zone with a web part inside you should receive an error similar to "“Unknown server tag WebPartZone" (see this blog or this answer from Dave). Web part on application page are possible only if used as standard web control (and even there there are some issues with caching and such).

If you have to, your best bet seems to be opening the file programmatically like a text file and then adding the required tags manually - you won't be able to use the web part manager. Anyway, I would try and see if I can redeploy that page to a page library or such and transform it to a standard publishing page.

| improve this answer | |
  • I programmatically added web parts to aspx pages using web part manager. This does require you to copy the page to a web first, and to add web part zones beforehand. – Kenneth Van Coppenolle Nov 29 '12 at 8:26
  • And that's the point. If you copy it to the web, it is not an application page anymore (or at last not strictly talking). Since at that point you would lose one of the main point of using a _layout page (-> the page is the same for all web site), why keep it in the layout folder at all? That said, if you don't have control of the page original location AND is acceptable to customize it on a web site basis your solution should work without problem. – BlueSoul Nov 29 '12 at 8:35
  • Btw, I was more point at explaining WHY you can't use the SPFile object (never intended to say that your solution is wrong). Your solution provide a valid alternative for customizing the page, but all depends on what is acceptable for the user. – BlueSoul Nov 29 '12 at 8:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy