How to use CopyIntoItems to copy files into existing doclib items - web-services

This is my scenario: I need to copy files to a sharepoint document library using its web services and set metadata on them. That's all possible with CopyIntoItems (from Copy webservice) except for Lookup fields. CopyIntoItems ignores them, so i need another way to set data on those fields.
I've tried to create a list item with the mandatory and lookup fields metadata and then, using the item ID (creating a FieldInformation field with the ID, as well as some other simple metadata), called the CopyIntoItems method and, instead of updating the item, sharepoint created a new one.
I can't do this in the reverse order because i have no way to get the ID from the item created by CopyIntoItems...
So, the question is: How can i upload a file to a sharepoint document library and set all its metadata? Including Lookup fields.

Use a regular PUT WebRequest to to upload the document into the library
Query the document library to find the ID of the item you just uploaded (based on path)
Use the Lists.asmx web service to update the document metadata
Helpful link: Uploading files to the SharePoint Document Library and updating any metadata columns

Keep in mind that if the destination folder item count + the ancestor folders item count exceeds the list view threshold then you can't query the list for the id (step 2 from Kit's answer).
Queries can be done more efficiently if constrained to a particular branch in the folder hierarchy. A workaround would be to modify the site settings, but the queries would be sluggish and would make the solution less portable because the threshold for Office365 and BPOS can't be changed.
This explains it much better: http://office.microsoft.com/en-us/office365-sharepoint-online-enterprise-help/create-or-delete-a-folder-in-a-list-or-library-HA102771961.aspx

Related

What strategies can I use in Sitecore to archive items and then restore later via code?

We are building a Sitecore site that will pull in some product data from an external database. On a nightly basis we will query the external database and either Add, Update or Archive/Delete/Remove product content items in Sitecore as needed. Our data template has some fields that will be populated directly from the external database (and will be read-only for content authors) and other fields that they will populate themselves. Included in our custom fields will be the SKU of the item from the external database. It is possible that over time a product could disappear from the external database. In this case we would want Sitecore to somehow remove this item from our list of products, but not completely delete it. The reason for this is that the products that have been removed could reappear in the future and we would not want to lose all of the data that had been added to other custom fields on the item. I can think of a number of different approaches for this:
Use Archiving/Recycling features of Sitecore. When we find that there is a product item in Sitecore that no longer appears in the external database, then we could archive it. That works well. However I can't seem to figure out a way to restore that item later if it reappears in the external database. I don't have any access to any custom fields when an item is archived (from what I have read online). So when I come across a SKU in the external database that is not in Sitecore, I have no way of figuring out if there is an archived item that has that SKU.
Use a custom status field on each product content item. I could set each product content item to "active" or "inactive". This would make it easy to reactivate items that reappear in the external database. However I worry about things like search and publishing. It seems messy to me to have some content items that are inactive in the folder of all products in the master database. It could be confusing to content authors and I worry that they will find their way in to the web database, etc. It seems like I would have to do a lot of custom coding to make sure that those products do not show up on any pages, etc.
When a product disppears from the external database I could then move those content items to a different location in Sitecore. Then when they reappear I could move them back. This also feels messy.
I just wonder if there is some better solution that I am missing. Thanks in advance for any help.
I would go with option 2 "Setting status field on each product "Active" or "Inactive", as its more clear and keep the data in one place.
Additional thing to do (as suggested by Vasiliy) is to set the "Publishable" checkbox on product to "False", this way the product will disappear from web database, hence no extra filter in your search methods.
You can implement custom content editor warning to inform content editor that the current product is "inactive":
Creating Custom Content Editor warnings
Hope this helps
Just a thought what if you just unpublished the items that were removed from the external database and set the ones in the authoring db unpublishable until they reappear again. With this scenario, you could also have a task running archiving items that have been unpublished and not republished for a given period of time.
The best solution really depends on the number and frequency of items appearing / disappearing and the cost benefit of keeping those items in the authoring database vs. deleting them.

sharepoint online list archival

I want to know list archival methords specific to SharePoint Online/O365. I dont think record center will be applicable to SharePoint Online. I see workflow as the only solution to move the items to an archive list, but the problem I see here is I will not be able to update the metadata fields like CreatedBy , etc to the archive list as expected.
Does micorsoft suggent any ways of list item archival?
Any 3rd party tool for the same?
Microsoft suggest a list can hold up to 50 million records, what is the real significance, how does it affect the performance
If archived to a different list how does the workflow associated will get affect or can be handled ?
If you move list items between lists using the "Content and
Structure" tool in Site Settings, the system fields such as created
will be preserved, as the items are moved and not copied.
In-Place record management of list items can be implemented by:
Manual Declaration, Content Type Policies, List Workflows or
Reusable Workflows.
Record Center is used for documents and not list items, but is
available in SharePoint Online.
Lots of pricy third-party solutions.
Haven't seen the 50 million figure, here is a lengthy response to dealing with large lists in SharePoint Online.
4.Reusable Workflows will "handle" being used in multiple lists if configured properly.
Personally, I recommend using content type policies that declare
items in-place as records.

sitecore: Serialization and package designer

I have a large amount of data(content created by user, not developer) created in Sitecore.
I know that in order to transfer large amount of data from one environment to another, I need to serialize all the content first.
My question is, after I serialize the content, do I need to create a designer package that contains the data I want to move? Or after I serialize, I use the serialized file?
Serialization is an option, but you could also create a package through the Package designer, download it and install it on the other environment.
If you are installing big packages, it is a good practice to set the value of Indexing.UpdateInterval in the web.config to 00:00:00 to prevent starting the Lucene indexer during the package install which results in much longer install times.
You don't need to create a package, use the serliazied file and update via the UI as below.
To update an item from the text file:
In the Content Editor, select the item that you want to update.
On the Developer tab, in the Serialize group, click Update Item.
To update an item with all its subitems from the file system:
In the Content Editor, select the parent item that you want to update with all its subitems.
On the Developer tab, in the Serialize group, click Update Tree.
To update the whole database:
In the Content Editor, select any item.
On the Developer tab, in the Serialize group, click Update Database
You can also use the "Transfer Item to Another Database" feature.
Just select the database where you want to go, go to Control Panel, Database, Transfer Item to Another Database.
This will open a wizard. Then you can select the Source items (the items you want to transfer to another database), then select the Target database and select where you want the items to be in the tree (i.e. under Home or some other node).
For some more information you can go to this blogpost by Sam J. Griffin, which explains it step by step.
One very important side-note though - don't copy the /sitecore/templates/sytem if you want to do all templates. This will result in some circular reference issues. If it's just content that you're copying it should be fine.
If you have a spare $149 then you should also take a look at the new Sitecore synchronization tool from Hedgehog:
http://www.hhogdev.com/Products/Razl.aspx

DropLink datasource item reference with custom dataprovider in Sitecore

How do bind a DropLink using a custom dataprovider?
More info:
I am trying to build a product catalogue site using Sitecore. Each product in the sitecore content tree can have a star rating and short text review attached to it (which will be linked to a user extended with a profile provider but that is another question).
I am planning to store the review information in an external database and reference it using a custom dataprovider. I have downloaded the NorthwindDataProvider from the Shared Source (here) and have altered it to use a table which contains the rating, text and a uniqueidentifier field to store the ID of the product from in sitecore the review is attached to.
The template field is a droplink and the datasource is set to the products in the catalogue.
When I edit a review in the custom dataprovider using the sitecore content editor, the droplink states 'Value not in selection list' even if I select one of the populated products and save using sitecore.
It is saving the ID in the database but if I look at the raw value it displays the id without the curly brackets. Working droplink fields' raw values appear to contain the brackets.
To create a review, I am using a jquery post to a webservice which writes to the database using an external datacontext. Should I be using some Sitecore API to use the custom dataprovider instead?
Any information using custom dataproviders would be helpful. The documentation I've been able to find has all stated what can be done but I'm struggling to find actual implementation.
So the first thing is that you have a template field and you're using droplink which is going to store the guid for the item selected. I'm not quite clear on whether or not you're pointing the datasource to a Sitecore item or not.. but that's essential if you're using droplink. Here's what I would suggest instead for the most straight forward way to do this:
Create a template that you add fields to handle the logic dealing with your catalog items. How you do that is your choice and Sitecore doesn't care since its only going to deal with the item and all it cares about is finding an item... you write business logic to manipulate the external data.
Once you have a folder that stores your catalog items, you could easily write a script to be triggered by the Rules engine in Sitecore or a Sitecore task that runs regularly to get your catalog items to add/update or remove the corresponding list of Sitecore items.
Also, another option that is more complex to implement, but if you have multiple data sources on your site, is a valid approach, is to use an object framework (like the Entity framework) as a data object layer that allows you to create and populate common objects with from any data source.
Hope this is helpful!

Is it possible to use SharePoint web services to retrieve all items in a folder with a given ID?

I'm using the GetListItems method of the SharePoint List web service. I would like to get all items in a given folder, with a given ID (not path). The method allows you to pass in QueryOptions xml, which lets you set the Folder path. However, since paths can change, this is not that useful to me, and it would be much better to be able to use the ID of the folder instead.
Does anybody know how to do that?
A workaround - one way you can do it, is to perform two queries - first, to find the folder by its ID (add 'FileLeafRef' to the list of needed fields), then make a recursive query, requiring the items to be in the folder with URL you got in the first cycle.