How to show detailed diagnostic information when publishing dacpac with dacservices object? - sql-server-data-tools

How to show detailed diagnostic information when publishing dacpac with dacservices object?
SqlPackage.exe has a Diagnostics switch for detailed output of the publish operation.
/Diagnostics: /d {True|False} Specifies whether diagnostic logging is output to the console. Defaults to False.
My question is how do I enable this for dacservices instead of using the exe?
The deploy and publish methods below do not seem to offer a parameter for this:
public Microsoft.SqlServer.Dac.PublishResult Publish (Microsoft.SqlServer.Dac.DacPackage package, string targetDatabaseName, Microsoft.SqlServer.Dac.PublishOptions publishOptions);
public void Deploy (Microsoft.SqlServer.Dac.DacPackage package, string targetDatabaseName, bool upgradeExisting = false, Microsoft.SqlServer.Dac.DacDeployOptions options = default, System.Threading.CancellationToken? cancellationToken = default);
This question would further apply for using Sql Server Data tools inside visual studio as a publish profile.. there seems to be no means to enable detailed diagnostic information to be output during a db publish operation.

Related

Why does turning on Application Insights on a App Service crash the app?

I have turned on Application Insights on my app service. Everytime I try to run the app or login using the app it gives an error:
An error has occurred. Please call support or your account manager if this error persists
When i looked in the Application errors under Logging,I get the following:
System.ApplicationException: The trace listener AzureBlobTraceListener is disabled.
---> System.InvalidOperationException: The SAS URL for the cloud storage account is not
specified. Use the environment variable
'DIAGNOSTICS_AZUREBLOBCONTAINERSASURL' to define it.
Im assuming I need to add the following in the Configuration of the App Service:
{
"name": "DIAGNOSTICS_AZUREBLOBCONTAINERSASURL",
"value": <URL>,
"slotSetting": true
},
But what is the and where can i find it ? Or is there a different error causing the app to crash once application insights is enabled, has anyone experienced this ?
I can see you have configured DIAGNOSTICS_AZUREBLOBCONTAINERSASURL without providing the value.
Get the Blob service SAS URL value from the Storage Account.
In Azure Portal => Create a Storage Account.
Initially the option to generate SAS is disabled for me.
Navigate to your Storage Account => Shared access signature = > select Container and Object checkboxes.
An option to Generate SAS and connection string will be enabled.
Copy the Blob service SAS URL and provide the value in either local Configuration settings or in Azure App Service => Configuration => Application Settings.
In Azure App Service Settings
Save the settings and access the URL.
My question before is that once i generate Generate SAS and Conection string and copy to clip board.
Even if you generate the SAS again, the value will be same till here - https://yourSA.blob.core.windows.net/?sv=2021-06-08&ss=*****=co&sp=******&se=2022-12-05T14:.
Even we can add the SAS token in App settings automatically. Follow the below steps.
In Azure App Service => App Service logs = >set Application logging (Blob) to On and continue the steps to add the Storage Account. If you don't have create a new Storage Account.
"Unable to find mscorlib assembly reference:.
Make sure you are using the latest package references.
Update the framework version 4.7.2 to 4.8 in VS. Rebuild and Re-deploy the App.

Pass arguments to IDesignTimeDbContextFactory of EF Core

How can we pass arguments to dotnet ef database update?
i want to be able to update different database with the use of arguments.
i've tried
dotnet ef database update "Accept"
dotnet ef databse update Accept
but it didn't work..
Or how I can put a switch to get different conenctionString from my configuration?
public ProjectContext CreateDbContext(string[] args)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
// Find a way to get different connection string
var connectionString = configuration.GetConnectionString(args[0]);
var builder = new DbContextOptionsBuilder<ProjectContext >();
builder.UseSqlServer(connectionString);
return new ProjectContext(builder.Options);
}
.NET 5 releases in a couple weeks from the time of this answer. So this is possible to change.
Answer Now
The .NET 5, and the associated EF Core 5+ NuGets support this. In Package Manager you can type:
Add-Migration YourMigrationName -Args "Space Separated Args"
Update-Database -Args "Space Separated Args"
For example, I use this:
Update-Database -Args MyConnName
In my Startup project I have a config file (Or appsettings.json) that has that connection string key, and I pull that in.
Note I said .NET Core 5. This will be have a full release in a few weeks from now. So in a few weeks this answer may be simple. But until then, you may need to install Preview versions (And NuGet PreReleases)
Answer Prior to now
There were lacking options when this question was asked, though there were options, like using dotnet ef commands with AppArgs, as discussed here. But these have changed, and are also now accessible from PM Console as discussed in the above "Now" answer.
You can also set variables like this:
$env:SqlConnectionString="Server=tcp:mySqlServerStuffxxx"
Add-Migration InitialCreate
Update-Database
Source:
https://dev.to/azure/using-entity-framework-with-azure-functions-50aa#adding-an-entity-framework-migration
It won't work for ConnectionStrings.DefaultConnection though. It will give the following error:
The property 'DefaultConnection' cannot be found on this object.
Verify that the property exists and can be set.
from everything I ready here I basically ended up with CreateDbContext(string[] args) the args will get populated with anything after you initial CMD
The -- token directs dotnet ef to treat everything that follows as an
argument and not try to parse them as options. Any extra arguments not
used by dotnet ef are forwarded to the app.
more here
will result with args being populated with 4 args
this works as the -- passes the all else back to dotnet to set the args
As an example, when adding IDesignTimeDbContextFactory<YourContext> interface to your Context adds the following method and this is where I am able to pass in the vars
public DataBaseContext CreateDbContext(string[] args)
{
Debugger.Launch();
Console.WriteLine($#"Args:");
foreach (var arg in args)
{
Console.WriteLine($"Arg: {arg}");
}
}
this will write out the 4 vars passed in -test something -testagain again
I post this answer to help expand on other answers here and see the full context
Hope this answer will help people who are trying to resolve this using .net cli.
Custom arguments can be passed to IDesignTimeDbContextFactory<T> using -- token as mentioned earlier, but I found missing actual example showing that basically there is no rule how you define them, e.g. can be -- -DbUser Admin, -- DbUser=Admin. Just make sure there is a space separator following --. The rest is forwarded to design time context factory automatically.
With all this in mind the sample usage may look like:
dotnet ef database update -c YourDbContext -- -DbUser Admin -Password Secret
dotnet ef database update -c YourDbContext -- DbUser=Admin Password=Secret
Latter seems makes more sense as parameters arrive in single dimension array, so have to map param name with param value manually if you choose the first example. Also second one looks more clear to me as extra dashes make it more confusing.
More information here: learn.microsoft.com
I had a similar issue recently trying to get an Asp.Net Core app to read the connection string. It turns out that you don't need the IDesignTimeDbContextFactory. Instead, just make sure that your context has a paramerless constructor, and use something like this in the startup:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
This should resolve to whichever connection string you have configured. If you did want to use two separate connections at the same time (which I realise you didn't want), you could do this by registering multiple DbContexts at this point; for example:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("OtherConnection")));

Permission for event log used in SSRS custom extension

we are have written one custom input language translator SSRS extension which gets input and convert it into another language and send back. In this extension we have written a code to write error messages using event logger. When we running our SSRS reports they are showing message error!. But we are not getting any error in event logger only in SSRS trace log it returns "Data not found at parameter 5".
Following is sample asp.net code. Please do let us know permissions needed on extension so that we can write event log. We are getting error at Eventlog.SourceExists in below code.
System.Diagnostics.EventLogPermission pEventLog = new EventLogPermission(System.Security.Permissions.PermissionState.Unrestricted);
pEventLog.Assert();
if (!EventLog.SourceExists("Report Server"))
{
myLog = new EventLog();
myLog.Source = "Report Server";
}
According to Microsoft, you will not be able to acquire EventLogPermission unless the process is running with Administrator permissions.
https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogpermission(v=vs.110).aspx
This sounds pretty risky to me. You might want to use a different logging mechanism (like Log4Net, etc).

Difference between starting process from Console applciation and ASP.NET application

I have a Web API application that needs to run a Python script which in turn runs a Perl script:) does some otehr stuff and get the output results from it.
The way I do this is with starting a Process:
var start = new ProcessStartInfo()
{
FileName = _pythonPath, //#"C:\Python27\python.exe",
Arguments = arguments, //#"D:\apps\scripts\Process.py
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
var result = reader.ReadToEnd();
var err = process.StandardError.ReadToEnd();
process.WaitForExit();
return result;
}
}
The script inside tries to connect to Perforce server using P4 Python API and then Perl script call a P4 command as well. When running this code from Console application, everything goes fine. The program automatically gets the Perforce settings (I've got a P4V client with all the settings specified). But when running from ASP.NET Web API, it doesn't get the settigns and says that it cannot conenct to perforce:1666 server (I guess this is the standard value when no settign specified).
I do understand that not so many people use Perforce, especially in such way and can help here, but would like to know what is the difference between running this script from Console app and Web API app that mich cause this different behaviour.
One of the most obvious differences between running code from a console application and running code in IIS* is that, usually, the two pieces of code will be running under different user accounts.
Frequently, if you're experiencing issues where code works in one of those situations and not the other, it's a permissions or a per-user-settings issue. You can verify whether this is the case by either running the console application under the same user account that is configured for the appropriate IIS application pool, or vice verse, configure the application pool to use your own user account, and then see whether the problem persists.
If you've confirmed that it's a permissions issue and/or per-user-settings, then you need to decide how you want to fix it. I'd usually recommend not running IIS application pools under your own user account - if you cannot seem to get the correct settings configured for the existing application pool user, I'd usually recommend creating a separate user account (either locally on the machine or as part of your domain, depending on what's required) and giving it just the permissions/settings that it requires to do the job.
*IIS Express being the exception here because it doesn't do application pools and the code does end up running under your own user account.

Problem with Unit testing of ASP.NET project (NullReferenceException when running the test)

I'm trying to create a bunch of MS visual studio unit tests for my n-tiered web app but for some reason I can't run those tests and I get the following error -
"Object reference not set to an
instance of an object"
What I'm trying to do is testing of my data access layer where I use LINQ data context class to execute a certain function and return a result,however during the debugging process I found out that all the tests fail as soon as they get to the LINQ data context class and it has something to do with the connection string but I cant figure out what is the problem.
The debugging of tests fails here(the second line):
public EICDataClassesDataContext() :
base(global::System.Configuration.ConfigurationManager.ConnectionStrings["EICDatabaseConnectionString"].ConnectionString, mappingSource)
{
OnCreated();
}
And my test is as follows:
TestMethod()]
public void OnGetCustomerIDTest()
{
FrontLineStaffDataAccess target = new FrontLineStaffDataAccess(); // TODO: Initialize to an appropriate value
string regNo = "jonh"; // TODO: Initialize to an appropriate value
int expected = 10; // TODO: Initialize to an appropriate value
int actual;
actual = target.OnGetCustomerID(regNo);
Assert.AreEqual(expected, actual);
}
The method which I call from DAL is:
public int OnGetCustomerID(string regNo)
{
using (LINQDataAccess.EICDataClassesDataContext dataContext = new LINQDataAccess.EICDataClassesDataContext())
{
IEnumerable<LINQDataAccess.GetCustomerIDResult> sProcCustomerIDResult = dataContext.GetCustomerID(regNo);
int customerID = sProcCustomerIDResult.First().CustomerID;
return customerID;
}
}
So basically everything fails after it reaches the 1st line of DA layer method and when it tries to instantiate the LINQ data access class...
I've spent around 10 hours trying to troubleshoot the problem but no result...I would really appreciate any help!
UPDATE:
Finally I've fixed this!!!!:) I dont know why but for some reasons in the app.config file the connection to my database was as follows:
AttachDbFilename=|DataDirectory|\EICDatabase.MDF
So what I did is I just changed the path and instead of |DataDirectory| I put the actual path where my MDF file sits,i.e
C:\Users\1\Documents\Visual Studio 2008\Projects\EICWebSystem\EICWebSystem\App_Data\EICDatabase.mdf
After I had done that it worked out!But still it's a bit not clear what was the problem...probably incorrect path to the database?My web.config of ASP.NET project contains the |DataDirectory|\EICDatabase.MDF path though..
Is LINQDataAccess.EICDataClassesDataContext looking to the web.config or some other outside source of data for its setup?
I can tell you for a fact that you must jump thru hoops to get web.config accessible to your test code.
Update
Ah, yes. I see that you're using ConfigurationManager on the line where your test fails... ConfigurationManager looks to web.config for configuration. This has been a sticking point for me when I write my tests.
You need to either change the code so that the class can be instantiated without web.config, or you need to make it so that your tests can access web.config.
Does your test project have it's own configuration file? This type of behavior usually means the app can't find the connection string. Test projects require their own file since they are not running in the context of the client app.
UPDATE The error you describe after adding an app.config is common when testing web applications built on SQLExpress and attaching an .mdf. SQLExpress cannot be run in more than one process at a time. So if you have previously run your web application it may still be active and will conflict with the attempt to attach the database.
You can use SQL Management Studio to attach the database permanently and then use a more traditional connection string like:
Server=myServer;Database=EICDatabase;Trusted_Connection=True;
For me it seems like your problem is the connection string, which is not set.
I assume your unit test is in a different project than the DAL.
You call the 'new' command on the datacontext constructor without a connection string. So it should usually use its default, when set. But since this setting normally is stored in the web.config of the other project there is no connection string set and you get the error.
If its right, what i assume, you have to get the settings from the DAL project into the unit-testing project. Simplest solution should be to copy web.config connection string to app.config of unit test project.
There are other possibilities for sure, but i think its not easy to get the web.config configuration into your unit-testing project.

Resources