Update Lookup Column Web and List Programmatically

I had requirement of creating custom list programmatically for our varience sites en-us(English) and de-de(German). For that, I have created site-columns, content-type and add site-columns to content-type at root site level. Now I am using same content-type in varience site’s list. But the lookup column of varience site’s list refer to root web ( and list) instead of current web.So to fix this issue I have to manually change the lookup column webid and list of current site not root site.

 

///
/// Set lookup site-columns webid and listid for all variance site
///
public static void SetLookupFieldWebAndListID()
{
  try
  {
    using (SPSite site = new SPSite(RootSiteUrl))
    {
      SPWebCollection allWebs = site.AllWebs;
      foreach (SPWeb currentWeb in allWebs)
      {
        if (PublishingWeb.IsPublishingWeb(currentWeb))
        {
          using (currentWeb)
          {
            //fetch lookup column list and lookup column
            SPList list = currentWeb.Lists["ListName"];
            SPFieldLookup lookupColumn = (SPFieldLookup)list.Fields.GetField("LookupColumnName");

            //update lookup column webid
            lookupColumn.LookupWebId = currentWeb.ID;

            //fetch lookup list
            SPList lookupList = currentWeb.Lists["lookupListName"];

            //update lookup column listid
            if (string.IsNullOrEmpty(lookupColumn.LookupList))
            {
              lookupColumn.LookupList = lookupList.ID.ToString();
            }
            else
            {
              lookupColumn.SchemaXml = lookupColumn.SchemaXml.ReplaceXmlAttributeValue("List", lookupList.ID.ToString()).ReplaceXmlAttributeValue("WebId", currentWeb.ID.ToString());
            }
            lookupColumn.Update(true);
          }
        }

      }
    }

  }
  catch (Exception ex)
  {
    Logger.LogError(ex.Message, "Setup lookup field error", ex.StackTrace);
  }
}

///
/// Relpace the WebID and ListID of lookup field xml-schema.
///
public static string ReplaceXmlAttributeValue(this string xml, string attributeName, string value)
{
            if (string.IsNullOrEmpty(xml))
            {
                throw new ArgumentNullException("xml");
            }
            if (string.IsNullOrEmpty(value))
            {
                throw new ArgumentNullException("value");
            }

            int indexOfAttributeName = xml.IndexOf(attributeName, StringComparison.CurrentCultureIgnoreCase);
            if (indexOfAttributeName == -1)
            {
                throw new ArgumentOutOfRangeException("attributeName", string.Format("Attribute {0} not found in source xml", attributeName));
            }

            int indexOfAttibuteValueBegin = xml.IndexOf('"', indexOfAttributeName);
            int indexOfAttributeValueEnd = xml.IndexOf('"', indexOfAttibuteValueBegin + 1);

            return xml.Substring(0, indexOfAttibuteValueBegin + 1) + value +    xml.Substring(indexOfAttributeValueEnd);
}

 

Moss 2007 to Sharepoint2013 page migration

Few months ago, I had arequirement of copy SharePoint 2007 pages to SharePoint 2013 site in my migration project. The web application was hosted on other server (not on the SharePoint server). So Ihad to use SharePoint services model.I have used copy-service for this requirement. Please note that this service will only copy static content of page not other webparts content.

To start the page migration, first fetch source page fieldinfo and bytearray using copy-service ‘GetItem’ method(add copy service reference and programatically change its url).

 //give source copy-service url and credentials
CopyWS.Copy copyWS = new CopyWS.Copy();
copyWS.Url = “http://wssdev:7001/_vti_bin/copy.asmx”;
copyWS.Credentials = new NetworkCredential(“sourcesite-username”, “sourcesite-password”);//fetch page fieldinfo and bytearray using copy GetItem method from source page.
CopyWS.FieldInformation[] mossPageFieldInfoArray;
byte[] mossPageByteArray;
uint myGetUint = copyWS.GetItem(“http://wssdev:7001/Pages/test1.aspx”, out mossPageFieldInfoArray, out mossPageByteArray);

Next, set copy-service url to destination site and copy the page using ‘CopyIntoItems’ method. Provide source page fieldinfo and bytearray into this method.

//give destination copy-service url and credentials
copyWS = new CopyWS.Copy();
copyWS.Url = “http://spe2013dev1:4444/_vti_bin/copy.asmx”;
copyWS.Credentials = new NetworkCredential(“destinationsite-username”, “destinationsite-password”);// create page in destination site using source page info.
CopyWS.CopyResult[] copyResultArray;
string[] copyDest = { “http://spe2013dev1:4444/Pages/test1.aspx” };
uint myCopyUint = copyWS.CopyIntoItems(“http://wssdev:7001/Pages/test1.aspx”, copyDest, mossPageFieldInfoArray, mossPageByteArray, out copyResultArray);

To confirm the migration process, check CopyResult.ErrorCode, if it is successful than your page gets copied successfully else it will show error message.

Additional Information:

  • Page FieldInformation Array
  • Page Byte Array
  • Page Copy Result
Related link:
http://msdn.microsoft.com/en-us/library/copy.copy.copyintoitems%28v=office.12%29.aspx

Working with SharePoint Search with Form Based Authentication

When you configure form based authentication sometime is is need that  you disable Integrated Windows Authentication. By doing so search does not work as per expectation and you may face error. If you check in crawl log you will saw following notification error message.

Error:

Access is denied. Verify that either the Default Content Access Account has access to this repository, or add a crawl rule to crawl this repository. If the repository being crawled is a SharePoint repository, verify that the account you are using has “Full Read” permissions on the SharePoint Web Application being crawled. ( HttpStatusCode Unauthorized The request failed with HTTP status 401: Unauthorized. )

Reason:

This error will occur, when search engine tries to crawl the content using the URL but as there is a change in user identity server is unable to access database and server will reject the request.

Solution:

For SharePoint Search you need Integrated Windows Authentication for crawling the content database. To resolve this issue we need to create extended website. Follow below steps to extend

  1. Go to Central Administration and select your Form Based Authentication website and extend your website with integrated windows authentication enabled. Note, when you extend website you have different site in IIS.
  2. Now modify your search service application’s content source and in content source give your extended website URL instead of live site url(Form-based authenticated site).
  3. Once you do that, click on content source and start full crawl. After crawl completes you will not face above error and search result is coming.
  4. If you check in your site now you may observe that search result is coming with extended site URL not with live site URL. To display live site URL open your Search Service Application and in the crawling section click on Server Name Mappings.
  5. From Server Name Mappings click on New Mapping.
  6. “In Address in index” give your extended site URL and “In address in search results” give your live site URL and click on Ok.
  7. Now once again click on content source and start full crawl. Now result will come with your live site URL.

 

Shraddha Shah
SharePoint Developer