How i can query sharepoint list items using soap in c#?
Code that should query data will be placed on one host (sharepoint 2007, .net 2.0). List located on another host (Sharepoint 2010).
As far as I know, I can not use for this purpose SPSite, SPWeb..
using(SPSite site = new SPSite("http://hostname/...")) {
using(SPWeb web = site.OpenWeb()) {
...
Can anyone give me an example of how this can be done?
Tnx!
To integrate between two different sharepoint instances you have to use the sharepoint web services.
In your project create a web reference to the following url: http://sharepointserver/_vti_bin/lists.asmx
Create a connection to the web service:
var client = new SharePointWebServices.Lists { Credentials = new NetworkCredential("username", "password") };
var xmlDoc = new XmlDocument();
var viewFields = xmlDoc.CreateElement("ViewFields");
viewFields.InnerXml = "<FieldRef Name=\"ows_FIELD YOU WISH TO RETRIEVE\" />";
var listGuid = ConfigurationManager.AppSettings["GUID_OF_LIST"];
XmlNode listItems = client.GetListItems(listGuid, null, null, viewFields,
null, null, null);
Now you have received your collection. simply iterate through the xmlDoc retrieved from the webservice. I do this like this:
foreach (XmlNode node in listItems)
{
if (node.Name == "rs:data")
{
for (int f = 0; f < node.ChildNodes.Count; f++)
{
if (node.ChildNodes[f].Name == "z:row")
{
var xmlAttributeCollection = node.ChildNodes[f].Attributes;
if (xmlAttributeCollection != null)
{
string listItem = xmlAttributeCollection["ows_ows_FIELD YOU WISH TO RETRIEVE"].Value;
}
}
}
}
}
You can use SharePoint soap web services. Or if you are getting data from SharePoint 2010 you can use
its rest api.
Related
I'm after some C# code to recursively enumerate all the folders in a SharePoint web site and list the permissions applying to them to be run from a Sharepoint client machine. Can anyone provide or point me to an example?
The following code can perform this function on a server using SPSite object ( from https://social.msdn.microsoft.com/Forums/sqlserver/en-US/8c7c5735-039e-4cb9-a2b5-58d70a10793f/get-permissions-group-from-folders-tree-view-on-a-doc-library?forum=sharepointdevelopmentprevious) but I need to run it using SharePoint Client code
public static void getPermissionsOfFolders()
{
using (SPSite site = new SPSite("http://sp"))
{
using (SPWeb web = site.RootWeb)
{
SPList list = web.GetList("/Lists/List2");
foreach (SPListItem item in list.Folders)
{
Console.WriteLine("ID: "+item["ID"]+"--"+item.SortType);
if (SPFileSystemObjectType.Folder == item.SortType)
{
SPRoleAssignmentCollection roles = item.RoleAssignments;
foreach (SPRoleAssignment role in roles)
{
Console.WriteLine("~");
Console.WriteLine("Name: "+role.Member.Name);
SPRoleDefinitionBindingCollection bindings = role.RoleDefinitionBindings;
XmlDocument doc = new XmlDocument();
doc.LoadXml(bindings.Xml);
XmlNodeList itemList = doc.DocumentElement.SelectNodes("Role");
foreach (XmlNode currNode in itemList)
{
string s = currNode.Attributes["Name"].Value.ToString();
Console.WriteLine("Permission Level: "+s);
}
}
Console.WriteLine("--------------------------------------");
}
}
}
}
}
Code below fails with exception "Property ListItemAllFields not found" as shown below on clientContext.ExecuteQuery()
private void ListSPPermissions3()
{
string sSite = "http://server2012a/sites/TestDocs/";
using (var clientContext = new ClientContext(sSite))
{
Site site = clientContext.Site;
Web web = clientContext.Web;
List list = web.Lists.GetByTitle("Shared Documents");
clientContext.Load(list.RootFolder.Folders); //load the client object list.RootFolder.Folders
clientContext.ExecuteQuery();
int FolderCount = list.RootFolder.Folders.Count;
foreach (Microsoft.SharePoint.Client.Folder folder in list.RootFolder.Folders)
{
RoleAssignmentCollection roleAssCol = folder.ListItemAllFields.RoleAssignments;
clientContext.Load(roleAssCol);
clientContext.ExecuteQuery(); // Exception property ListItemAllFields not found
foreach (RoleAssignment roleAss in roleAssCol)
{
Console.WriteLine(roleAss.Member.Title);
}
}
}
}
There are at least the following flaws with your example:
The specified example only allows to retrieve folders one level
beneath:
clientContext.Load(list.RootFolder.Folders); //load the client object list.RootFolder.Folders
clientContext.ExecuteQuery();
Role assignments could be retrieved using a single request to the
server (see the below example), hence there is no need to perform
multiple requests to retrieve role assignments per folder.
Folder.ListItemAllFields property is supported only in SharePoint
2013 CSOM API
Having said that i would recommend to consider the following example to enumerate folder permissions:
using (var ctx = new ClientContext(webUri))
{
var list = ctx.Web.Lists.GetByTitle(listTitle);
var items = list.GetItems(CamlQuery.CreateAllFoldersQuery());
ctx.Load(items, icol => icol.Include(i => i.RoleAssignments.Include( ra => ra.Member), i => i.DisplayName ));
ctx.ExecuteQuery();
foreach (var item in items)
{
Console.WriteLine("{0} folder permissions",item.DisplayName);
foreach (var assignment in item.RoleAssignments)
{
Console.WriteLine(assignment.Member.Title);
}
}
}
The error is probably because the SharePoint SDK you are using is pre-SharePoint 2013 CSOM.
Folder.ListItemAllFields
property is available in SharePoint 2013 CSOM
For SharePoint 2010, you have to access folders like list items
ListItem item = context.Web.Lists.GetByTitle("Shared Documents").GetItemById(<item ID>);
and then get the RoleAssignments for the items.
I have a SharePoint List to which I'm adding new ListItems using the Client Object Model.
Adding ListItems is not a problem and works great.
Now I want to add attachments.
I'm using the SaveBinaryDirect in the following manner:
File.SaveBinaryDirect(clientCtx, url.AbsolutePath + "/Attachments/31/" + fileName, inputStream, true);
It works without any problem as long as the item that I'm trying to add the attachment to, already has an attachment that was added through the SharePoint site and not using the Client Object Model.
When I try to add an attachment to a item that doesnt have any attachments yet, I get the following errors (both happen but not with the same files - but those two messages appear consistently):
The remote server returned an error: (409) Conflict
The remote server returned an error: (404) Not Found
I figured that maybe I need to create the attachment folder first for this item.
When I try the following code:
clientCtx.Load(ticketList.RootFolder.Folders);
clientCtx.ExecuteQuery();
clientCtx.Load(ticketList.RootFolder.Folders[1]); // 1 -> Attachment folder
clientCtx.Load(ticketList.RootFolder.Folders[1].Folders);
clientCtx.ExecuteQuery();
Folder folder = ticketList.RootFolder.Folders[1].Folders.Add("33");
clientCtx.ExecuteQuery();
I receive an error message saying:
Cannot create folder "Lists/Ticket System/Attachment/33"
I have full administrator rights for the SharePoint site/list.
Any ideas what I could be doing wrong?
Thanks, Thorben
I struggled for a long time with this problem too, so I thought I'd post a complete code sample showing how to successfully create a list item and add an attachment.
I am using the Client Object API to create the list item, and the SOAP web service to add the attachment. This is because, as noted in other places on the web, the Client Object API can only be used to add attachments to an item where the item's upload directory already exists (eg. if the item already has an attachment). Else it fails with a 409 error or something. The SOAP web service copes with this OK though.
Note that another thing I had to overcome was that even though I added the SOAP reference using the following URL:
https://my.sharepoint.installation/personal/test/_vti_bin/lists.asmx
The URL that VS actually added to the app.config was:
https://my.sharepoint.installation/_vti_bin/lists.asmx
I had to manually change the app.config back to the correct URL, else I would get the error:
List does not exist.
The page you selected contains a list that does not exist. It may have been deleted by another user.
0x82000006
Here is the code:
void CreateWithAttachment()
{
const string listName = "MyListName";
// set up our credentials
var credentials = new NetworkCredential("username", "password", "domain");
// create a soap client
var soapClient = new ListsService.Lists();
soapClient.Credentials = credentials;
// create a client context
var clientContext = new Microsoft.SharePoint.Client.ClientContext("https://my.sharepoint.installation/personal/test");
clientContext.Credentials = credentials;
// create a list item
var list = clientContext.Web.Lists.GetByTitle(listName);
var itemCreateInfo = new ListItemCreationInformation();
var newItem = list.AddItem(itemCreateInfo);
// set its properties
newItem["Title"] = "Created from Client API";
newItem["Status"] = "New";
newItem["_Comments"] = "here are some comments!!";
// commit it
newItem.Update();
clientContext.ExecuteQuery();
// load back the created item so its ID field is available for use below
clientContext.Load(newItem);
clientContext.ExecuteQuery();
// use the soap client to add the attachment
const string path = #"c:\temp\test.txt";
soapClient.AddAttachment(listName, newItem["ID"].ToString(), Path.GetFileName(path),
System.IO.File.ReadAllBytes(path));
}
Hope this helps someone.
I have discussed this question with Microsoft. Looks like that only one way to create attachments remotely is List.asmx web service. I have tried to create this subfolder also and with no success.
With Sharepoint 2010 there was no way to upload a first attachment to a list item using the COM. The recommendation was to use the Lists web service inmstead.
With Sharepoint 2013 it works.
AttachmentCreationInformation newAtt = new AttachmentCreationInformation();
newAtt.FileName = "myAttachment.txt";
// create a file stream
string fileContent = "This file is was ubloaded by client object meodel ";
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
byte[] buffer = enc.GetBytes(fileContent);
newAtt.ContentStream = new MemoryStream(buffer);
// att new item or get existing one
ListItem itm = list.GetItemById(itemId);
ctx.Load(itm);
// do not execute query, otherwise a "version conflict" exception is rised, but the file is uploaded
// add file to attachment collection
newAtt.ContentStream = new MemoryStream(buffer);
itm.AttachmentFiles.Add(newAtt);
AttachmentCollection attachments = itm.AttachmentFiles;
ctx.Load(attachments);
ctx.ExecuteQuery();
// see all attachments for list item
// this snippet works if the list item has no attachments
This method is used in http://www.mailtosharepoint.net/
It reflects rather poorly on the Microsoft SharePoint team for not coming forward with an acknowledgement of the issue and a usable suggestion on how to resolve it. Here is how I dealt with it:
I am using the new SharePoint 2010 managed client that ships with the product. Hence, I already have a SharePoint ClientContext with credentials. The following function adds an attachment to a list item:
private void SharePoint2010AddAttachment(ClientContext ctx,
string listName, string itemId,
string fileName, byte[] fileContent)
{
var listsSvc = new sp2010.Lists();
listsSvc.Credentials = _sharePointCtx.Credentials;
listsSvc.Url = _sharePointCtx.Web.Context.Url + "_vti_bin/Lists.asmx";
listsSvc.AddAttachment(listName, itemId, fileName, fileContent);
}
The only prerequisite for the code above is to add to the project (I used Visual Studio 2008) a _web_reference_ I called sp2010 which is created from the URL of: http:///_vti_bin/Lists.asmx
Bon Chance...
HTML:
<asp:FileUpload ID="FileUpload1" runat="server" AllowMultiple="true" />
Event in code behind :
protected void UploadMultipleFiles(object sender, EventArgs e)
{
Common.UploadDocuments(Common.getContext(new Uri(Request.QueryString["SPHostUrl"]),
Request.LogonUserIdentity), FileUpload1.PostedFiles, new CustomerRequirement(), 5);
}
public static List<string> UploadDocuments<T>(ClientContext ctx,IList<HttpPostedFile> selectedFiles, T reqObj, int itemID)
{
List<Attachment> existingFiles = null;
List<string> processedFiles = null;
List<string> unProcessedFiles = null;
ListItem item = null;
FileStream sr = null;
AttachmentCollection attachments = null;
byte[] contents = null;
try
{
existingFiles = new List<Attachment>();
processedFiles = new List<string>();
unProcessedFiles = new List<string>();
//Get the existing item
item = ctx.Web.Lists.GetByTitle(typeof(T).Name).GetItemById(itemID);
//get the Existing attached attachments
attachments = item.AttachmentFiles;
ctx.Load(attachments);
ctx.ExecuteQuery();
//adding into the new List
foreach (Attachment att in attachments)
existingFiles.Add(att);
//For each Files which user has selected
foreach (HttpPostedFile postedFile in selectedFiles)
{
string fileName = Path.GetFileName(postedFile.FileName);
//If selected file not exist in existing item attachment
if (!existingFiles.Any(x => x.FileName == fileName))
{
//Added to Process List
processedFiles.Add(postedFile.FileName);
}
else
unProcessedFiles.Add(fileName);
}
//Foreach process item add it as an attachment
foreach (string path in processedFiles)
{
sr = new FileStream(path, FileMode.Open);
contents = new byte[sr.Length];
sr.Read(contents, 0, (int)sr.Length);
var attInfo = new AttachmentCreationInformation();
attInfo.FileName = Path.GetFileName(path);
attInfo.ContentStream = sr;
item.AttachmentFiles.Add(attInfo);
item.Update();
}
ctx.ExecuteQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
existingFiles = null;
processedFiles = null;
item = null;
sr = null;
attachments = null;
contents = null;
ctx = null;
}
return unProcessedFiles;
}
I've used and tried this one on my CSOM (SharePoint Client Object Model) application and it works for me
using (ClientContext context = new ClientContext("http://spsite2010"))
{
context.Credentials = new NetworkCredential("admin", "password");
Web oWeb = context.Web;
List list = context.Web.Lists.GetByTitle("Tasks");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View><Where><Eq><FieldRef Name = \"Title\"/><Value Type=\"String\">New Task Created</Value></Eq></Where></View>";
ListItemCollection listItems = list.GetItems(query);
context.Load(listItems);
context.ExecuteQuery();
FileStream oFileStream = new FileStream(#"C:\\sample.txt", FileMode.Open);
string attachmentpath = "/Lists/Tasks/Attachments/" + listItems[listItems.Count - 1].Id + "/sample.txt";
Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, attachmentpath, oFileStream, true);
}
Note: Only works if item folder has been created already
I am trying to access list of all Sites and Lists from Sharepoint 2007 using c#.
I am able to get Name of sites and list.
But unable to get folders and subfolders of particular list.
And Document uploaded in particular Folder.
I am using Web Services (no dependency of Microsoft.Sharepoint.dll)
Regards,
Jene
Try this:
using(SPSite site = new SPSite("http://yoursite"))
using(SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["your_doclib"];
SPQuery query = new SPQuery()
{
Query = "",
ViewAttributes = #"Scope=""RecursiveAll"""
};
SPListItemCollection itens = list.GetItems(query);
foreach (SPListItem item in itens)
{
Console.ForegroundColor =
item.FileSystemObjectType == SPFileSystemObjectType.Folder ?
ConsoleColor.White : ConsoleColor.Gray;
Console.WriteLine("{0}", item.Name);
}
}
I am really looking for either a small code snippet.
I have a C# console app that I will use to somehow add list items to my custom list. I have created a custom content type too. So not sure if I need to create an C# class from this content type too. Perhaps not.
I think these both blog post should help you solving your problem.
http://blog.the-dargans.co.uk/2007/04/programmatically-adding-items-to.html
http://asadewa.wordpress.com/2007/11/19/adding-a-custom-content-type-specific-item-on-a-sharepoint-list/
Short walk through:
Get a instance of the list you want to add the item to.
Add a new item to the list:
SPListItem newItem = list.AddItem();
To bind you new item to a content type you have to set the content type id for the new item:
newItem["ContentTypeId"] = <Id of the content type>;
Set the fields specified within your content type.
Commit your changes:
newItem.Update();
To put it simple you will need to follow the step.
You need to reference the Microsoft.SharePoint.dll to the application.
Assuming the List Name is Test and it has only one Field "Title" here is the code.
using (SPSite oSite=new SPSite("http://mysharepoint"))
{
using (SPWeb oWeb=oSite.RootWeb)
{
SPList oList = oWeb.Lists["Test"];
SPListItem oSPListItem = oList.Items.Add();
oSPListItem["Title"] = "Hello SharePoint";
oSPListItem.Update();
}
}
Note that you need to run this application in the Same server where the SharePoint is installed.
You dont need to create a Custom Class for Custom Content Type
You can create an item in your custom SharePoint list doing something like this:
using (SPSite site = new SPSite("http://sharepoint"))
{
using (SPWeb web = site.RootWeb)
{
SPList list = web.Lists["My List"];
SPListItem listItem = list.AddItem();
listItem["Title"] = "The Title";
listItem["CustomColumn"] = "I am custom";
listItem.Update();
}
}
Using list.AddItem() should save the lists items being enumerated.
This is how it was on the Microsoft site, with me just tweaking the SPSite and SPWeb since these might vary from environment to environment and it helps not to have to hard-code these:
using (SPSite oSiteCollection = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb oWeb = oSiteCollection.OpenWeb(SPContext.Current.Web))
{
SPList oList = oWeb.Lists["Announcements"];
// You may also use
// SPList oList = oWeb.GetList("/Lists/Announcements");
// to avoid querying all of the sites' lists
SPListItem oListItem = oList.Items.Add();
oListItem["Title"] = "My Item";
oListItem["Created"] = new DateTime(2004, 1, 23);
oListItem["Modified"] = new DateTime(2005, 10, 1);
oListItem["Author"] = 3;
oListItem["Editor"] = 3;
oListItem.Update();
}
}
Source:
SPListItemClass (Microsoft.SharePoint). (2012). Retrieved February 22, 2012, from http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistitem.aspx.
I had a similar problem and was able to solve it by following the below approach (similar to other answers but needed credentials too),
1- add Microsoft.SharePointOnline.CSOM by tools->NuGet Package Manager->Manage NuGet Packages for solution->Browse-> select and install
2- Add "using Microsoft.SharePoint.Client; "
then the below code
string siteUrl = "https://yourcompany.sharepoint.com/sites/Yoursite";
SecureString passWord = new SecureString();
var password = "Your password here";
var securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
ClientContext clientContext = new ClientContext(siteUrl);
clientContext.Credentials = new SharePointOnlineCredentials("Username#domain.nz", securePassword);/*passWord*/
List oList = clientContext.Web.Lists.GetByTitle("The name of your list here");
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem oListItem = oList.AddItem(itemCreateInfo);
oListItem["PK"] = "1";
oListItem["Precinct"] = "Mangere";
oListItem["Title"] = "Innovation";
oListItem["Project_x0020_Name"] = "test from C#";
oListItem["Project_x0020_ID"] = "ID_123_from C#";
oListItem["Project_x0020_start_x0020_date"] = "2020-05-01 01:01:01";
oListItem.Update();
clientContext.ExecuteQuery();
Remember that your fields may be different with what you see, for example in my list I see "Project Name", while the actual value is "Project_x0020_ID". How to get these values (i.e. internal filed values)?
A few approaches:
1- Use MS flow and see them
2- https://mstechtalk.com/check-column-internal-name-sharepoint-list/ or https://sharepoint.stackexchange.com/questions/787/finding-the-internal-name-and-display-name-for-a-list-column
3- Use a C# reader and read your sharepoint list
The rest of operations (update/delete):
https://learn.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ee539976(v%3Doffice.14)
I have items in a list in a SharePoint 2003 site that I need to add to an existing list in a 2007 site. The items have attachments.
How can this be accomplished using PowerShell or C#?
I ended up using a C# program in conjunction with the SharePoint web services to accomplish this. I also used the extension methods (GetXElement, GetXmlNode) on Eric White's blog here to convert between XMLNodes and XElements which made the XML from SharePoint easier to work with.
Below is a template for most of the code needed to transfer list data, including attachments, from one SharePoint List (either 2003 or 2007) to another one:
1) This is the code moves attachments after a new item has been added to the target list.
// Adds attachments from a list item in one SharePoint server to a list item in another SharePoint server.
// addResults is the return value from a lists.UpdateListItems call.
private void AddAttachments(XElement addResults, XElement listItem)
{
XElement itemElements = _listsService2003.GetAttachmentCollection(_listNameGuid, GetListItemIDString(listItem)).GetXElement();
XNamespace s = "http://schemas.microsoft.com/sharepoint/soap/";
var items = from i in itemElements.Elements(s + "Attachment")
select new { File = i.Value };
WebClient Client = new WebClient();
Client.Credentials = new NetworkCredential("user", "password", "domain");
// Pull each attachment file from old site list and upload it to the new site list.
foreach (var item in items)
{
byte[] data = Client.DownloadData(item.File);
string fileName = Path.GetFileName(item.File);
string id = GetID(addResults);
_listsService2007.AddAttachment(_newListNameGuid, id, fileName, data);
}
}
2) Code that iterates through the old SharePoint List and populates the new one.
private void TransferListItems()
{
XElement listItems = _listsService2003.GetListItems(_listNameGuid, _viewNameGuid, null, null, "", null).GetXElement();
XNamespace z = "#RowsetSchema";
foreach (XElement listItem in listItems.Descendants(z + "row"))
{
AddNewListItem(listItem);
}
}
private void AddNewListItem(XElement listItem)
{
// SharePoint XML for adding new list item.
XElement newItem = new XElement("Batch",
new XAttribute("OnError", "Return"),
new XAttribute("ListVersion", "1"),
new XElement("Method",
new XAttribute("ID", "1"),
new XAttribute("Cmd", "New")));
// Populate fields from old list to new list mapping different field names as necessary.
PopulateFields(newItem, listItem);
XElement addResults = _listsService2007.UpdateListItems(_newListNameGuid, newItem.GetXmlNode()).GetXElement();
// Address attachements.
if (HasAttachments(listItem))
{
AddAttachments(addResults, listItem);
}
}
private static bool HasAttachments(XElement listItem)
{
XAttribute attachments = listItem.Attribute("ows_Attachments");
if (System.Convert.ToInt32(attachments.Value) != 0)
return true;
return false;
}
3) Miscellaneous support code for this sample.
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Net;
using System.IO;
// This method uses an map List<FieldMap> created from an XML file to map fields in the
// 2003 SharePoint list to the new 2007 SharePoint list.
private object PopulateFields(XElement batchItem, XElement listItem)
{
foreach (FieldMap mapItem in FieldMaps)
{
if (listItem.Attribute(mapItem.OldField) != null)
{
batchItem.Element("Method").Add(new XElement("Field",
new XAttribute("Name", mapItem.NewField),
listItem.Attribute(mapItem.OldField).Value));
}
}
return listItem;
}
private static string GetID(XElement elem)
{
XNamespace z = "#RowsetSchema";
XElement temp = elem.Descendants(z + "row").First();
return temp.Attribute("ows_ID").Value;
}
private static string GetListItemIDString(XElement listItem)
{
XAttribute field = listItem.Attribute("ows_ID");
return field.Value;
}
private void SetupServices()
{
_listsService2003 = new SPLists2003.Lists();
_listsService2003.Url = "http://oldsite/_vti_bin/Lists.asmx";
_listsService2003.Credentials = new System.Net.NetworkCredential("username", "password", "domain");
_listsService2007 = new SPLists2007.Lists();
_listsService2007.Url = "http://newsite/_vti_bin/Lists.asmx";
_listsService2007.Credentials = new System.Net.NetworkCredential("username", "password", "domain");
}
private string _listNameGuid = "SomeGuid"; // Unique ID for the old SharePoint List.
private string _viewNameGuid = "SomeGuid"; // Unique ID for the old SharePoint View that has all the fields needed.
private string _newListNameGuid = "SomeGuid"; // Unique ID for the new SharePoint List (target).
private SPLists2003.Lists _listsService2003; // WebService reference for the old SharePoint site (2003 or 2007 is fine).
private SPLists2007.Lists _listsService2007; // WebService reference for the new SharePoint site.
private List<FieldMap> FieldMaps; // Used to map the old list to the new list. Populated with a support function on startup.
class FieldMap
{
public string OldField { get; set; }
public string OldType { get; set; }
public string NewField { get; set; }
public string NewType { get; set; }
}
I'd probably try implementing something with the web services - I know that for 2007 the attachment urls show up in the ows_Attachements attribute, and once you have that you can do a fairly standard download/upload. It's been a while since I did anything with 2003, but I don't think that's a new field.
If you have trouble getting the right data from 2003, you could always migrate the entire site to 2007 and then extract the data you want using the latest API.
Have you tried saving the list ("with content") as a template, save that file to the 2007 portal templates, then create a new list using that "custom" template? That won't work if the attachments and items total more than 10MB, and I'm not 100% sure that that'll work for 2003 > 2007. It should take < 10 minutes, so it's worth a try if you haven't already.
I had to create this project: http://sourceforge.net/projects/splistcp for a similar task, but in order to keep the modified and created time and user I had to use the local API on the destination. The benefit of your approach seems to be easier support for both 2003 and 2007 as the source.