views:

730

answers:

2

Because Microsoft did not include a way to have unique constraints in sharepoint, this has to be done manually.

I am inserting items into a sharepoint list via a web service method.

How can I check if an existing list item already exists with the same field ID value?

I've learnt I should be using wsLists.getListitems web service method, but its not exactly "user friendly". MSDN documentation is again not really great at explaining what should be an easy thing to do.

+2  A: 

Here's a procedure I wrote 2 years ago that pulls the ID of a document with a given filename... I think you could easily revise it to return true/false if a given ID exists in a list.

protected string GetDocumentID(Lists.Lists ls, string ListGUID, string FileName)
{
    string strDocumentID = "-1";

    string strViewGUID = "";
    string strRowLimit = "50000";

    XmlDocument xmlDoc = new XmlDocument();
    XmlNode query = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");
    XmlNode viewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");
    XmlNode queryOptions = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions", "");

    query.InnerXml = "";
    viewFields.InnerXml = "";
    queryOptions.InnerXml = "<IncludeAttachmentUrls>TRUE</IncludeAttachmentUrls>";

    System.Xml.XmlNode nodeListItems = ls.GetListItems(ListGUID, strViewGUID, query, viewFields, strRowLimit, queryOptions, null);

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(nodeListItems.InnerXml);
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
    nsmgr.AddNamespace("z", "#RowsetSchema");
    nsmgr.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");

    foreach (XmlNode node in doc.SelectNodes("/rs:data/z:row", nsmgr))
    {
     if (node.Attributes["ows_LinkFilename"].Value == FileName)
     {
      strDocumentID = node.Attributes["ows_ID"].Value;
      break;
     }
    }

    return strDocumentID;
}

Here's the code that calls it...

Lists.Lists ls = new Lists.Lists();
ls.PreAuthenticate = true;
ls.Credentials = System.Net.CredentialCache.DefaultCredentials;
ls.Url = SharePointSiteURL + @"/_vti_bin/lists.asmx";

string DocID = GetDocumentID(ls, ListGUID, FileName);
Mayo
+1 for effort of a usable code block. I got it working will post another easier way
JL
I figured there was a way to be cleaner with XML but the project was rushed beyond reason and it was a one-time deal (copy data from non-SharePoint repository to SharePoint) - this was a "make it work" effort. :)
Mayo
+4  A: 
private bool itemDoesntExist()
{
    XmlDocument doc = new XmlDocument();
    doc.LoadXml("<Document><Query><Where><Contains><FieldRef Name=\"ID\" /><Value Type=\"Text\">" + this.ID  + "</Value></Contains></Where></Query><ViewFields /><QueryOptions /></Document>");
    XmlNode listQuery = doc.SelectSingleNode("//Query");
    XmlNode listViewFields = doc.SelectSingleNode("//ViewFields");
    XmlNode listQueryOptions = doc.SelectSingleNode("//QueryOptions");
    XmlNode items = this.wsLists.GetListItems(this.ListName , string.Empty, listQuery, listViewFields, string.Empty, listQueryOptions, null);
    if (items.ChildNodes[1].Attributes["ItemCount"].Value == "0")
    {
        return true; 
    }
    else
    {
        return false; 
    }
}
JL
Please use non-negative method names, like ItemExist(). It's far more easy to read.
Magnus Johansson
I agree with Magnus on the naming issue, but I like the succinctness of your solution using XML to get the information you need. One more vote and you can get the badge for answering your own question with 3+ votes.
Mayo