Not so long time ago I had a task to import messages from our NNTP Server to a sharepoint list. Importing itself is not difficult procedure - the problem is that then it is using a standard wss object model it substitutes process credentials instead of the credentials of the message author. As a result after importing - all messages has the same author, and, obviously it's not the thing that I was looking for. Below is example, the c# procedure which first I tried to use -
private void AddListMessage(SPWeb web, string listName, string messageTitle, string messageBody, Attachment[] attachments)
{
SPListItem item = web.Lists[listName].Items.Add();
item["Subject"] = messageTitle;
item["Text"] = messageBody;
item["Author"] = "Domain\user"; <- doing like this is useless, parameter will be ignored
foreach (Attachment attachment in attachments)
{
item.Attachments.Add(attachment.Filename, attachment.BinaryData);
}
item.Update();
}
To solve my problem I created another c# procedure which uses lists.asmx web service to post messages together with windows impersonation and few lines of CAML. Of course write permissions should be granted to user before it can start posting to the wss list. IIS must be configured to use integrated windows authentication. On my test machine I have Sharepoint running web site with basic + ssl authetication on port 80 and the same site with windows authentication on port 82 which I use to access wss web services and inject messages to the lists.
private
void AddListMessage2(SPWeb web,
string listName,
string messageTitle,
string messageBody,
string Author, Attachment[] attachments)
{
string listGUID = web.Lists[listName].ID.ToString();
if (web.Name == String.Empty)
{
ls.Url = "http://localhost:82/_vti_bin/lists.asmx";
}
else
{
ls.Url = "http://localhost:82/" + web.Name + "/_vti_bin/lists.asmx";
}
// Create an XmlDocument object and construct a Batch element and its attributes.
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
// Create Batch element
System.Xml.XmlElement batchElement = doc.CreateElement("Batch");
batchElement.SetAttribute("OnError", "Continue");
batchElement.SetAttribute("ListVersion", "1");
batchElement.SetAttribute("ViewName", String.Empty);
batchElement.InnerXml = "<Method Id='1' Cmd='New'><Field Name='Title'><[!CDATA[" + messageTitle + "]]></Field>" +
"<Field Name='Body'><[!CDATA[" + messageBody + "]]></Field></Method>";
// Impersonating user <- this will work only with windows 2003 Server
WindowsIdentity wi = new WindowsIdentity(Author); <- credentials should be passed as user@domian.com
WindowsImpersonationContext ctx = wi.Impersonate();
// Updating list
ls.Credentials = System.Net.CredentialCache.DefaultCredentials;
System.Xml.XmlNode node;
try
{
node = ls.UpdateListItems(listGUID, batchElement);
// Adding an attachment
foreach (Attachment attachment in attachments)
{
ls.AddAttachment(listGUID, node.SelectSingleNode("//@ows_ID").Value,
attachment.Filename, attachment.BinaryData);
}
}
finally
{
ctx. Undo();
}
}