sqlFileStream System.ComponentModel.Win32Exception: The request is not supported - c#

I have SQL server express 2008 SP1 on windows 7 (Version 6.1 Build 7601: Service Pack 1) and visual studio 2010.
I am attempting to create a Stored Procedure CLR for inserting a file into a file stream using the following code.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.IO;
using System.Security.Principal;
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void sp_fileController(String friendlyName, String filePath)
{
SqlParameter fDataParam = new System.Data.SqlClient.SqlParameter("#fData", SqlDbType.VarBinary, -1);
SqlParameter fNameParam = new System.Data.SqlClient.SqlParameter("#fName", SqlDbType.NVarChar, 300);
WindowsIdentity newId = SqlContext.WindowsIdentity;
WindowsImpersonationContext impersonatedUser = newId.Impersonate();
try
{
string cs = #"Server=[myservername];Integrated Security=true";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
SqlTransaction objSqlTran = con.BeginTransaction();
//string sql = "INSERT INTO fileStreamTest VALUES ((Cast('' As varbinary(Max))), #fName, default); Select fData.PathName() As Path From fileStreamTest Where fId = SCOPE_IDENTITY()";//OUTPUT inserted.fid
SqlCommand insertFileCommand = con.CreateCommand();
insertFileCommand.Transaction = objSqlTran;
insertFileCommand.CommandText = "INSERT INTO fileStreamTest.dbo.fileStreamTest (RowGuid, fData) VALUES (#FileID, CAST ('' as varbinary(max)))";
Guid newFileID = Guid.NewGuid();
insertFileCommand.Parameters.Add("#FileID", SqlDbType.UniqueIdentifier).Value = newFileID;
insertFileCommand.ExecuteNonQuery();
SqlCommand getPathAndTokenCommand = con.CreateCommand();
getPathAndTokenCommand.Transaction = objSqlTran;
getPathAndTokenCommand.CommandText =
"SELECT fData.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() " +
"FROM fileStreamTest.dbo.fileStreamTest " +
"WHERE rowGuid = #FileID";
getPathAndTokenCommand.Parameters.Add("#FileID", SqlDbType.UniqueIdentifier).Value = newFileID;
SqlDataReader tokenReader = getPathAndTokenCommand.ExecuteReader(CommandBehavior.SingleRow);
tokenReader.Read();
SqlString filePathName = tokenReader.GetSqlString(0);
SqlBinary fileToken = tokenReader.GetSqlBinary(1);
tokenReader.Close();
SqlFileStream sqlFile = new SqlFileStream(filePathName.Value, fileToken.Value, System.IO.FileAccess.ReadWrite);
sqlFile.Close();
objSqlTran.Rollback();
//objSqlTran.Commit();
con.Close();
}
}
finally
{
impersonatedUser.Undo();
}
}
};
However when it gets to the line:
SqlFileStream sqlFile = new SqlFileStream(filePathName.Value, fileToken.Value, System.IO.FileAccess.ReadWrite);
I get:
A .NET Framework error occurred during execution of user-defined routine or aggregate "sp_fileController":
System.ComponentModel.Win32Exception: The request is not supported
System.ComponentModel.Win32Exception:
at System.Data.SqlTypes.SqlFileStream.OpenSqlFileStream(String path, Byte[] transactionContext, FileAccess access, FileOptions options, Int64 allocationSize)
at System.Data.SqlTypes.SqlFileStream..ctor(String path, Byte[] transactionContext, FileAccess access, FileOptions options, Int64 allocationSize)
at System.Data.SqlTypes.SqlFileStream..ctor(String path, Byte[] transactionContext, FileAccess access)
at StoredProcedures.sp_fileController(String friendlyName, String filePath)
Can anyone tell me how to fix this issue? Is simply that I cannot execute the code in this manner with sql 2008 express edition?

I think I have found working solution here:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/f49def09-3b47-4e54-8a53-2dd47762821e/filestream-on-windows-server-2012-the-request-is-not-supported?forum=sqldatabaseengine
To sum up: Adding registry key solved the problem on SQL Server 11.0.7001:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\FsctlAllowlist]
"FSCTL_SQL_FILESTREAM_FETCH_OLD_CONTENT"=dword:0x00092560

As odd as it sounds Microsoft intentionally blocked the use of the SqlFileStream class usages inside SQL CLR assemblies (even if you grant EXTERNAL_ACCESS or declare the assembly as UNSAFE) as you can read in Microsoft Connect issue 768308.
However you can access the FILESTREAM as a stream by the means of the SqlBytes type (a really nice tip found on a blog post).. at least for read-only use, I've never tried writing.
I copy-past the code in case the blog disappears (in a slightly improved version with proper disposal of objects):
using System;
using System.IO;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Security.Cryptography;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true, SystemDataAccess = SystemDataAccessKind.None)]
public static SqlBinary Hash(SqlBytes source, SqlString hashAlgorithmName)
{
if (Source.IsNull)
{
return null;
}
using (HashAlgorithm ha = GetHashAlgotithm(hashAlgorithmName.Value))
using (Stream stream = Source.Stream)
{
return new SqlBinary(ha.ComputeHash(source.Stream));
}
}
}
I can confirm this definitely works for read-only access. I've never tried for write access (I'm writing FILESTREAM data from an external C# Windows Service or Web Application).

Related

Using Odbc driver query given result in database but not filling datatable in c#, there is no error

Just started using windows 11 and installed Oracle drivers for 32Bit and 64Bit, wrote program using C# to fetch data from Oracle database.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data.Odbc;
using System.Data;
using System.Data.SqlClient;
namespace ApexAutoEmailConsol
{
static class ServiceLog
{
static String connectionString = "Dsn=Prod21_32;uid=ebseb;pwd=ebseb";
static string strQuery = string.Empty;
public static string OutstandingInvoices()
{
try
{
OdbcConnection oCon = new OdbcConnection();
oCon.ConnectionString = connectionString;
oCon.Open();
DataTable dtSales = new DataTable();
strQuery = "SELECT * from apps.org_organization_definitions HO";
// if I run above query in Toad it's giving result.
OdbcDataAdapter myAdp = new OdbcDataAdapter(strQuery, oCon);
myAdp.Fill(dtSales);
//Adapter not filling data to the datatable.
if (dtSales.Rows.Count <= 0)
{
return "";
}
return strReturn;
}
catch (Exception Ex)
{
WriteErrorLog(Ex.ToString());
return "";
}
}
}
When I copy strQuery and run on Toad, getting result but datatable is still empty.
What is the problem? The same code is working perfect on my Windows10 machine.
UnCOMMITted data is only visible within the session that created it (and will ROLLBACK at the end of the session if it has not been COMMITted). If you can't see the data from another session (C#) then make sure you have issued a COMMIT command in the SQL client (Toad).
If you have issued a COMMIT and still can't see the data then make sure that both the SQL Client (Toad) and the C# program are connecting to the same database and are querying the same user's schema of that database.
It's very unique problem, I had it around 2 years ago with my another machine, where I was not able to get some query result in Toad. Some queries are working but some of with specific table in joing was giving empty result. That time I added following language setting in my environment variable and was worked.
NLS_LANG = American_America.UTF8
Used same in my new machine and now am getting result with Visual Studio 2022.

XML to String from Database call - MVC

I'm trying to recycle an approach found here
to call a stored procedure from SQL Server, receive an XML response, render the response to a string variable, and process it against an XLST template. I can't seem to get the string variable created correctly. Here's what I'm doing in my controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.SqlClient;
using System.Configuration;
using Demo2.Models;
namespace Demo2.Controllers
{
public class CfsController : Controller
{
// GET: Cfs
public ActionResult Report()
{
{
SqlConnection con = new SqlConnection("data source=.; database=Test; integrated security=SSPI");
SqlCommand cmd = new SqlCommand("EXEC [TEST].[REPORTSERV].[CFSREPORT] #CFSNUMBER = N'010101-10';", con);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
string response = rdr.ToString();
con.Close();
ViewBag.CurrentReport = response;
return View();
}
}
}
}
When I run the code I'm getting an error in the transform step in the tranformObj.Transform(reader, args, writer) step of the helper CS.
I believe the issue is caused by the string response variable not taking the XML response from the SQL Server as a string.
Since my stored procedure is going to return only one record (an XML response), I've changed ExecuteReader to ExecuteScalar and converted the response into a string. It's now working but it looks like some of the XML files I'm getting back are exceeding the size of the string variable.
string rdr = cmd.ExecuteScalar().ToString();
ViewBag.CurrentReport = rdr;
You never provided your SP source code... So it is assumed that it returns an XML data type.
You need to change the following two lines:
SqlDataReader rdr = cmd.ExecuteReader();
string response = rdr.ToString();
To the following:
using (XmlReader reader = cmd.ExecuteXmlReader())
{
XDocument xdoc = XDocument.Load(reader);
string response = xdoc.ToString();
}

SQL connection string in web service c#

Hi I'm having a problem finding the correct connection statement for my web-service to an sql-server database. I'm trying to retrieve data from my database to check a users login details.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
namespace BTC_Service
{
public class UseDatabase
{
SqlConnection sqlConn;
internal Boolean Connect()
{
try
{
sqlConn = new SqlConnection(#"Integrated Security=true; Initial Catalog=BTCFS_DataBase; Data Source=.\SQLEXPRESS;");
sqlConn.Open();
return true;
}
catch (SqlException ex)
{
return false;
}
}
internal void DisconnectDatabase()
{
sqlConn.Close();
}
internal Boolean ExecuteCommand(String query)
{
try
{
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = query;
cmd.ExecuteNonQuery();
return true;
}
catch (SqlException ex)
{
return false;
}
}
internal SqlDataReader ExecuteQuery(String query)
{
try
{
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = query;
return cmd.ExecuteReader();
}
catch (SqlException ex)
{
return null;
}
}
}
}
The database is created with sql-server 2008 and the path for it is:
C:\BTCFS_DataBase\db_BTDC_data.mdf
and the log file
C:\BTCFS_DataBase\db_BTDC_log.ldf
There is no password for the database and the code is as follows:
USE master
GO
create database db_BTCFC
ON PRIMARY
(
NAME = 'db_BTCFC_Data',
FILENAME = 'c:\BTCFS_DataBase\db_BTDC_data.mdf',
SIZE = 5MB,
FILEGROWTH = 10%
)
LOG ON
(
NAME = 'db_BTFC_log',
FILENAME = 'c:\BTCFS_DataBase\db_BTDC_log.ldf',
SIZE = 5MB,
FILEGROWTH = 10%
)
GO
Is there any suggestion to what I am doing wrong?
Should I add the database to visual studio in a specific way?
Or am i creating my database in the wrong way?
Thank you in advance.
The fact that you are connected using Integrated Security, means that your local user account on Windows should be authenticated on the SQL server instance which is hosted locally on your machine (evident by the "." in the Data Source, which refers to your local machine). It might be that the setup of your SQL server instance doesn't accommodate windows authentication. Check that your configuration allows for "mixed mode" authentication, i.e. either Windows authentication or username/password authentication...
I found this statement to be more effective than the previous one:
sqlConn = new SqlConnection(#"Integrated Security=SSPI; Initial Catalog=BTCFS_DataBase; Data Source=localhost");
Thanks #Wolfish for the link.

How do I create a MySql database connection that returns results to a text file?

I want to write a MySql statement that will connect to the database, select a column from the table, then output that data to a text file to a specific location on my computer. I have searched the internet for a couple days now and don't seem to find the answer I am looking for. I am fairly new to c#, MySql, and Visual Studio. I am just trying to learn how to write the correct statements and get the desired result. Any help would be greatly appreciated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
using MySql.Data;
using System.Windows.Forms;
using System.IO;
namespace NewPractice
{
public class Connect
{
static void Main()
{
string results = #"server=111.111.11.111; userid=anyone;
password=anypassword; database=anydatabase";
MySqlConnection conn = null;
try
{
conn = new MySqlConnection(results);
conn.Open();
//Console.WriteLine(
File.WriteAllLines(
#"C:\Documents and Settings\anyone\My Documents\Tests\testoutput.txt",
results.ToArray());
}
catch (MySqlException ex)
{
Console.WriteLine("Error: (0)", ex.ToString());
}
finally
{
if (conn != null)
{
conn.Close();
}
}
}
}
}
You're writing the contents of the result string to the file, not the data you're attempting to select. You need to run a sql command and get a SqlDataReader object to write your data to the file.
string results = #"server=111.111.11.111; userid=anyone;
password=anypassword; database=anydatabase";
MySqlConnection connection = new MySqlConnection(results);
MySqlCommand command = connection.CreateCommand();
MySqlDataReader reader;
command.CommandText = "select * from mycustomers";
connection.Open();
reader = command.ExecuteReader();
using(var sw = new StreamWriter("C:\MyPath\MyFile.txt"))
{
while (reader.Read())
{
var row = (IDataRecord)reader;
sw.WriteLine(row["myColumn"]);
}
}
connection.Close();
If the database is on your local machine you can use 'select .. into outfile'. http://dev.mysql.com/doc/refman/5.1/en/select-into.html. This will write to a folder on the server so it's not v useful if it's a different machine and you can't copy from there.
There are plenty of tutorials out there for accessing MySQL from .NET.
This is one: http://zetcode.com/db/mysqlcsharptutorial/
In any language, there are a few simple steps to read from a database:
1. connect to the database.
2. execute a query
3. iterate through the results of the query
4. close the connection.
What you are doing in your code is connecting to the database and then trying to write the connection information to a file.

Cannot Connect to Oracle in C#

I am trying to connect to Oracle in a 32-bit Console Application. I am getting the following erorr. The code (with the exception of host, username, and password change) is below. It is a simple two function project.
Any help will be appreciated.
I am using C# in Visual Studion 2010 Premium and Oracle 10g. I can connect to the database with Oracle SQL Developer with the information set in the connection string.
---------------ToString--------------------------
--Oracle.DataAccess.Client.OracleException at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure)
at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, Oracle
Connection conn, IntPtr opsErrCtx, Object src)
at Oracle.DataAccess.Client.OracleConnection.Open()
at ConsoleApplication1.Program.GetConnection() in c:\users\maholt\documents\visual studio 2010\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 61
---------------Message---------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Oracle.DataAccess.Client;
namespace ConsoleApplication1
{
class Program
{
static OracleConnection conn;
static void Main(string[] args)
{
OracleConnection connC = GetConnection();
conn = connC;
simpleQuery();
Console.WriteLine("DONE");
}
public static void simpleQuery()
{
OracleCommand cmd = new OracleCommand("select count(*) as total from console.client");
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
try
{
cmd.Connection.Open();
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(Convert.ToString(reader["total"]));
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
cmd.Dispose();
}
}
public static OracleConnection GetConnection()
{
Oracle.DataAccess.Client.OracleConnection rtn = null;
try
{
string connstr = "Data Source=//10.10.10.10:1521/PRD2_OLTP;User Id=user; Password=pass;";
rtn = new Oracle.DataAccess.Client.OracleConnection(connstr);
if (rtn.State != System.Data.ConnectionState.Open)
{
rtn.Open();
}
}
catch (Exception ee)
{
Console.WriteLine("-------------------------------------------------");
Console.WriteLine("---------------ToString--------------------------");
Console.WriteLine("--" + ee.ToString());
Console.WriteLine("---------------Message---------------------------");
Console.WriteLine("--" + ee.Message);
Console.WriteLine("-------------------------------------------------");
}
return (rtn);
}
}
}
SQL Developer uses effectively JDBC connection... so it is not really comparable with what happens in .NET :-(
Regarding the Oracle versus .NET version compatibility - I found this rather problematic esp. since the clients don't have always the option to update according to Oracle roadmap...
After researching some I switched to using the Devart components - support everything from Oracle 7.3 up to 11gR2 in .NET 2 up with 32 and 64 bit and come with a "direct-mode option" which means if need be I can run my app without any Oracle client being installed on the machine... not affiliated, just a happy customer...
First - Oracle doesn't support 10g with .net 4.0. You must use 11.2.0.2 or higher to be compliant with Oracle's supported versions.
Second - The problem is you probably don't have ODP.Net installed correctly. This can mean it isn't installed, it was installed to a second instance, or it failed to copy on or more files during installation.
I have some blog posts about these items along with a link to some connection testing applications I wrote. Feel free to use them.
https://tsells.wordpress.com/category/oracle/

Categories