1

我正在尝试在 Sharepoint MOSS 2007 自定义 Web 部件中加载 XSLT 文件,但在尝试访问 XSLT 文件时出现 401 错误。我尝试提供默认凭据,但在调试期间检查时它是空的。

有谁知道如何从自定义 Web 部件加载 XSLT 文件?提前致谢。

    XmlUrlResolver resolver = new XmlUrlResolver();
    resolver.Credentials = CredentialCache.DefaultNetworkCredentials;

    XsltSettings settings = new XsltSettings(true, true);  

    XslCompiledTransform oXSLTranform = new XslCompiledTransform();

    string siteUrl = SPContext.Current.Site.Url;
    if (siteUrl.EndsWith("/"))
        siteUrl = siteUrl.Remove(siteUrl.LastIndexOf("/"));

    siteUrl += "/Style Library/XSL Style Sheets/THM1News.xslt";

    oXSLTranform.Load(siteUrl ,settings, resolver);

此代码返回 401 错误:

远程服务器返回错误:(401) Unauthorized。

[WebException: 远程服务器返回错误:(401) Unauthorized.] System.Net.HttpWebRequest.GetResponse() +5313085 System.Xml.XmlDownloadManager.GetNonFileStream(Uri uri, ICredentials credentials) +69 System.Xml.XmlDownloadManager.GetStream (Uri uri,ICredentials 凭据)+3929007 System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri,字符串角色,Type ofObjectToReturn)+54 System.Xml.Xsl.Xslt.XsltLoader.CreateReader(Uri uri,XmlResolver xmlResolver)+26 System. Xml.Xsl.Xslt.XsltLoader.Load(编译器编译器,对象样式表,XmlResolver xmlResolver)+315 System.Xml.Xsl.Xslt.Compiler.Compile(对象样式表,XmlResolver xmlResolver,QilExpression&qil)+41 System.Xml.Xsl。 XslCompiledTransform.CompileXsltToQil(对象样式表,XsltSettings 设置,XmlResolver stylesheetResolver)+59 System.Xml.Xsl。XslCompiledTransform.LoadInternal(Object stylesheet, XsltSettings settings, XmlResolver stylesheetResolver) +66 System.Xml.Xsl.XslCompiledTransform.Load(String stylesheetUri, XsltSettings settings, XmlResolver stylesheetResolver) +38 NewsGallery.AjaxNewsWebPart.AjaxNewsControl.RenderContents(HtmlTextWriter output) +403 System .Web.UI.WebControls.WebControl.Render(HtmlTextWriter 编写器)+32 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter 编写器,ControlAdapter 适配器)+27 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器,ControlAdapter 适配器) +99 System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25 System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +134 System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +19 System.Web.UI.WebControls.WebControl。RenderContents(HtmlTextWriter 编写器)+10 System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter 编写器)+32 Microsoft.SharePoint.WebPartPages.WebPart.RenderWebPart(HtmlTextWriter 输出)+36 Microsoft.SharePoint.WebPartPages.WebPart.RenderWebPartInternal(HtmlTextWriter编写器)+139 Microsoft.SharePoint.WebPartPages.WebPart.Render(HtmlTextWriter 编写器)+93 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter 编写器,ControlAdapter 适配器)+27 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器, ControlAdapter 适配器)+99 System.Web.UI.Control.RenderControl(HtmlTextWriter writer)+25 Microsoft.SharePoint.WebPartPages.SPChrome.RenderPartContents(HtmlTextWriter 输出,WebPart 部分)+66渲染(HtmlTextWriter 编写器)+32 Microsoft.SharePoint.WebPartPages.WebPart.RenderWebPart(HtmlTextWriter 输出)+36 Microsoft.SharePoint.WebPartPages.WebPart.RenderWebPartInternal(HtmlTextWriter 编写器)+139 Microsoft.SharePoint.WebPartPages.WebPart.Render(HtmlTextWriter 编写器) +93 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter 编写器,ControlAdapter 适配器)+27 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器,ControlAdapter 适配器)+99 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器) +25 Microsoft.SharePoint.WebPartPages.SPChrome.RenderPartContents(HtmlTextWriter 输出,WebPart 部分) +66渲染(HtmlTextWriter 编写器)+32 Microsoft.SharePoint.WebPartPages.WebPart.RenderWebPart(HtmlTextWriter 输出)+36 Microsoft.SharePoint.WebPartPages.WebPart.RenderWebPartInternal(HtmlTextWriter 编写器)+139 Microsoft.SharePoint.WebPartPages.WebPart.Render(HtmlTextWriter 编写器) +93 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter 编写器,ControlAdapter 适配器)+27 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器,ControlAdapter 适配器)+99 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器) +25 Microsoft.SharePoint.WebPartPages.SPChrome.RenderPartContents(HtmlTextWriter 输出,WebPart 部分) +66WebPartPages.WebPart.Render(HtmlTextWriter 编写器)+93 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter 编写器,ControlAdapter 适配器)+27 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器,ControlAdapter 适配器)+99 System.Web .UI.Control.RenderControl(HtmlTextWriter writer)+25 Microsoft.SharePoint.WebPartPages.SPChrome.RenderPartContents(HtmlTextWriter 输出,WebPart 部分)+66WebPartPages.WebPart.Render(HtmlTextWriter 编写器)+93 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter 编写器,ControlAdapter 适配器)+27 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器,ControlAdapter 适配器)+99 System.Web .UI.Control.RenderControl(HtmlTextWriter writer)+25 Microsoft.SharePoint.WebPartPages.SPChrome.RenderPartContents(HtmlTextWriter 输出,WebPart 部分)+66

4

2 回答 2

1

不久前我遇到了同样的问题。这可能无法帮助您看到您发布已经有一段时间了,但它可能会帮助其他人。

我假设您已经消除了导致此 401 错误的明显情况 - 即样式库中的 xslt 没有已发布的主要版本或访问将 xslt 拉到没有的用户帐户下的 webpart 页面首先可以访问样式库。我还假设您有一个农场环境,其中至少有一个 Web 前端和一个单独的数据库服务器来托管内容数据库,Web 应用程序未启用匿名访问,并且身份验证方案是与 NTLM 集成的窗口(不是 kerberos)授权和模拟已启用。

这里我们需要了解的是,当您从 webpart 代码中调用 oXSLTranform.Load(xsltUrl) 时,在模拟用户的凭据下运行的代码实际上是在制定一个带外请求(请求不是直接来的)来自浏览器)用于驻留在数据库中而不是物理上位于 Web 服务器上的文件。如果您在发出请求的 Web 前端查看 IIS 日志,您将看到正常的 401.2,然后是 401.1(正常的 NTLM 握手请求-响应序列),但下一个响应也将是 401.1,而不是预期的200.0 因为请求是使用空的 cs-username 标头发出的(而不是预期的模拟用户名)。它是空的,因为无法委派此带外请求的安全上下文(因为未启用 kerberos),并且由于 Web 应用程序也未启用匿名访问,因此对文件的请求以 401 状态被拒绝。您需要将一个明确的网络凭据对象(如在 new NetworkCredential(username, password, domain) 中)传递给您的解析器以使其工作,这显然是不行的。

这是我解决它的方法...

string siteUrl = SPContext.Current.Site.Url;
SPWeb rootWeb = SPContext.Current.Site.RootWeb;

if (siteUrl.EndsWith("/")) 
    siteUrl = siteUrl.Remove(siteUrl.LastIndexOf("/"));

string xmlFileUrl = siteUrl + "/data.xml";
string xsltFileUrl = siteUrl + "/transform.xslt";

if (rootWeb != null)
{
    var xmlDoc = new XmlDocument();
    var xslDoc = new XmlDocument();

    SPFile xmlDataFile = rootWeb.GetFile(xmlFileUrl);  // since you are
    // using the SP OM to extract the file from the doc library item you
    // are going under the impersonated user credential. No need to elevate
    // permissions

    if (xmlDataFile != null)
    {
        Stream xmlDataStream = xmlDataFile.OpenBinaryStream();
        xmlDoc.Load(xmlDataStream);
        xmlDataStream.Close();
    }

    SPFile xsltTransformFile = rootWeb.GetFile(xsltFileUrl);

    if (xsltTransformFile != null)
    {
        Stream xsltStream = xsltTransformFile.OpenBinaryStream();
        xslDoc.Load(xsltStream);
        xsltStream.Close();
    }

    // You now have your xmlDoc and xslDoc you can run your transform
    // without having to provide a resolver
    TransformXml(xmlDoc.outerXml, xslDoc.outerXml, false);
}

private string TransformXml(string xml, string xslt, bool bDebug)
{
    StringReader xsltInput = new StringReader(xslt);
    StringReader xmlInput = new StringReader(xml);
    XmlTextReader xsltReader = new XmlTextReader(xsltInput);
    XmlTextReader xmlReader = new XmlTextReader(xmlInput);

    // Create required writer for output   
    StringWriter stringWriter = new StringWriter();
    XmlTextWriter transformedXml = new XmlTextWriter(stringWriter);

    // Create a XslCompiledTransform to perform transformation   
    XslCompiledTransform xsltTransform = new XslCompiledTransform(bDebug);            
    xsltTransform.Load(xsltReader);
    xsltTransform.Transform(xmlReader, transformedXml);
}
于 2011-06-09T22:21:42.827 回答
1

我改用了这种方法:

StringReader xmlReader = new StringReader(rawXML);
XPathDocument xmlDoc = new XPathDocument(xmlReader);

XslCompiledTransform myXslTransformer = new XslCompiledTransform();
XmlUrlResolver xmlResolver = new XmlUrlResolver();
xmlResolver.Credentials = CredentialCache.DefaultCredentials;
XsltSettings settings = new XsltSettings(true, true);

// Load XSL
SPSecurity.RunWithElevatedPrivileges(delegate()
{
    myXslTransformer.Load(XslPath, settings, xmlResolver);
});


// Create the output stream
StringWriter sWriter = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(sWriter);

// Transform
myXslTransformer.Transform(xmlDoc, null, writer);

writer.Close();

string transformedXML = sWriter.ToString();

它奏效了。

于 2012-05-15T12:57:49.130 回答