SaveBinaryDirect arroja datos no autorizados cuando el modelo de objetos del cliente funciona bien

sharepoint.stackexchange https://sharepoint.stackexchange.com//questions/70562

Pregunta

He decidido utilizar el método SaveBinaryDirect para cargar documentos en el sitio de SharePoint debido a que no tengo las limitaciones de tamaño de solicitud/archivo que tiene el modelo de objetos del cliente.

La aplicación hace dos cosas: agrega una carpeta (usando el modelo de objetos del Cliente) y luego carga un archivo seleccionado en la carpeta que acaba de crear (usando Save Binary Direct).

Esto funciona bien en mi configuración aquí.pero en el sitio de nuestros clientes la carpeta se crea bien pero la parte de carga del archivo devuelve el error "401 no autorizado".

            SP.ClientContext ctx = new SP.ClientContext(siteurl);
            SP.Web currentWeb = ctx.Web;
            //Pass user details from config (That has owner permissions)
            ctx.Credentials = new NetworkCredential(username, password, domain);   
            //create folder method (checks if the folder exists and creates using Client Object Model)
            CreateFolder(ctx,libraryUrl,folderName)

            //Save Binary Direct Method
            string fileUrl = "/"+ libraryname + "/" + folderName + "/" + fileName;
            using (data)
            {
                //upload by passing the context, file url, file data stream, 
                //set overwrite to true
                SP.File.SaveBinaryDirect(ctx, fileUrl,data, true);
            }

Esto me hace pensar en una de dos cosas.

  1. Hay una configuración que debe cambiarse en el punto compartido o en el servidor web con respecto a la autorización/autenticación.
  2. La forma en que aplico las credenciales de red es incorrecta.ya que solo lo hace para el modelo de objetos del cliente pero no para guardar el binario directo.

Soy consciente de que podemos utilizar el modelo de objetos del cliente y es posible que necesitemos realizar otra versión si no se trata de un problema de configuración.

¿Alguien con más experiencia con esto tiene algunas ideas sobre por qué se hace esto?

¿Fue útil?

Solución

Si está utilizando SharePoint 2013, no puede usar SaveBinaryDirect, no funciona con la autenticación de reclamaciones.La llamada hecha por SaveBinaryDirect no incluye las cookies de autorización requeridas.Los detalles se discuten en los comentarios de esta publicación del blog: Cómo realizar la autenticación activa a Office 365 y SharePoint Online

update (2 de julio de 2016):

Tomé otra mirada a esto después de ver el comentario de James Love.No estoy seguro de qué cambió, pero mi prueba indica que SaveBinaryDirect ahora está trabajando con SharePoint 2013 y SharePoint Online.

Aquí está el código que utilicé:

// var context = new ClientContext("http://intranet.wingtip.com/sites/demo/");
// context.Credentials = System.Net.CredentialCache.DefaultCredentials;

var context = new ClientContext("https://robwindsor2.sharepoint.com/sites/demo/");
context.Credentials = new SharePointOnlineCredentials(loginName, securePassword);

var web = context.Web;
var lib = web.Lists.GetByTitle("Documents");

context.Load(lib);
context.Load(lib.RootFolder);
context.ExecuteQuery();

var fileName = "Test.docx";
var filePath = @"C:\Users\robwindsor\Desktop\" + fileName;
using (var fs = new FileStream(filePath, FileMode.Open))
{
    Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, lib.RootFolder.ServerRelativeUrl + "/" + fileName, fs, true);
}

var query = new CamlQuery();
query.ViewXml = "<View></View>";
var files = lib.GetItems(query);

context.Load(files, c => c.Include(f => f.File));
context.ExecuteQuery();

foreach(ListItem item in files)
{
    Console.WriteLine(item.File.Name);
}

Console.WriteLine("Done");        

Otros consejos

Intenta esto:

FileCreationInformation fci = new FileCreationInformation();

fci.Content = newFile.Bytes;

fci.Url = sourceFile.Url;

fci.Overwrite = true;

Microsoft.SharePoint.Client.File replacedFile = list.RootFolder.Files.Add(fci);

context.Load(replacedFile);

context.ExecuteQuery();

Soy capaz de cargar el archivo del sistema de archivos a SharePoint 2010 usando el modelo de objeto cliente.

Si no está autorizado 401, asegúrese de que está proporcionando las credenciales correctas y la correcta URL relativa de la carpeta de biblioteca de documentos de Target SharePoint.

ClientContext ctx = new ClientContext(Siteurl);
ctx.Credentials = new System.Net.NetworkCredential("username", "password", "domain");
var sourceFilePath = @"C:\test\test.xlsx";
var targetUrl = "/Shared%20Documents";
var targetFileUrl = String.Format("{0}/{1}", targetUrl, Path.GetFileName(sourceFilePath));
var fs = new FileStream(sourceFilePath, FileMode.Open);
Microsoft.SharePoint.Client.File.SaveBinaryDirect(ctx, targetFileUrl, fs, true);
var uploadedFile = ctx.Web.GetFileByServerRelativeUrl(targetFileUrl);
var listItem = uploadedFile.ListItemAllFields;
listItem.Update();
ctx.ExecuteQuery();

Creo que debes agregar esto:

ctx.RequestTimeout = 3600000;

Me encontré con el mismo problema, y encontré una solución aunque no sé si es legítimo.

 System.Net.WebClient webClient = new System.Net.WebClient();

 System.Uri uri = new Uri(url); //Create a uri object with the file name but without extension

 webClient.Credentials = new NetworkCredential(username,password,domain);        //Network credentials to connect with the sharepoint server

 webClient.UploadFile(uri, "PUT", pFilePath);     //Upload File will push the file to the server

TLDR:necesitas usar el servidor URL relativa, aunque el contexto incluya la información del sitio.

Tuve el mismo problema y lo resolví usando Fiddler.Cuando utilicé el modelo de objetos del cliente, creé el contexto con la ruta del sitio, es decir."https://servidor/sitios/nombredelsitio", entonces

var docs = web.Lists.GetByTitle(documentLibraryName);
SP.File uploadFile = docs.RootFolder.Files.Add(newFile);
context.Load(uploadFile);
context.ExecuteQuery();

Esto resultó en un POST para https://<server>/sites/<siteName>/_vti_bin/client.svc/ProcessQueryla ruta y el nombre del archivo (y el contenido) fueron incrustados en el XML por el CSOM.

Ahora el SP.File.SaveBinaryDirect la firma es SaveBinaryDirect(ClientContext context, string serverRelativeUrl, Stream stream, bool overwriteIfExists) -- pero la petición SaveBinaryDirect(context, "/<library>/<folder>/filename", stream, true) falló con un error 401.Busque en Fiddler y aquí está la solicitud realizada:

PUT https://<server>/<library>/<filename>

Aunque el contexto incluye el sitio, tienes que darle la camino completo desde la raíz del servidor.La llamada exitosa fue

SaveBinaryDirect(context, "/sites/<sitename>/<library>/<folder>/filename", stream, true)

y eso da como resultado un PUT en la ubicación correcta.El parámetro es llamado serverRelativeUrl después de todo.

Licenciado bajo: CC-BY-SA con atribución
scroll top