debugsqlMinor
Error publishing SQLCLR C# Function using Visual Studio 2017
Viewed 0 times
errorvisualsqlclrfunctionpublishingusingstudio2017
Problem
I'm trying to (learn) publish a SQLCLR function using Visual Studio 2017. (It's a simple function that sends an email.)
As a reference I used this articles on CodeProject and MSSQLTips:
Create, Run, Debug and Deploy SQL CLR Function with Visual Studio 2013 Database Project
Send Email from SQL Server Express Using a CLR Stored Procedure
On project properties->SQLCLR I've set:
And according to the article I've updated target databases:
And after I've got the error I've followed this advice on MSSQLTips article:
If you get error messages when trying to compile the code you may need to alter the database using the following command and then try again to create the assembly and the stored procedure.
I've tried using two different target databases:
I can build the project without errors, but when I publish the project I receive one error when it executes the next command:
(47,1): SQL72014: .Net SqlClient Data Provider: Msg 10327, Level 14, State 1, Line 1 CREATE ASSEMBLY for assembly 'dbSysmac' failed because assembly 'dbSysmac' is not trusted. The assembly is trusted when either of the following is true: the assembly is signed with a certificate or an asymmetric key that has a corresponding login with UNSAFE ASSEMBLY permission, or the assembly is trusted using sp_add_trusted_assembly.
What I'm doing wrong?
As a reference I used this articles on CodeProject and MSSQLTips:
Create, Run, Debug and Deploy SQL CLR Function with Visual Studio 2013 Database Project
Send Email from SQL Server Express Using a CLR Stored Procedure
On project properties->SQLCLR I've set:
Permission level : UNSAFEAnd according to the article I've updated target databases:
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GOAnd after I've got the error I've followed this advice on MSSQLTips article:
If you get error messages when trying to compile the code you may need to alter the database using the following command and then try again to create the assembly and the stored procedure.
ALTER DATABASE msdb SET trustworthy ONI've tried using two different target databases:
- SQL-Server 2017 LocalDB
- SQL-Server 2017 Express
I can build the project without errors, but when I publish the project I receive one error when it executes the next command:
CREATE ASSEMBLY [dbSysmac]
AUTHORIZATION [dbo]
FROM 0x5F8A900003000000...
WITH PERMISSION_SET = UNSAFE;(47,1): SQL72014: .Net SqlClient Data Provider: Msg 10327, Level 14, State 1, Line 1 CREATE ASSEMBLY for assembly 'dbSysmac' failed because assembly 'dbSysmac' is not trusted. The assembly is trusted when either of the following is true: the assembly is signed with a certificate or an asymmetric key that has a corresponding login with UNSAFE ASSEMBLY permission, or the assembly is trusted using sp_add_trusted_assembly.
What I'm doing wrong?
Solution
I've updated target databases:
Just to be clear, "clr enabled", and
I've followed this advice on MSSQLTips article
Yikes. Well, that article on MSSQLTips is more of a problem than the error that you are getting. It would be best if you forgot everything you saw in that article and never looked at it again. It is full of bad advice:
SQLCLR vs. SQL Server 2017, Part 2: "CLR strict security" - Solution 1
What database are you actually publishing to? Assuming that you are publishing to another database that is not
Now, if you are executing the
Your options are:
-
If you are deploying database properties:
To enable
-
If you are not deploying database properties:
Enable trustworthy in the database where you are deploying the assembly (enabling
-
Once you have this working correctly in development, handle security properly before pushing to production:
SQLCLR vs. SQL Server 2017, Part 2: "CLR strict security" - Solution 1
For learning more about SQLCLR in general, please visit: SQLCLR Info. Be sure to check out the "Stairway to SQLCLR" link, which is a series I am writing on this topic on SQL Server Central.
sp_configure 'clr enabled', 1;Just to be clear, "clr enabled", and
sp_configure in general, are instance-level, not database-level configuration.I've followed this advice on MSSQLTips article
Yikes. Well, that article on MSSQLTips is more of a problem than the error that you are getting. It would be best if you forgot everything you saw in that article and never looked at it again. It is full of bad advice:
- SQLCLR not required for sending email in SQL Server Express (I have tested this and it does work). HOWEVER, it does not work in SQL Server Express LocalDB :-(
- You should use
SqlStringinstead ofStringfor input parameter types (and for return types)
- Deploying to
msdb? Maybe it's just me, but I would never deploy code tomsdb(and I would only add code tomasterif it is physically required, such as when marking a proc as either a start up proc or as a system proc).
UNSAFEpermission set? Why? For email? The assembly should beEXTERNAL_ACCESS. Code (assemblies, logins, users, or anything else) shouldn't be given more permissions than necessary.
- Setting
TRUSTWORTHY ONformsdbis two problems in one:
- Setting
TRUSTWORTHY ONis lazy. Sure, it's fine for doing proof-of-concepts / quick tests, but it is not a good long-term / production-level option. It's a huge security risk. Instead, Module Signing should be used. Here is a guide I wrote for how to accomplish this, and do so within Visual Studio:
SQLCLR vs. SQL Server 2017, Part 2: "CLR strict security" - Solution 1
TRUSTWORTHYis alreadyONformsdb. At least it isONby default.
- The
@bodyinput parameter should beNVARCHAR(MAX), notNVARCHAR(4000). This is, after all, HTML email (i.e.myMessage.IsBodyHtml = True)
- No, absolutely do not store your plain-text email password in the .NET code. DLLs / Assemblies are not encrypted. ALL strings are stored as-is at the end of the EXE / DLL / Assembly. It takes almost no effort to display the contents of an assembly, and if you follow this advice, your SMTP server, login, and password will be stored for anyone to see. Either pass those in from a variable, or do a simple query to select from a table. You might even be able to get them from the Windows Registry.
What database are you actually publishing to? Assuming that you are publishing to another database that is not
msdb, then you, at least simplistically, in this moment to move forward, need to set TRUSTWORTHY ON for the DB that you are publishing to. But again, enabling TRUSTWORTHY is just for testing (please see: PLEASE, Please, please Stop Using Impersonation, TRUSTWORTHY, and Cross-DB Ownership Chaining).Now, if you are executing the
ALTER DATABASE... manually and then still get the error upon publishing, then most likely you have the "deploy database properties" option selected (in Visual Studio: go to "Project Properties" | "Debug" tab | "Deployment Options" area towards the bottom). TRUSTWORTHY is one of those database properties. So, when "deploy database properties" is checked, then every deployment will set the options to match what is defined in the project. And by default, Trustworthy is not enabled.Your options are:
-
If you are deploying database properties:
To enable
Trustworthy in Visual Studio (for deployments): go to "Project Properties" | "Project Settings" tab | "Database Settings..." button | "Miscellaneous" tab. Check the box for "Trustworthy" and then click the "OK" button.-
If you are not deploying database properties:
Enable trustworthy in the database where you are deploying the assembly (enabling
TRUSTWORTHY in msdb won't help)-
Once you have this working correctly in development, handle security properly before pushing to production:
SQLCLR vs. SQL Server 2017, Part 2: "CLR strict security" - Solution 1
For learning more about SQLCLR in general, please visit: SQLCLR Info. Be sure to check out the "Stairway to SQLCLR" link, which is a series I am writing on this topic on SQL Server Central.
Code Snippets
sp_configure 'clr enabled', 1;Context
StackExchange Database Administrators Q#227619, answer score: 2
Revisions (0)
No revisions yet.