Excel to DataSet using OLEDB working differently between .NET Core and .NET Framework - excel

I have a worker service that references a .NET Framework class library. The class library contains a method to convert Excel to a dataset.
While debugging on Visual Studio, everything works as expected, but after publishing I get the error message:
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
To debug, I built the below two console apps with exactly the same code—one in .NET Core, the other .NET Framework. I then run the projects on two computers.
Computer A: Microsoft Office Tools installed, but no AccessDatabaseEngine.exe
Computer B: No Microsoft Office Tools, AccessDatabaseEngine installed
using System;
using System.Data;
using System.Data.OleDb;
using System.Text;
namespace ToDataSheetCore
{
class Program
{
static void Main(string[] args)
{
DataSet dt2 = ExcelToDataSetCommon("C:\\pathToExcel\\excelFile - AUGUST 04 2021.xlsx");
StringBuilder sb2 = new StringBuilder();
foreach (DataTable table in dt2.Tables)
{
foreach (DataRow row in table.Rows)
{
sb2.Append(string.Join(" ", row.ItemArray));
sb2.AppendLine();
}
}
Console.WriteLine(sb2);
Console.ReadLine();
}
public static DataSet ExcelToDataSetCommon(string SourceFilename)
{
DataSet ds = new DataSet();
try
{
string connStr = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;HDR=YES;\"", SourceFilename);
OleDbConnection conn = new OleDbConnection(connStr);
conn.Open();
DataTable schemaDT = conn.GetSchema("Tables", new string[] { null, null, null, "TABLE" });
conn.Close();
string tableName = schemaDT.Rows[0]["TABLE_NAME"].ToString();
OleDbCommand cmd = new OleDbCommand(string.Format("SELECT * FROM [{0}]", tableName), conn);
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
adapter.Fill(ds);
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
return ds;
}
}
}
Result
Computer A
.NET Core
Debug mode
Prints excel content to console
Publish mode - self-contained(win64, anypc)
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
.NET Framework
Debug mode
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
Publish mode - self-contained
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
Computer B
.NET Core
Debug mode
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
Publish mode - self-contained(win64, anypc)
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
.NET Framework
Debug mode
Prints excel content to console (Fails on uninstalling AccessDatabaseEngine)
Publish mode - self-contained
Prints excel content to console (Fails on uninstalling AccessDatabaseEngine)
I understand installing AccessDatabaseEngine provider has an effect, but I don't understand the different results from .NET Framework and .NET Core.
Though I have resorted to using ExcelDataReader since I want to avoid external dependencies.
I am confused by the difference in the results using OleDB API between .NET Core and .NET Framework. Is there a way the AccessDatabaseEngine provider can be published together with a .NET project?

Related

Owin startup bug with Umbraco Cloud - netStandard reference missing

In our current Umbraco Cloud project, we are using the Hangfire library (1.6.17) - the lib has a OWIN dependency (1.0.0).
Here is the code to call the hangfire launch:
In our current project, we are using the Hangfire library (1.6.17) - the lib has a OWIN dependency (1.0.0).
Here is the code to call the hangfire launch:
using Microsoft.Owin;
using Owin;
using Umbraco.Web;
using Hangfire;
using Hangfire.Dashboard;
using Hangfire.Annotations;
using Umbraco.Core.Models;
using Umbraco.Core;
using System.Web;
[assembly: OwinStartup(typeof(XX.Web.Core.Startup))]
namespace XX.Web.Core
{
public class Startup : UmbracoDefaultOwinStartup
{
public override void Configuration(IAppBuilder app)
{
//ensure the default options are configured
base.Configuration(app);
var cs = Umbraco.Core.ApplicationContext.Current.DatabaseContext.ConnectionString;
GlobalConfiguration.Configuration.UseSqlServerStorage(cs);
app.UseHangfireDashboard("/umbraco/backoffice/hangfire", new DashboardOptions
{
Authorization = new[] { new UmbracoUserAuthorisedFilter() },
AppPath = "/Umbraco"
});
app.UseHangfireServer();
}
}
public class UmbracoUserAuthorisedFilter : IDashboardAuthorizationFilter
{
public bool Authorize([NotNull] DashboardContext context)
{
// In case you need an OWIN context, use the next line,
// `OwinContext` class is the part of the `Microsoft.Owin` package.
//var context = new OwinContext(owinEnvironment);
// Allow all authenticated users to see the Dashboard (potentially dangerous).
//return context.Authentication.User.Identity.IsAuthenticated;
//this if you want to lock down to admins only
var userService = ApplicationContext.Current.Services.UserService;
var user = userService.GetByUsername(HttpContext.Current.User.Identity.Name);
return user.IsAdmin();
//this if you just want to make sure user is logged into backoffice
//return UmbracoContext.Current.Security.CurrentUser != null;
}
}
}
This is the default hangfire startup code to be able to use the library. The code has been working fine on 2 local machines, one Azure Web App instance but when I push this code to the Umbraco Cloud branch I get the following error:
Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.
The issue is: we are not using .net standard, both projects (web and core) are using .net framework 4.6.2
Is there any workaround for that issue ?

ASP.NET Core Identity Implementation using Cassandra Database

I am building an ASP.NET Core MVC application using the Cassandra Database on Windows.
I need help implementing ASP.NET Core Identity with Cassandra.
On Google I found AspNet.Identity.Cassandra in the version 2.0.0.1, but it's not compatible with ASP.NET Core 1.0.
I'm working on data store adapter for ASP.NET Core Identity
which allows you to build ASP.NET Core web applications, including membership, login, and user data. With this library, you can store your user's membership related data on Apache Cassandra.
Please note the library is in alpha version and needs to be finished
If you want to try it, follow these steps:
1 - Run the following command from the package manager console to install Cassandra identity provider.
Install-Package AspNetCore.Identity.Cassandra -Version 1.0.0-alpha1
2 - Add settings to appsettings.json
{
"CassandraNodes": [
"127.0.0.1"
],
"CassandraOptions": {
"KeyspaceName": "identity",
"Replication": {
"class": "NetworkTopologyStrategy",
"datacenter1": "1"
}
}
}
3 - Configure services in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// CassandraOptions configuration
services.Configure<CassandraOptions>(Configuration.GetSection("CassandraOptions"));
// Cassandra ISession initialization
services.AddCassandraSession<Cassandra.ISession>(() =>
{
var cluster = Cassandra.Cluster.Builder()
.AddContactPoints(Configuration.GetSection("CassandraNodes").GetChildren().Select(x => x.Value))
.Build();
var session = cluster.Connect();
return session;
});
// Added custom Cassandra stores
services.AddIdentity<ApplicationUser, ApplicationRole>()
.UseCassandraStores<Cassandra.ISession>()
.AddDefaultTokenProviders();
// Other code omitted
}
4 - And finally initialize DB in Program.cs
public static class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build()
.InitializeIdentityDb<ApplicationUser, ApplicationRole>();
}
For more information check project site at github.
Few Option
Try implement your own cassandra identity for ASP.net core, there is many sample how to create your Custom IdentityUser for ASP.net (using Google) then make it work with Cassandra
Fork / Update the AspNet.Identity.Cassandra project to .net core (open source, so makes easy to implement your own)
Use another provider, instead of Cassandra Database
Request update on github (link on section 2.)

Restart Web/Api-App on Azure programmatically

How can I restart Web-Apps and API-Apps on Azure programmatically?
(I'd like to call it from another API-App within the same App service plan.)
There's also the "Microsoft Azure Management Libraries" Nuget that allows you to work with Azure services from inside of applications.
See this page for an example on how to create new web sites from inside of an Azure Web site. Restarting web services work in a similar way to creating new services. See this page for a list of available web site related methods.
Also, for authenticating is used certificate base authentication, see this page for more details on that.
Bellow is a short command line program that will restart all websites in all the webspaces you got in your Azure subscription. It works kinda like an iisreset for Azure Web Sites.
The code is based on samples taken from the links earlier mentioned:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.Management.WebSites;
using Microsoft.WindowsAzure;
using System.Security.Cryptography.X509Certificates;
using Microsoft.WindowsAzure.Management.WebSites.Models;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var subscriptionId = "[INSERT_YOUR_SUBSCRIPTION_ID_HERE]";
var cred = new CertificateCloudCredentials(subscriptionId, GetCertificate());
var client = new WebSiteManagementClient(cred);
WebSpacesListResponse webspaces = client.WebSpaces.List();
webspaces.Select(p =>
{
Console.WriteLine("Processing webspace {0}", p.Name);
WebSpacesListWebSitesResponse websitesInWebspace = client.WebSpaces.ListWebSites(p.Name,
new WebSiteListParameters()
{
});
websitesInWebspace.Select(o =>
{
Console.Write(" - Restarting {0} ... ", o.Name);
OperationResponse operation = client.WebSites.Restart(p.Name, o.Name);
Console.WriteLine(operation.StatusCode.ToString());
return o;
}).ToArray();
return p;
}).ToArray();
if(System.Diagnostics.Debugger.IsAttached)
{
Console.WriteLine("Press anykey to exit");
Console.Read();
}
}
private static X509Certificate2 GetCertificate()
{
string certPath = Environment.CurrentDirectory + "\\" + "[NAME_OF_PFX_CERTIFICATE]";
var x509Cert = new X509Certificate2(certPath,"[PASSWORD_FOR_PFX_CERTIFICATE]");
return x509Cert;
}
}
}
Another alternative, if you can't find the function you need from the above mentioned library, you can also run powershell commands programmatically from inside of your application. You most likely will need to move, the application that is supposed to run these cmdlets, to a virtual machine to be able to load the needed powershell modules. See this page for more information on running powershell cmdlets programmatically.
You can use Powershell to do this. The relevant commands are:
Start-AzureWebsite -Name “xxxx”
Stop-AzureWebsite -Name “xxxx”
You can find help on these commands at the following links:
https://msdn.microsoft.com/en-us/library/azure/dn495288.aspx
https://msdn.microsoft.com/en-us/library/azure/dn495185.aspx
I think handling the base REST API is much better option. The Azure SDK changes quite a lot and lacks good documentation.
Here is an up-to-date sample code:
https://github.com/davidebbo/AzureWebsitesSamples/
You can adapt it to your needs.

Windows Azure project errors The CctSharedPackage did not load correctly

I opened a solution file that was working fine and got this mysterious error
The 'CctSharedPackage' did not load correctly
This project was a Windows Azure 2.1 project that had no issues working last week, however between then and a reboot it would not successfully load in Visual Studio 2012 any longer. This occurred on a machine that does have Windows Azure SDK 2.1 installed (the project did work fine last week)
The error stated to check the c:\Users\{user}\AppData\Roaming\Microsoft\VisualStudio\11.0\ActivityLog.xml file for more information.
In this file it stated "Could not find assembly Microsoft.Azure.Diagnostics ver 2.1".
Seeing as Windows Azure SDK 2.1 was already installed, i redownloaded the installer and went to run it to ask it to reinstall or repair the installation. Seeing as the install is the Web Platform Installer, it provided none of those options. At this point I decided that I must uninstall the SDK to be able to reinstall it from Add/Remove Programs.
When I went to Add/Remove Programs I saw that there were installations there for Windows Azure Libraries for .NET - v1.8 and Windows Azure Authoring Tools - v1.8. I removed both of these installations and then the project was able to load successfully.
this seems to be a problem with the installer. Re-installing is an option, but you can fix it with a simple command line by registering your assemblies in the GAC.
C:\Program Files (x86)\Windows Azure Tools\Visual Studio 11.0>gacutil /i .\Microsoft.VisualStudio.WindowsAzure.Diagnostics.dll
I don't have the 1.8 SDK installed. I believe it was a windows update relating to .Net 3.5 which might have broken my installation. To Fix all I did was open up Explorer in Windows 8 and select the 'Uninstall or Change a program' option from the ribbon.
Search for Azure and when there was an option to 'repair' I repaired the program. FIXED
I ran into similar problem (The 'CctSharedPackage' did not load correctly). In my case starting Visual Studio with Run as administrator solved the issue.
I also encountered this prolem today, but for me luckily it was solved just by restarting Visual Studio 2012. Just try it at least once to be sure :-) !
I was having this same problem. Reinstalling SDKs didn't seem to be helping and reinstalling Visual Studio sounded too painful so I decided to figure out what was causing the error.
I used another instance of Visual Studio and attached it to debug the offending Visual Studio instance. I couldn't see where the exact error was happening, but I was able to see what library the exception occured in and could see the source code using .NET Reflector to get an idea of what it does.
On startup the Microsoft.Cct.CctSharedPackage library iterates through all the Azure SDKs to figure out which ones are installed on your computer.
I ended up writing a console application to emulate what the startup does and see if I could find what was wrong. All the classes are internal so I had to use reflection to access them.
On my computer it turned out to be the Azure SDK 1.6 that was messed up. The SDK was installed, but the TargetAzureLibraries property was coming back as null. I uninstalled that SDK and it corrected the problem.
Console app below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WindowWidth = 240;
// The Microsft.Cct.AssemblyResolver does this:
/*
private IEnumerable<IAzureToolsVersionInfo> GetInstalledSDKsByProductVersionDesc(IServiceProvider serviceProvider) =>
(from knownProduct in AzureToolsVersionInfoUtilities.GetAllProducts()
where knownProduct.TargetAzureSDK.IsSDKInstalled() && knownProduct.TargetAzureLibraries.IsLibrariesInstalled()
orderby knownProduct.ProductVersion descending
select knownProduct)
*/
// Duplicate this logic using reflection to find the SDK install that is broken.
var asm = System.Reflection.Assembly.LoadFile("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\Extensions\\Microsoft\\Windows Azure Tools\\Microsoft.VisualStudio.WindowsAzure.Common.2.8.dll");
var typ = asm.GetType("Microsoft.Cct.ProductVersionInfo.AzureToolsVersionInfoConstants");
//Console.WriteLine(typ.ToString());
var allMethods = typ.GetFields(BindingFlags.Static | BindingFlags.Public).Select(it => it.Name).ToArray();
allMethods = allMethods.Where(it => it.StartsWith("WAT") && it.Length == 5).OrderBy(it => it).ToArray();
foreach (string version in allMethods)
{
var fld = typ.GetField(version, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
dynamic val = fld.GetValue(null);
var azTypeInfo = asm.GetType("Microsoft.Cct.ProductVersionInfo.AzureToolsVersionInfo");
bool isSdkInstalled = false;
bool isLibrariesInstalled = false;
Dictionary<string, string> sdkProperties = new Dictionary<string, string>();
Dictionary<string, string> libProperties = new Dictionary<string, string>();
// Get the SDK reference
var targetAzureSDK = azTypeInfo.GetProperty("TargetAzureSDK").GetValue(val);
Type targetAzureSDKProp = targetAzureSDK.GetType();
var methodNames = targetAzureSDKProp.GetMethods().Select(it => it.Name).ToArray();
var sdkIsInstalledMethod = targetAzureSDKProp.GetMethods().FirstOrDefault(it => it.Name == "IsSDKInstalled");
isSdkInstalled = (bool)sdkIsInstalledMethod.Invoke(targetAzureSDK, null);
var sdkProps = targetAzureSDKProp.GetProperties().ToArray();
foreach (var prop in sdkProps)
{
try
{
sdkProperties[prop.Name] = string.Concat(prop.GetValue(targetAzureSDK));
}
catch (Exception ex)
{
sdkProperties[prop.Name] = "Error:" + ex.Message;
}
}
if (isSdkInstalled)
{
// Get the Azure libraries reference
var targetAzureLibraries = azTypeInfo.GetProperty("TargetAzureLibraries").GetValue(val);
Type targetAzureLibrariesProp = targetAzureLibraries.GetType();
var isInstalledMethod = targetAzureLibrariesProp.GetMethods().FirstOrDefault(it => it.Name == "IsLibrariesInstalled");
isLibrariesInstalled = (bool)isInstalledMethod.Invoke(targetAzureLibraries, null);
var props = targetAzureLibrariesProp.GetProperties().ToArray();
foreach (var prop in props)
{
try
{
libProperties[prop.Name] = string.Concat(prop.GetValue(targetAzureLibraries));
}
catch (Exception ex)
{
libProperties[prop.Name] = "Error:" + ex.Message;
}
}
}
// Output details of this SDK
Console.WriteLine("{0}, {1}, {2}", version, isSdkInstalled, isLibrariesInstalled);
Console.WriteLine("\tSDK");
foreach (var kp in sdkProperties)
{
Console.WriteLine("\t{0} {1}", kp.Key, kp.Value);
}
Console.WriteLine("\tLib");
foreach (var kp in libProperties)
{
Console.WriteLine("\t{0} {1}", kp.Key, kp.Value);
}
}
}
}
}
Uninstalled all Windows Azure entries ending with October 2012 via control panel. After reopening my solution I got a dialog to convert the project target (screenshot).
I second the turn it off then on again option. Got this error on loading a project after a week away. Rebooted and it went away. So try that at least once.

Sharepoint Object Model applicaton cannot run outside of WSS server

I create a C# console application using Microsoft.SharePoint object model VS WSS extensions on Windows Server 2003. The application is supposed to iterate WSS3.0 sites looking for all available lists. It runs just fine on the server. But if I try to run the exe from another computer on the network, the application crashes instantly on SPSite siteCollection = new SPSite("http://devsharepoint);
Even my try and catch doesn't help as catch is not executed.
Is it intended to run the Sharepoint object model applications only on machines with VS SharePoint extensions installed?
Here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
namespace ConsoleApplicationWSSobjectModel
{
class Program
{
static void Main(string[] args)
{
string url = "http://sharepoint";
Console.WriteLine("Trying to access: " + url);
try
{
SPSite siteCollection = new SPSite(url);//"http://Server_Name");
SPWebCollection sites = siteCollection.AllWebs;
foreach (SPWeb site in sites)
{
SPListCollection lists = site.Lists;
Console.WriteLine("Site: " + site.Name + " Lists: " + lists.Count.ToString());
}
Console.WriteLine("Press ENTER to continue");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
You cannot use the SP object model ”outside sharepoint” you will have to use web services (or if your go with sharepoint 2010 you can use the new client object model)
Anything built with the SharePoint object model can only run on a server with SharePoint installed. There is however no dependency on the VS extensions.
You can use Client Object Model using C# or VB as your language. Add references Microsoft.sharepoint.client.dll and Microsoft.sharepoint.client.Runtime.dll it can be found under 14(SP2010) or 15(SP2013) hive ISAPI folder.

Resources