Я столкнулся с той же проблемой некоторое время назад.Это может не помочь вам увидеть, что прошло много времени с момента публикации, но это может помочь кому-то еще.
Я предполагаю, что вы уже устранили очевидные ситуации, которые приведут к этой ошибке 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);
}