Загрузка XSLT-файла веб-части Sharepoint возвращает 401 - PullRequest
1 голос
/ 02 марта 2011

Я пытаюсь загрузить файл XSLT в пользовательскую веб-часть Sharepoint MOSS 2007, но при попытке доступа к файлу XSLT я получаю ошибку 401.Я попытался предоставить учетные данные по умолчанию, но при проверке во время отладки он пуст.

Кто-нибудь знает, как я могу загрузить файл 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) Не авторизован.

[WebException: удаленный сервер возвратил ошибку: (401) не авторизован.] System.Net.HttpWebRequest.GetResponse () +5313085 System.Xml.XmlDownloadManager.GetNonFileStream (Uri uri, учетные данные ICredentials) +69 система.Xml.XmlDownloadManager.GetStream (Uri uri, учетные данные ICredentials) +3929007 System.Xml.XmlUrlResolver.GetEntity (Uri absoluteUri, строковая роль, тип объектаObjectToReturn) +54 системный. XML-файл.xmlResolver) +26 System.Xml.Xsl.Xslt.XsltLoader.Load (компилятор компилятора, таблица стилей объектов, XmlResolver xmlResolver) +315 System.Xml.Xsl.Xslt.Compiler.Compile (таблица стилей объектов, XmlResolver & qilp) xmlResolver xmlResolverSystem.Xml.Xsl.XslCompiledTransform.CompileXsltToQil (Таблица стилей объекта, параметры XsltSettings, таблица стилей XmlResolver) +59 System.Xml.Xsl.XslCompiledTransform.LoadInternal (таблица стилей стилей, файлЗагрузить (стиль строкинастройки sheetUri, XsltSettings, stylesheetResolver XmlResolver +38 NewsGallery.AjaxNewsWebPart.AjaxNewsControl.RenderContents (вывод HtmlTextWriter) +403 System.Web.UI.WebControls.WebControl.TerWinterWriterInTerWinterWriterInTerWinterWRerTerWRT (Модуль записи HtmlTextWriter, адаптер ControlAdapter) +27 System.Web.UI.Control.RenderControl (модуль записи HtmlTextWriter, адаптер ControlAdapter) +99 System.Web.UI.Control.RenderControl (модуль записи HtmlTextWriter) +25 System.WildrolInenderContInI(Писатель HtmlTextWriter, дети ICollection) +134 System.Web.UI.Control.RenderChildren (писатель HtmlTextWriter) +19 System.Web.UI.WebControls.WebControl.RenderContents (писатель HtmlTextWriter)) +10 System.Wrolrol.I..Render (писатель HtmlTextWriter) +32 Microsoft.SharePoint.WebPartPages.WebPart.RenderWebPart (выходной HtmlTextWriter) +36 Microsoft.SharePoint.WebPartPages.WebPart.RenderWebPartInternal (HtmlTextWriterPart Writer + WPWPWP9 + WAPW)nder (писатель HtmlTextWriter) +93 System.Web.UI.Control.RenderControlInternal (писатель HtmlTextWriter, адаптер ControlAdapter) +27 System.Web.UI.Control.RenderControl (HtmlTextWriter Writer, адаптер ControlAdapter) +I. System.Web.RenderControl (писатель HtmlTextWriter) +25 Microsoft.SharePoint.WebPartPages.SPChrome.RenderPartContents (вывод HtmlTextWriter, часть WebPart) + 66

Ответы [ 2 ]

1 голос
/ 15 мая 2012

Я использовал эту методологию вместо:

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();

И это сработало.

1 голос
/ 10 июня 2011

Я столкнулся с той же проблемой некоторое время назад.Это может не помочь вам увидеть, что прошло много времени с момента публикации, но это может помочь кому-то еще.

Я предполагаю, что вы уже устранили очевидные ситуации, которые приведут к этой ошибке 401, а именно: в библиотеке стилей xslt нет опубликованной основной версии или нет доступа к странице веб-части, которая тянет xslt подучетная запись пользователя, которая не имеет доступа к библиотеке стилей в первую очередь.Я также предполагаю, что у вас есть среда фермы с по крайней мере одним веб-интерфейсом и отдельным сервером БД для размещения базы данных контента, веб-приложение НЕ включено для анонимного доступа, а схема аутентификации интегрирована в Windows с NTLM (не Kerberos)авторизация и олицетворение включены.

Здесь нам нужно понять, что при вызове oXSLTranform.Load (xsltUrl) из кода веб-части код, который выполняется под учетными данными олицетворенного пользователя, фактически формулируетвнеполосный запрос (запрос не приходит напрямую из браузера) для файла, который находится в базе данных, а не физически на веб-сервере.Если вы посмотрите журнал IIS в веб-интерфейсе, где вы делаете запрос, вы увидите обычный 401.2, за которым следует 401.1 (обычная последовательность запроса-ответа рукопожатия NTLM), но следующий ответ также будет 401.1 вместо ожидаемого200.0, потому что запрос был сделан с пустым заголовком cs-username (вместо ожидаемого олицетворенного имени пользователя).Он пуст, поскольку контекст безопасности этого внеполосного запроса не может быть делегирован (поскольку Kerberos не включен), а также поскольку анонимный доступ также не включен для веб-приложения, в запросе на файл отказано со статусом 401.Чтобы сделать эту работу, вам нужно будет передать явный объект сетевых учетных данных (как в новом NetworkCredential (имя пользователя, пароль, домен)), и это, очевидно, бесполезно.

Вот как я это решил...

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);
}
...