How to access a file in the current url or _layouts folder?
Question
My code behind code from the aspx webpage uses a transform.xsl to do some custom xslt transformation.
Scenario 1: Try to get the file from the _layouts folder.
SPWeb web = SPContext.Current.Web;
SPFile file = web.GetFile(@"/layouts/MyFeature/transform.xsl");
Note : The file is accesible on this url http://mysite:8080/_layouts/MyFeature/transform.xsl when using the browser.
Scenario 2: Try to get the file from the current (http://mysite:8080/MyFeature/MyPage.aspx) url.
SPWeb web = SPContext.Current.Web;
SPFile file = web.GetFile(@"transform.xsl");
or
SPFile file = web.GetFile(@"MyFeature/transform.xsl");
or
SPFile file = web.GetFile(@"/MyFeature/transform.xsl");
All scenarios fail, how to solve this?
Solution
The 'transform.xsl' is now located at 'MyFeature/transform.xsl' and I've followed the tip from Anders Rask, and my code looks like this now:
SPWeb web = SPContext.Current.Web;
XslCompiledTransform transformer = new XslCompiledTransform();
XsltSettings settings = new XsltSettings(true, true);
string xslLocation = web.Url + "/FormWrapper/transform.xsl";
transformer.Load(xslLocation, settings, GetResolverWithDefaultCredentials());
// Do XSLT transform...
Solution
I'm pretty sure SPWeb.GetFile() returns your site pages, like default.aspx. Also your XSLT file isnt an SPFile if its located in the _LAYOUTS folder.
Instead try something similar to the below code (note boilerplate code so error handling etc should be added)
// fetch xsl processor
XslCompiledTransform processor = GetXslt(@"/layouts/MyFeature/transform.xsl");
StringWriter writer = new StringWriter(CultureInfo.CurrentCulture);
// Transform XSLT code here
private static XslCompiledTransform GetXslt(string xsltUrl)
{
XslCompiledTransform processor = new XslCompiledTransform(false);
bool enableDocumentFunctions = true;
bool enableScript = true;
XsltSettings settings = new XsltSettings(enableDocumentFunctions, enableScript);
// add error handling here
processor.Load(xsltUrl, settings, GetResolverWithDefaultCredentials());
return processor;
}
// use resolver to avoid getting security exceptions
private static XmlUrlResolver GetResolverWithDefaultCredentials()
{
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;
return resolver;
}
OTHER TIPS
You could write a Module Feature that "uploads" your transform.xsl into a document library (Style Library for example) which allows you to access the file as an SPFile.