Adicionar Biblioteca de Documentos XsltListViewWebPart usando CSOM ou serviços da web
-
10-12-2019 - |
Pergunta
Como adicionar uma biblioteca de documentos XsltListViewWebPart (ou peça web vista de lista) na página usando CSOM com SP2013 quando não queremos usar a ver com "Nome", Modificado, Modificado Por" campos?
Listas personalizadas são importados corretamente através de CSOM com este xml, e isso também funciona na importação através de INTERFACE de usuário diretamente, mas não funciona através de CSOM para Bibliotecas de Documentos ou Listas Ligadas, por exemplo:
<?xml version="1.0" encoding="utf-8" ?>
<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
<metaData>
<type name="Microsoft.SharePoint.WebPartPages.XsltListViewWebPart, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
<importErrorMessage>Cannot import this Web Part.</importErrorMessage>
</metaData>
<data>
<properties>
<property name="ListUrl" type="string">Lists/MyList</property>
<property name="XmlDefinition" type="string"><View Name="{ABCDEFGH-ABCD-ABCD-ABCD-ABCDEFGHIJK}" MobileView="TRUE" Type="HTML" Hidden="TRUE" OrderedView="TRUE" DisplayName="" Url="/sites/site/Pages/default.aspx" Level="255" BaseViewID="1" ContentTypeID="0x" ImageUrl="/_layouts/15/images/links.png?rev=23" ><Query><OrderBy><FieldRef Name="Order" Ascending="TRUE"/></OrderBy></Query><ViewFields><FieldRef Name="DocIcon"/><FieldRef Name="Edit"/><FieldRef Name="URLwMenu"/></ViewFields><RowLimit Paged="TRUE">99</RowLimit><JSLink>clienttemplates.js</JSLink><XslLink Default="TRUE">main.xsl</XslLink><Toolbar Type="Standard"/></View></property>
<property name="MissingAssembly" type="string">Cannot import this Web Part.</property>
</properties>
</data>
</webPart>
</webParts>
EDITAR / Solução:
Como Anthony sugeriu que deve primeiro adicionar o XsltListViewWebPart sem especificar o modo de exibição.Adicionar a web part irá automaticamente criar um oculto modo de exibição da lista e link da web part para ele.Atualizando essa visão também vai atualizar a web part.
Solução de exemplo abaixo.
Peça Web xml:
<?xml version="1.0" encoding="utf-8" ?>
<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
<metaData>
<type name="Microsoft.SharePoint.WebPartPages.XsltListViewWebPart, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
<importErrorMessage>Cannot import this Web Part.</importErrorMessage>
</metaData>
<data>
<properties>
<property name="ListUrl" type="string">MyLibrary</property>
<property name="MissingAssembly" type="string">Cannot import this Web Part.</property>
</properties>
</data>
</webPart>
</webParts>
Código:
WebPart importingWebPart = mgr.ImportWebPart(webPartXml).WebPart; // take webPartXml from above
WebPartDefinition wpDefinition = mgr.AddWebPart(importingWebPart, "Top", 1);
mgr.Context.Load(wpDefinition,
d => d.Id); // Id of the hidden view which gets automatically created
mgr.Context.ExecuteQuery();
var viewId = wpDefinition.Id;
List list = web.Lists.GetByTitle("MyLibrary");
View view = list.Views.GetById(viewId);
view.ViewFields.RemoveAll();
view.ViewFields.Add("Title");
view.ViewQuery = "<Where><Eq><FieldRef Name=\"Title\" /><Value Type=\"Text\">Something Here</Value></Eq></Where>";
view.RowLimit = 10;
web.Context.ExecuteQuery();
Solução
Me deparei com isso hoje e encontrou outra solução.
Quando a web part é adicionada à página cria um oculto de vista sobre a lista, é associado.Você pode ficar escondido ver e fazer as alterações diretamente para ela.Isso funciona para anúncios, calendários e doc bibliotecas do que eu testei até agora.
Exemplo:
private static void AddWebPart(Web web, LimitedWebPartManager mgr, string xmlSchema, string listName, string zoneName, int zoneId)
{
WebPartDefinition def = mgr.ImportWebPart(xmlSchema);
mgr.AddWebPart(def.WebPart, zoneName, zoneId);
mgr.Context.ExecuteQuery();
List list = web.Lists.GetByTitle(listName);
web.Context.Load(list.Views);
web.Context.ExecuteQuery();
foreach (View v in list.Views)
{
if (v.Hidden)
{
FixView(v);
}
}
}
private static void FixView(View v)
{
v.ViewFields.RemoveAll();
v.ViewFields.Add("LinkTitle");
v.ViewFields.Add("Description");
v.ViewFields.Add("Location");
v.ViewQuery = "<Where><Eq><FieldRef Name=\"Title\" /><Value Type=\"Text\">Something Here</Value></Eq></Where>";
v.RowLimit = 4;
v.Update();
v.Context.ExecuteQuery();
}
Você provavelmente poderia ler o modo de exibição de campos a partir de seu esquema e encontrar uma boa maneira de aplicá-los, ao invés de incluir codificado como exemplo.
Infelizmente eu não encontrei distância para aplicar um estilo para o modo de exibição (por exemplo,Jornal, box, etc.) que é algo que eu também preciso.
Outras dicas
Eu testei o seu código e posso confirmar o comportamento que você descreveu.
Parece ser um bug onde, não importa o que XmlDefinition você especificar, uma webpart anexado a uma biblioteca de documentos sempre acaba mostrando o padrão de OOB vista (Nome, Modificado, alterado Pelo).
Se fosse o modelo de objeto servidor e, em seguida, seria possível conjurar a webpart para o objeto do tipo XsltListViewWebPart
e alterar os seus ViewGuid
propriedade (ou campos de visão usando a reflexão).
Infelizmente, CSOM não expor subjacente tipos, de modo AFAIK não há nenhuma solução alternativa para superar esse estranho comportamento.
Desde XsltListWebPart.ViewGuid e XsltListWebPart.XmlDefinition propriedades são ignoradas quando adicionar a web part através de CSOM torna impossível especificar modo de exibição personalizado para XsltListWebPart web part.
Solução
Desde o modo de exibição padrão é usado quando a web part provisionado através de CSOM, a solução proposta seria a de modificar o modo de exibição padrão durante web part de aprovisionamento:
- modificar o modo de exibição padrão de propriedades antes de adicionar a web part na página
- adicionar a web part na página
- restaurar o modo de exibição padrão original do estado
Exemplo
using (var ctx = new ClientContext("http://intranet.contoso.com/"))
{
var web = ctx.Web;
var view = GetDefaultView(web,listTitle);
var originalViewFields = view.ViewFields.ToArray();
UpdateViewFields(view,new []{ "LinkTitle","Editor"});
//Add web part on page ()
AddWebPart(ctx.Web, pageUrl, "TopColumnZone", 1, webPartSchemaXml);
//Restore default view
UpdateViewFields(view,originalViewFields);
}
/// <summary>
/// Get default view
/// </summary>
/// <param name="web"></param>
/// <param name="listTitle"></param>
/// <returns></returns>
private static View GetDefaultView(Web web,string listTitle)
{
var list = web.Lists.GetByTitle(listTitle);
var viewQuery = list.Context.LoadQuery(list.Views.Include(v => v.ViewFields, v => v.DefaultView)).Where(v => v.DefaultView);
list.Context.ExecuteQuery();
return viewQuery.FirstOrDefault();
}
/// <summary>
/// Update view fields
/// </summary>
/// <param name="view"></param>
/// <param name="viewFields"></param>
private static void UpdateViewFields(View view,string[] viewFields)
{
view.ViewFields.RemoveAll();
foreach (var viewField in viewFields)
{
view.ViewFields.Add(viewField);
}
view.Update();
view.Context.ExecuteQuery();
}
public static WebPartDefinition AddWebPart(Web web, string pageUrl, string zoneId, int zoneIndex, string webPartXml)
{
var file = web.GetFileByServerRelativeUrl(pageUrl);
var webPartManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
var webPartImportedDef = webPartManager.ImportWebPart(webPartXml);
var webPartDef = webPartManager.AddWebPart(webPartImportedDef.WebPart, zoneId, zoneIndex);
web.Context.Load(webPartDef);
web.Context.ExecuteQuery();
return webPartDef;
}
Se alguém se depara com isso.Eu fiz um post sobre isso :ADICIONAR BIBLIOTECA DE DOCUMENTOS DA WEB PART NO SHAREPOINT 2013 PÁGINA
Conforme solicitado por Phil, eu colocar todos os passo por aqui também.
Passos:
Primeiro adicione a biblioteca de documentos em uma página e salve-o.
Página aberta e editá-lo com o SharePoint Designer, se você não tiver o SharePoint Designer, você pode baixar a página em seu computador e Encontrar a biblioteca de documentos de webpart marcação, e o conjunto de exportMode="Todos" e salve-o.
Agora, abra a página no SharePoint Online e clique em editar.Na Biblioteca de Documentos da web part no canto direito, clique no ícone e você vai ver a opção de exportação de agora.Exportar o XML e salvá-lo.Este é o XML que você vai utilizar para adicionar uma peça web a uma página através de CSOM.Observação o Campo ListID, Você precisa substituir a lista de IDENTIFICAÇÃO de novo ou biblioteca real.Se você não substituem, você vai criar mesma biblioteca em qualquer lugar quando você adicionar este web part com CSOM.
E aqui está o código para obter a Lista de ID para obter uma Lista (Biblioteca de Documentos).
Código para adicionar webpart ou Parte do Aplicativo em uma página do SharePoint.Isso funciona para ambos dependendo XML fornecido.
[WebMethod]
public void AddWebpartSharepointOnline(string siteURL, string pageUrl,string webPartXml,string Title)
{
using (ClientContext clientContext = new ClientContext(siteURL))
{
SecureString passWord = new SecureString();
foreach (char c in sharepointPass.ToCharArray()) passWord.AppendChar(c);
clientContext.Credentials = new SharePointOnlineCredentials(sharepointUser, passWord);
Microsoft.SharePoint.Client.File page = clientContext.Web.GetFileByServerRelativeUrl(pageUrl); /* /NucleonSite/SitePages/Home.aspx */
LimitedWebPartManager wpm = page.GetLimitedWebPartManager(PersonalizationScope.Shared);
WebPartDefinition wpd = wpm.ImportWebPart(webPartXml);
wpd.WebPart.Title = Title;
wpm.AddWebPart(wpd.WebPart, “Right”, 1);
try
{
clientContext.ExecuteQuery();
}
catch { throw; }
}
}
Eu fiz ele para trabalhar em uma Biblioteca de Documentos usando este blog post sugestões.
Basicamente, você só precisa ter uma instância da XsltListViewWebPart
após adicioná-lo, usando um novo WebPartManager e, em seguida, usar a Reflexão para obter o interno ContextView
propriedade:
GetWebPartManagerForPage(web, "SitePages/default.aspx", manager =>
{
var xvl = (from System.Web.UI.WebControls.WebParts.WebPart wp in manager.WebParts
where wp.GetType() == typeof(XsltListViewWebPart)
select wp).FirstOrDefault();
PropertyInfo pi = xvl.GetType().GetProperty("ContextView", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
SPView view = (SPView)(pi.GetValue(xvl, null));
SetXsltListViewFields(view);
manager.SaveChanges(xvl);
});
Em seguida, atualize o modo de exibição para corresponder às suas necessidades (no meu caso, só para ter o doc nome com o link):
public static void SetXsltListViewFields(SPView view)
{
string viewQuery = "<OrderBy><FieldRef Name=\"ID\" /></OrderBy>";
view.Query = viewQuery;
view.ViewFields.DeleteAll();
view.ViewFields.Add("DocIcon");
view.ViewFields.Add("LinkFilename");
view.Paged = true;
view.RowLimit = 10;
view.DefaultView = true;
view.Update();
}
Como parte do meu processo de provisionamento, ele agora está trabalhando bem.