Tuesday, July 31, 2012

The store provider factory type Oracle.DataAccess.Client.OracleClientFactory does not implement the IServiceProvider interface


Trying to use the Oracle Data Provider for .NET (ODP.NET) with Entity Framework (EF) results in the following error:

System.Data.ProviderIncompatibleException:   The store provider factory type 'Oracle.DataAccess.Client.OracleClientFactory' does not implement the IServiceProvider interface. Use a store provider that implements this interface.

Possible Root Causes:

1.  If ODP.Net Entity Framework is used, make sure that the dll 'Oracle.DataAccess.dll'  in Visual Studio Solution explorer is pointing to version '2.112.3.0'. The reason is that the ODP.Net Entity Framework is supported only with version '112.3.0' or later.

 To know which version dll is loaded in Visual Studio, we can use a free tool called Process Explorer, this will help to analyze the dlls loaded on Visual Studio exe (Devenv.exe).


2. ODP.Net Entitiy framework support .Net 4.0 (or later) versions. I have created ODP.Net entities in Visual Studio 2010 and changed the framework to 3.5  (for SharePoint development reasons) that gave me the same error as above one when i ran the application, but when I change the framework to 4.0, it works fine.
Most of the blogs (I personally found in google search) doesn't speak clearly about this. So please make sure that you are using ODP.Net  Entity Frameworkwith only 4.0 or later version of .Net framework. However, please note that the ODP.Net  (without entity framework) supports the earlier .Net versions such as .Net 3.5 (this is what we tried).

 Sometimes, you may also see errors like "Could not load assembly Oracle.DataAccess.dll", this may be the issue with bit versions. Oracle provides this dll in two versions, they are: 32 bit and 64 bit. In visual studio you make sure that you are using 32 bit dll since Visual Studio 2010 is 32 bit. While deploying the ShareObjects (like webparts), make sure that you are using 64 bit Oracle.DataAccess.dll since SharePoint 2010 supports only 64 bit dlls


Could not load file or assembly Oracle.DataAccess in SharePoint 2010

In our SharePoint 2010 environment we started using ODP.Net to connect to Oracle Database. We have installed the 64 bit ODP.Net software and tried to build a webpart which gets the data from Oracle DB and display it in a Gird. But while loading the webpart page in SharePoint after deployment, we got the issue with Oracle.DataAccess.dll. The error was "Could not load file or assembly 'Oracle.DataAccess'". Finally we have found that we needed to use 64 bit version Oracle.DataAccess.dll. For some reason we also had 32 bit version Oracle Access dll on our machine, so we had to find the 64 bit dll and correctly reference it in Visual Stuio, butild it and deploy to SharePoint Web App. Provided the steps below:

1.    Developed a web part which shows the data on button click from Oracle Database using a Stored Procedure with ODP.Net framework

2.    Referenced 64 bit Oracle dll from GAC and added the reference in Visual Studio

2.1  Steps for finding 64 bit dll from GAC

2.1.1      Go to command Prompt and enter the command “cd c:\Windows\assembly”, hit enter

2.1.2      Enter Command “dir Oracle.dataaccess.dll /s”, hit enter, now the screen should show like below:
                      

The above screen shows the references of Oracle.DataAccess.dll in GAC and their physical paths. We need to 64 bit dll path for SharePoint App.
3.    Make the Oracle dll path to 64 bit folder in GAC with the help of above screen, like below:
c:\Windows\assembly\GAC_64\Oracle.DataAccess\2.112.1.0__89b483f429c47342\oracle.dataaccess.dll
4.    Add the 64bit Oracle dll to Visual Studio solution, like below:
4.1  Go to Visual Studio Solution Explorer and click on “Add Reference”
4.2  That opens a dialogue like below:


Enter the dll path (found in step 2.1.2) in the File Name text box and hit enter, that shows the oracle.Dataaccess.dll as shown in the above diagram. Select the dll and click Ok.

5.    Now build the application and deploy the solution to SharePoint Web App

6.    Make sure that Oralce.DataAccess.dll is registered under safecontrol properly, as shown below:

<SafeControl Assembly="Oracle.DataAccess, Version=2.112.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" Namespace="Oracle.DataAccess" TypeName="*" Safe="True" SafeAgainstScript="False" />

This worked fine.

Monday, July 23, 2012

Update document content fields through K2 blackpearl

Recently, we have found a requirement where we need to automate a document content field's update. I think OpenXML SDK has some samples in MSDN, but our intention was to use K2 blackpearl since it provides a template do this. So found an article in K2 underground like below:
http://www.k2underground.com/blogs/k2/archive/2012/06/04/how-to-automate-document-assembly-from-within-a-k2-process.aspx

Though this article has a good explanation to use K2 WordDocument template, this has only one field update and that too through from K2 wizard. However, in our requirement we had more than one content field to be updated. So, on word document template decided to customize it and write my own code so that I can use same K2 blackpearl APIs and get my work done. Here is what I have done:

Right click on the WordDocument event template, select View Code option and the click on Event Item, that opens the code file. In that you can lot of templates code showing with switch cases and conditions, but I have used a source document libary and a destination document library. Source document library will help you to store templates which have content fields (you can prepare with the help of above article link from K2 underground) and the destination document library will store the updated document for content fields. I took a loop which has a loop count equal to the number of content fields in the document template and for each content field I have a mapped value. For this sample I took 2 content fields and updated some values dynamically. 
The code look like below:
private void ExecuteUpdateContent(Project_d5ff4cc5c544462496df8afb5a72a9a1.EventItemContext_5b01db313c294025905a3b5d8a27feb1 K2)
{
for (int i = 1; i <= 2; i++)
{
#region
string k2ServerConnStr = K2.Configuration.ServerConnectionString;
string outputSharepointUrl = K2.Configuration.OutputSharePointUrl;
string outputLocationType = K2.Configuration.OutputDocumentLocationType;
string temp = string.Empty;
if (i == 1)
{
temp = K2.Configuration.OutputContentControlName;
}
else
{
temp = "ID";
}
string contentControlName = temp;// K2.Configuration.OutputContentControlName;
string sourceLocationType = K2.Configuration.SourceLocationType;
string sourceFileName = K2.Configuration.SourceFileName;
string refFieldName = K2.Configuration.ReferenceFieldName;
bool addRefItem = K2.Configuration.AddReferenceToField;
 
List<IReferenceItem> referenceItems = null;
 
switch (sourceLocationType)
{
case "SharePointDocumentLibrary":
{
string sourceSPUrl = K2.Configuration.SourceSharePointUrl;
string sourceLibName = K2.Configuration.SourceLibraryName;
string sourceFolderName = K2.Configuration.SourceFolderName;
 
referenceItems = SharePointFileHelper.GetFilesReference(sourceSPUrl, sourceLibName, sourceFolderName, sourceFileName, k2ServerConnStr);
}
break;

// from text is a special case, the source files do not have to be retrieved
case "Text":
default:
break;
}
 
string outputfileName = K2.Configuration.OutputFileName;
 
switch (outputLocationType)
{
case "SharePointDocumentLibrary":
{
string outputlibraryName = K2.Configuration.OutputLibraryName;
string outputfolderName = K2.Configuration.OutputFolder;
 
byte[] file = SharePointFileHelper.LoadFile(outputSharepointUrl, outputlibraryName, outputfolderName, outputfileName, k2ServerConnStr);
 
WordDocumentHelper wdHelper = new WordDocumentHelper(file);
byte[] returnFile = null;
 
if (sourceLocationType == "Text")
{
string sourceText = K2.Configuration.SourceText + "1"; 
 
returnFile = wdHelper.UpdateContentControl(contentControlName, sourceText);
}
else
{
returnFile = wdHelper.UpdateContentControl(contentControlName, referenceItems);
}
 
SharePointFileHelper outputSpHelper = new SharePointFileHelper(outputSharepointUrl, k2ServerConnStr);
//outputSpHelper.Save(returnFile, outputlibraryName, outputfolderName, outputfileName);
outputSpHelper.Save(returnFile, outputlibraryName, outputfolderName, outputfileName);
}
break;
}
 
#endregion
}

}

For my convenience, I have removed other templates code inside this event code, but we can still keep that logic as part of this.

Also, if we understand the APIs nicely, we can use server code event template from K2 Tool box and add the above code in it. That way also it works fine, but using the word document template will guide us how to use it's document (OPENXML) APIs for doc operations.

Hope it helps others too!!!





Sunday, February 26, 2012

Command line error for adding content DB or delete content DB

Today I was playing with SharePoint content DBs for detaching and attaching. I mean changing the content DB of a Site Collection to a new Content DB (like restored copy of other environment like Prod).

So to do this, I was using STSADM commands like this:

stsadm -o deletecontentdb -url http://srisaihome:1099/sites/site2 -databasename wss_content_1099_1

I made this string in a notepad and coped to Commond Prompt Console and hit the Enter and I got the error like
“ Command Line Error”. However, I did'n’t do any mistake in writing the command. Here is the complete command I have written:

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN>stsadm -o deletecontentdb -url http://srisaihome:1099/sites/site2 -databasename wss_content_1099_1

The weird thing is instead of copying the command from notepad If I type the command manually it works like a charm. Don’t be surprised, it’s weird but it’s true.  Not sure how many has experienced this, but thought of sharing this in my blog.

Sunday, February 12, 2012

Replace a WebPart with new one in SharePoint

using (SPSite spSiteTest = new SPSite(webURL))
           {
               SPFile file = null;
               using (SPWeb web = spSiteTest.OpenWeb())
               {
                   try
                   {
                       file = web.GetFile(webPageURL);
                       if (file.Level == SPFileLevel.Checkout)
                       {
                           file.CheckIn("Checkin before replace");
                           file.CheckOut();
                       }
                       else
                       {
                           file.CheckOut();
                       }
                       SPLimitedWebPartManager webPartMgr = file.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
                       for (int k = 0; k < webPartMgr.WebParts.Count; k++)
                       {
                           System.Web.UI.WebControls.WebParts.WebPart wpOld = webPartMgr.WebParts[k];
                           if (string.Compare(wpOld.GetType().Name.Trim(), webPartName.Trim(), true) == 0)
                           {
                               //Read old webpart properties
                               string zoneID = webPartMgr.GetZoneID(wpOld);
                               string storageKey = webPartMgr.GetStorageKey(wpOld).ToString();
 
                               //create new webpart object            
                               MyNewWebPart wpNew = new MyNewWebPart();
                               wpNew.Title = wpOld.Title;// "Web Part Title";
                               wpNew.ChromeState = wpOld.ChromeState;// System.Web.UI.WebControls.WebParts.PartChromeState.Normal;
                               wpNew.ChromeType = wpOld.ChromeType;// System.Web.UI.WebControls.WebParts.PartChromeType.None;
 
                               webPartMgr.DeleteWebPart(wpOld);
                               //Add new webpart object to webparts collection     
                               webPartMgr.AddWebPart(wpNew, zoneID, 0);
                               file.Update();
                               web.Update();
                           }
                       }
                   }
                   catch (Exception ex)
                   {
                       if (file != null && file.Level == SPFileLevel.Checkout)
                       {
                           file.UndoCheckOut();
                       }
                   }
                   finally
                   {
                       if (file != null && file.Level == SPFileLevel.Checkout)
                       {
                           file.CheckIn("Added");
                       }
                       web.AllowUnsafeUpdates = false;
                   }
               }
 
           }

Access to XMLHttpRequest at 'from origin has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https. .net core angular

Issue: The angular application was getting error from API that the origin has been blocked by CORS policy. Solution: Make sure that the...