Subsonic 3 Class Library & Winforms App Null IDataProvider BUG - subsonic

I have got a class library project and a winforms app.
Everything is getting geerated fine and my Winforms app references the class library but as soon as I run it and try to retreive data it comes up with dataprovider is null.
The one thing to note is that I do not have a app.config in my Winforms app only in the class library. Do I need one in the Winforms app and if so what do I put in it?
Thanks
UPDATE: I think I have found a bug in Query\Select.cs
public Select(IDataProvider provider, params string[] columns)
{
//_provider is null
//provider is populated correctly
this.sqlFragment = new SqlFragment(_provider);
_provider = provider;
SelectColumnList = columns;
SQLCommand = this.sqlFragment.SELECT;
}

Yes, you need an App.config in your Winforms app and you put your connection string there. It's worth noting that an App.config is pointless in a class library EXCEPT when you're using SubSonic :), which will pull one from the project.
Class libraries don't have their own configuration - they pull their config from the execution environment.

Related

Blazor Component (in library) and JSInterop

I've created a Blazor Component within a full Blazor project and all works well.
However, when I move this component to it's own Razor Class Library project, I am now getting an error that I cannot use JSInterop until a connection with the server is made. I am running my code in the OnAfterRenderAsync() method.
I had to alter the code a little when I made the change.
In a full Blazor project, JSInterop is provided for you with DI in the Startup class. But this is not the case with a calss library.
So instead of "#inject JSInterop js" in the page, I had to set it up like this -
private IJSRuntime js { get; set; }
protected override void OnInitialized()
{
js = ScopedServices.GetRequiredService<IJSRuntime>();
}
From the sketchy details available on the web, I'm assuming this gets the service from the Parent project.
Using debugging, I can see that js is NOT null. It does seem to have been set to a valid object.
Can anyone point me in the right direction?
The server pre-renders, so your code will run before there is a client connection to the server. When rendering in OnAfterRenderAsync you should only use IJSRuntime when the firstRender parameter is true, or any point after that, but never before.
Found the solution to my problem and it has rendered my initial question irrelevant.
When I copied my component to it's own class library project, it would not compile. It gave me an error on the line #inject JSInterop js.
This led me to believe that it didn't know how to inject this as it is not set during the Startup of the project, as it is in a Blazor app.
So I cobbled together the code to get a reference via ScopedServices.GetRequiredService().
This did create an object but did not have _clientProxy set which contains the connection to the server.
So digging round I managed to find a complete component library example project at BlazorHelp Website
This did have the JSInterop injected in the Blazor file. So I reverted my code back to the original code that worked in the full project and tried to compile. It gave me the same error. So I deleted the #inject JSInterop js line and typed it in again.
IT RECOGNIZED IT!!!
It still failed to compile, not recognizing a custom type (Pivot) and asking whether I had included a reference to it.
[CascadingParameter] public Pivot OwnerPivot { get; set; }
I deleted the word Pivot and retyped it and, voila, it compiled.
So it looks like there some sort of error in VS2019 or the razor compiler, where deleting code in the source file and re-entering caused it to recognize and compile.

Why doesn't Azure load properly the Interop?

I have a WebApp on Azure that uses a dll. This library needs Interop libraries x86 and x64.
Sometimes, at the restart of the App (I suppose), the App fails due to an exception:
System.EntryPointNotFoundException: Unable to find an entry point named 'sqlite3_config' in DLL 'SQLite.Interop.dll'. at System.Data.SQLite.UnsafeNativeMethods.sqlite3_config_none(SQLiteConfigOpsEnum op) at System.Data.SQLite.SQLite3.StaticIsInitialized() at System.Data.SQLite.SQLiteLog.Initialize() at System.Data.SQLite.SQLiteConnection..ctor(String connectionString, Boolean parseViaFramework) at T_Dox.WebService.SQLiteDb.CreateConnection() at WebService.CeDb.Connect()
The SQLite used is the SQLCipher's one.
What am I missing here? I don't understand why the app stops working suddenly even if I don't make any changes.
The App is a Web Service (.asmx file) that uses a data access layer to perform some business logic.
It was under a web site project, then we moved it into another project, a webapi\mvc project.
The routing bypasses this extension, so it works as before, a simple web service call.
The called web method initializes a business class loaded from another .net library (a VB.Net library).
Inside, this class uses a wrapper to a sqlConnection, in this case the SQLiteConnection.
In its constructor it starts an SQLiteConnection, and normally it works.
Then it performs some CRUD operations ...
So I can represent the operation this way:
[WebService(Namespace = "...")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class SampleService : System.Web.Services.WebService
{
[WebMethod]
public ServerInfo Test()
{
var sampleBusinessClass = new SampleBusinessCLass();
sampleBusinessClass.DoSomething();
using(var connection = new SQLiteConnection()) //the constructor is the parameterless one
{
//...
}
}
}
And the stack will be this (this is not the real one):
System.EntryPointNotFoundException: Unable to find an entry point named 'sqlite3_config' in DLL 'SQLite.Interop.dll'.
at System.Data.SQLite.UnsafeNativeMethods.sqlite3_config_none(SQLiteConfigOpsEnum op)
at System.Data.SQLite.SQLite3.StaticIsInitialized()
at System.Data.SQLite.SQLiteLog.Initialize()
at System.Data.SQLite.SQLiteConnection..ctor(String connectionString, Boolean parseViaFramework)
at xxx.WebService.SampleService.Test()
It always works, but sometimes it starts to launch this error until the stop and start of the web application on iss (in our case: Azure).
Inspecting the System.Data.SQlite.dll I can clearly see the entry point and actually it always passes this internal code (no conditions that can bypass this part) and it generally works.
The System.Data.SQlite.dll (1.0.96.0 version) is provided by SqlCypher product. I think it is the original System.Data.SQLite one because at first sight I can see the same assembly manifest and content.
The interop System.Data.SQLite uses is probably modified by SqlCypher team to give their features.
To avoid possible issues we put the interop in the path /bin/x64, then we compile our web app ONLY in x64 and it runs on a x64 environment.

Why am I getting "A route named 'swagger_docs' is already in the route collection" after I publish my API App?

After publishing my API App I'm getting the yellow error screen of ASP.NET. The error message says "A route named 'swagger_docs' is already in the route collection".
How can I fix this?
This is not related to API Apps per se but more around Web API. What triggers the error is pretty simple:
You publish the API App which is based on Web API.
You discard your project and start working on a new API App based on Web API
You want to publish the new API App instead of the old API App you created at step 1.
You select the API App during "Publish.." and you get the publishing profile of the existing API App we deployed at step 1.
You deploy using Web Deploy and the publishing profile, the new API App on top of the old one.
That will trigger the issue I've explained before. That happens because there are two routes being registered by Swashbuckle when you try to start the app. One of the old one and one of the new one. That's because the old files are still present at the destination.
To solve this, during Web Deploy, click on the Settings tab and then expand the "File Publish Options". There is a checkbox there, called "Remove additional files from destination". This will fix the issue as it will only leave the files you deploy at the destination and not the old ones as well.
Hope it helps.
What if it happens when trying to debug the app locally ?
This happened for me, and the reason was, I renamed my assembly name. So the bin folder had two dlls for the same project with different names which caused this error. Once I deleted the old named dll all is well. Hope this helps.
This happens because You probally are configuring you route in your WebApiConfig class and SwaggerConfig class, as explained below:
WebApiConfig file:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
SwaggerConfig.Register();
}
}
SwaggerConfig file:
using Swashbuckle.Application;
[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
namespace NEOH.Api
{
public class SwaggerConfig
{
public static void Register()
{
What you should do is remove the assembly call on SwaggerConfig file.
It should work.
My Solution & Cause:
I had the same problem when I renamed NamesSpaces,Refactored,etc.
After reading what everyone else did here's what I tried:
Cleaned the Solution in Visual Studio
Cleaned the Bin folder manually
Checked the nameSpace in the Project Properties (copied it just in case) >> Build tab >> Scrolldown to Output and ensure the XML documentation file is correct. You will need this name later.
Opened up: SwaggerConfig.cs >> fixed the name space in here (copy,paste) c.SingleApiVersion("vX","NameSpace")
Scrolled down until I found: GetXmlCommentsPath() copied and pasted the correct name space in the .xml file path.
Ran, smoke tested, finished this post.
My issue was that I was referencing another project that had the Swashbuckle extension.
Here is how I kept both projects without changing the anything in project that was referenced:
Remove the routes created by the project referenced under SwaggerConfig.cs > Register right before GlobalConfiguration.Configuration.EnableSwagger(...).EnableSwaggerUi(...);:
// Clears the previous routes as this solution references another Swagger ASP.NET project which adds the swagger routes.
// Trying to add the Swagger routes more than once will prevent the application from starting
GlobalConfiguration.Configuration.Routes.Clear();
Then, the application will be able to start, but you will see the operations/functions that are in both projects. To remove the operations from the project being referenced...
Create the following class
using Swashbuckle.Swagger;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http.Description;
namespace yournamespace.Models
{
/// <summary>
/// This class allows to manage the Swagger document filters.
/// </summary>
public class SwaggerCustomOperationsFilter : IDocumentFilter
{
/// <summary>
/// Applies the Swagger operation filter to exclude the Swagger operations/functions
/// that are inherited by the other Swagger projects referenced.
/// </summary>
///
/// <param name="p_swaggerDoc">Swagger document</param>
/// <param name="p_schemaRegistry">Swagger schema registry</param>
/// <param name="p_apiExplorer">Api description collection</param>
public void Apply(SwaggerDocument p_swaggerDoc, SchemaRegistry p_schemaRegistry, IApiExplorer p_apiExplorer)
{
IEnumerable<ApiDescription> externalApiDescriptions = p_apiExplorer.ApiDescriptions
.Where(d => d.ActionDescriptor.ControllerDescriptor.ControllerType.Module.Name != GetType().Module.Name);
IEnumerable<int> externalApiDescriptionIndexes = externalApiDescriptions
.Select(d => p_apiExplorer.ApiDescriptions.IndexOf(d))
.OrderByDescending(i => i);
IEnumerable<string> externalPaths = externalApiDescriptions.Select(d => $"/{d.RelativePathSansQueryString()}");
foreach (string path in externalPaths)
{
p_swaggerDoc.paths.Remove(path);
}
foreach (int apiDescriptionIndex in externalApiDescriptionIndexes)
{
p_apiExplorer.ApiDescriptions.RemoveAt(apiDescriptionIndex);
}
}
}
}
And add the following in SwaggerConfig.cs > Register > GlobalConfiguration.Configuration.EnableSwagger(...)
c.DocumentFilter<SwaggerCustomOperationsFilter>();
Alternative cause of this problem:
Seems like a lot of people have this issue resolved by deleting their "bin" and "obj" folders as per the other answers.
However the cause of the issue might be that you are configuring your Swagger Config in a referenced project, as per this comment: https://github.com/domaindrivendev/Swashbuckle/issues/364#issuecomment-226013593
I received this error when one project with Swagger referenced another
project with Swagger. Removing the reference fixed the problem.
This caused me to split some core functionality out into a Third project that both of my API's could reference, rather than them referencing each other.

The model backing my context has changed

I have a class library project where my POCO classes live along with a Dbcontext. I am using Code First with data migrations and everything has gone great up to this point. I use the class library in a console application test project and it still works fine there, but I am also trying to use the same exact class library in an MVC project and I get a "The model backing the context has changed since the database was created". Whenever I make a change to the model, I do the database migration update and everything goes well. The model has not still works in the console application just fine.
I have this method in a controller where I am trying to access the context:
public MultiSelectList GetListOfPossibleDispositions()
{
List<DALDevices3.Dispositions> dispositions = new List<Dispositions>();
dispositions = context.Dispositions.GroupBy(d=>d.Description).Select(grp=>grp.First()).ToList();
dispositions.OrderBy(d=>d.Description);
selectListDispositions = new MultiSelectList(dispositions, "id", "Description");
context.Dispose();
return selectListDispositions;
}
Any thought on what might be causing this issue or a possible work around ?
Thanks
In my MVC application I had a connection string name like this:
<add name="DALDevices3.DeviceContextConnectionString" connectionString="Data Source=....
so I removed the connection string since it is code first and still received the same error. I put the connection string back like this:
<add name="DALDevices3.DeviceContext" connectionString="Data Source=....
and the application works. So a connection string is not required in the DAL application, but is needed in the consuming application.

Problems using an installclass in a web setup for a web site

I am trying to create a web setup for my web site, and I want to use an installer class to do some custom stuff. I am using VS 2010, and the web site and installer is .NET 3.5.
I have added reference to the installer class project output in the Install section under Custom Actions:
I have also set /targetdir="[TARGETDIR]/" on the CustomActionData for this action.
The InstallScript project is a standard class library (dll).
There is a public class that inherits from Installer class. It overrides the Install method as I have seen been done in several online examples:
using System.Collections;
using System.Windows.Forms;
namespace InstallScript
{
public class MyWebInstaller : System.Configuration.Install.Installer
{
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
var targetDir = Context.Parameters["targetdir"];
if(targetDir==null) targetDir = "No TARGETDIR!";
MessageBox.Show("TARGETDIR:\t" + targetDir);
}
}
}
I would think there should be shown a message box here som time during the install, but it seems like it is never called. No error is shown either. The setup just runs through as if this code was never called.
Anyone have idea of what is wrong?
OK, I found out what was missing.
You need to specify the class with the class attribute RunInstaller(true) for the setup to pick up and actually run the code.
So the class needs to be declared like this:
[System.ComponentModel.RunInstaller(true)]
public class MyWebInstaller : System.Configuration.Install.Installer
{
...

Resources