C# MSSQL base64 插入和 select。数据不同
C# MSSQL base64 insert and select. Data differs
我在这里遇到了一些挑战,我希望你们中的一些聪明人可以 guide/show 给我一个解决方案。
为了方便您,代码已经 condensated/cut 降低了一点。如果出现程序错误,那是因为那个。
该程序的任务是从 URL 下载 pdf,并将 PDF 保存在 MS SQL 服务器上。
我可以保存它,但数据似乎发生了变化。例如。下载的 PDF 的第一个字节是 25h(正确),当我将其保存在数据库中时,它变为 1Fh(错误)。
我意识到这一定是下载和保存之间的转换,可惜我做不到。
// This is where I suspect that my problem occurs.
byte[] myDataBuffer = client.DownloadData((new Uri(strFileUrlToDownload)));
如果我写的不清楚,请原谅。英语不是我的母语。
提前致谢。
用于创建 table 的脚本和下面的 C# 代码。
用于在 MS SQL 服务器上创建 table 的脚本:
SET [ThePartikularDatabase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[PDFTable](
[DokumentAID] [int] IDENTITY(1,1) NOT NULL,
[ident] [nchar](10) NOT NULL,
[AB] [nchar](10) NOT NULL,
[BI] [nchar](10) NOT NULL,
[dokumentType] [nchar](10) NOT NULL,
[base64] [varbinary](max) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
代码来了:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Web;
using System.Web.Script.Serialization;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using System.Web.UI;
using System.Text.RegularExpressions;
namespace test
{
class program
{
public static void DownloadData(string strFileUrlToDownload, WebClient client, string IV_ident, string IV_AB, string IV_BI, string IV_dokumentType)
{
// This function is made with inspiration from:
// http://www.c-sharpcorner.com/UploadFile/013102/save-and-read-pdf-file-using-sql-server-and-C-Sharp/
byte[] myDataBuffer = client.DownloadData((new Uri(strFileUrlToDownload)));
//string encodedText = Convert.ToBase64String(myDataBuffer);
//string decodedText = Encoding.UTF8.GetString(myDataBuffer);
// byte[] lars = Convert.ToByte(encodedText);
using (SqlConnection cn = new SqlConnection(GlobalVar.ConnectionString))
{
cn.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO [Database].[dbo].[PDFTable] " + "(Ident, AB, BI, dokumentType, base64) values (@ident, @AB, @BI, @dokumentType, @data);", cn))
{
cmd.Parameters.Add("@data", myDataBuffer);
cmd.Parameters.Add("@Ident", ident);
cmd.Parameters.Add("@AB", IV_AB);
cmd.Parameters.Add("@BI", IV_BI);
cmd.Parameters.Add("@dokumentType", IV_dokumentType);
cmd.ExecuteNonQuery();
}
}
using (SqlConnection cn = new SqlConnection(GlobalVar.ConnectionString))
{
cn.Open();
using (SqlCommand cmd = new SqlCommand("SELECT [base64] FROM [Database].[dbo].[PDFTable] WHERE ident = " + IV_ident + " ;", cn))
{
using (SqlDataReader dr = cmd.ExecuteReader(System.Data.CommandBehavior.Default))
{
if (dr.Read())
{
byte[] fileData = (byte[])dr.GetValue(0);
using (System.IO.FileStream fs = new System.IO.FileStream("c:\" + IV_ident + ".pdf", System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
{
using (System.IO.BinaryWriter bw = new System.IO.BinaryWriter(fs))
{
bw.Write(fileData);
bw.Close();
}
}
}
dr.Close();
}
}
}
}
public static void SaveMemoryStream(MemoryStream ms, string FileName)
{
FileStream outStream = File.OpenWrite(FileName);
ms.WriteTo(outStream);
outStream.Flush();
outStream.Close();
}
static void Main(string[] args)
{
int LI_start = 0;
int LI_slut = 0;
int LI_documentURL = 0;
string LS_ident = "";
string credentials = "Username:Password";
string url = "http://pdfurl.com/find;
CredentialCache mycache = new CredentialCache();
WebClient client = new WebClient();
client.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
Regex regex = new Regex("");
try
{
/*
ident is fetched from our database. Code removed for simplicity..
*/
LS_ident = Convert.ToString(theRow["ident"]);
string LS_json = "{\"from\":0,\"size\":1,\"query\":{\"term\":{\"ident\":" + LS_ident + "}}}";
string LS_pdfURL = "";
string reply = client.UploadString(url, "POST", LS_json);
/********************************************************/
/* Regex ************************************************/
/*
URL for the pdf is taken from the reply with Regular expression.
*/
/* Regex ************************************************/
/********************************************************/
LS_pdfURL = "" + dokURL[i].Substring(LI_start, (LI_slut + 1 - LI_start)) + "pdf";
/*
LS_pdfURL now contains the correct path for the pdf.
I can manually download the pdf with the url. It works.
So far, so good.
*/
DownloadData(LS_pdfURL, client, LS_ident, "StartDato", "SlutDato", "Doktype");
/**/
//break;
}
thisConnection.Close();
}
catch (SqlException ex)
{
Console.WriteLine("Der skete en fejl: (get) {0}", ex.ToString());
}
/**/
}
}
}
您的问题与不同的编码有关。
Base64 旨在通过使用减少的字符集将二进制数据 存储在 基于字符串的容器中,例如 XML 或 HTML。编码后的内容是一个仅由"secure characters"组成的字符串,可以像其他任何字符串一样处理。
十六进制字符串是位链。它们以 4 个为一组包装,并显示 0 到 9 和 A 到 F 的字符......在幕后,这只是一个比特链,分组包装并且 displayed 作为字符串16 个字符。这需要 - 但仅在字符中! - 比 base64 更多 space...作为比特链它需要更少...
总是有必要考虑:我的数据是什么类型,哪种类型适合存储它?
您决定将 base64 放在 VARCHAR(MAX)
类型的列中。似乎是个不错的选择。但我还是更喜欢 VARBINARY(MAX)
并在需要时进行 base64 编码。
我在这里遇到了一些挑战,我希望你们中的一些聪明人可以 guide/show 给我一个解决方案。 为了方便您,代码已经 condensated/cut 降低了一点。如果出现程序错误,那是因为那个。
该程序的任务是从 URL 下载 pdf,并将 PDF 保存在 MS SQL 服务器上。
我可以保存它,但数据似乎发生了变化。例如。下载的 PDF 的第一个字节是 25h(正确),当我将其保存在数据库中时,它变为 1Fh(错误)。
我意识到这一定是下载和保存之间的转换,可惜我做不到。
// This is where I suspect that my problem occurs.
byte[] myDataBuffer = client.DownloadData((new Uri(strFileUrlToDownload)));
如果我写的不清楚,请原谅。英语不是我的母语。
提前致谢。
用于创建 table 的脚本和下面的 C# 代码。
用于在 MS SQL 服务器上创建 table 的脚本:
SET [ThePartikularDatabase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[PDFTable](
[DokumentAID] [int] IDENTITY(1,1) NOT NULL,
[ident] [nchar](10) NOT NULL,
[AB] [nchar](10) NOT NULL,
[BI] [nchar](10) NOT NULL,
[dokumentType] [nchar](10) NOT NULL,
[base64] [varbinary](max) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
代码来了:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Web;
using System.Web.Script.Serialization;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using System.Web.UI;
using System.Text.RegularExpressions;
namespace test
{
class program
{
public static void DownloadData(string strFileUrlToDownload, WebClient client, string IV_ident, string IV_AB, string IV_BI, string IV_dokumentType)
{
// This function is made with inspiration from:
// http://www.c-sharpcorner.com/UploadFile/013102/save-and-read-pdf-file-using-sql-server-and-C-Sharp/
byte[] myDataBuffer = client.DownloadData((new Uri(strFileUrlToDownload)));
//string encodedText = Convert.ToBase64String(myDataBuffer);
//string decodedText = Encoding.UTF8.GetString(myDataBuffer);
// byte[] lars = Convert.ToByte(encodedText);
using (SqlConnection cn = new SqlConnection(GlobalVar.ConnectionString))
{
cn.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO [Database].[dbo].[PDFTable] " + "(Ident, AB, BI, dokumentType, base64) values (@ident, @AB, @BI, @dokumentType, @data);", cn))
{
cmd.Parameters.Add("@data", myDataBuffer);
cmd.Parameters.Add("@Ident", ident);
cmd.Parameters.Add("@AB", IV_AB);
cmd.Parameters.Add("@BI", IV_BI);
cmd.Parameters.Add("@dokumentType", IV_dokumentType);
cmd.ExecuteNonQuery();
}
}
using (SqlConnection cn = new SqlConnection(GlobalVar.ConnectionString))
{
cn.Open();
using (SqlCommand cmd = new SqlCommand("SELECT [base64] FROM [Database].[dbo].[PDFTable] WHERE ident = " + IV_ident + " ;", cn))
{
using (SqlDataReader dr = cmd.ExecuteReader(System.Data.CommandBehavior.Default))
{
if (dr.Read())
{
byte[] fileData = (byte[])dr.GetValue(0);
using (System.IO.FileStream fs = new System.IO.FileStream("c:\" + IV_ident + ".pdf", System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
{
using (System.IO.BinaryWriter bw = new System.IO.BinaryWriter(fs))
{
bw.Write(fileData);
bw.Close();
}
}
}
dr.Close();
}
}
}
}
public static void SaveMemoryStream(MemoryStream ms, string FileName)
{
FileStream outStream = File.OpenWrite(FileName);
ms.WriteTo(outStream);
outStream.Flush();
outStream.Close();
}
static void Main(string[] args)
{
int LI_start = 0;
int LI_slut = 0;
int LI_documentURL = 0;
string LS_ident = "";
string credentials = "Username:Password";
string url = "http://pdfurl.com/find;
CredentialCache mycache = new CredentialCache();
WebClient client = new WebClient();
client.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(credentials));
Regex regex = new Regex("");
try
{
/*
ident is fetched from our database. Code removed for simplicity..
*/
LS_ident = Convert.ToString(theRow["ident"]);
string LS_json = "{\"from\":0,\"size\":1,\"query\":{\"term\":{\"ident\":" + LS_ident + "}}}";
string LS_pdfURL = "";
string reply = client.UploadString(url, "POST", LS_json);
/********************************************************/
/* Regex ************************************************/
/*
URL for the pdf is taken from the reply with Regular expression.
*/
/* Regex ************************************************/
/********************************************************/
LS_pdfURL = "" + dokURL[i].Substring(LI_start, (LI_slut + 1 - LI_start)) + "pdf";
/*
LS_pdfURL now contains the correct path for the pdf.
I can manually download the pdf with the url. It works.
So far, so good.
*/
DownloadData(LS_pdfURL, client, LS_ident, "StartDato", "SlutDato", "Doktype");
/**/
//break;
}
thisConnection.Close();
}
catch (SqlException ex)
{
Console.WriteLine("Der skete en fejl: (get) {0}", ex.ToString());
}
/**/
}
}
}
您的问题与不同的编码有关。
Base64 旨在通过使用减少的字符集将二进制数据 存储在 基于字符串的容器中,例如 XML 或 HTML。编码后的内容是一个仅由"secure characters"组成的字符串,可以像其他任何字符串一样处理。
十六进制字符串是位链。它们以 4 个为一组包装,并显示 0 到 9 和 A 到 F 的字符......在幕后,这只是一个比特链,分组包装并且 displayed 作为字符串16 个字符。这需要 - 但仅在字符中! - 比 base64 更多 space...作为比特链它需要更少...
总是有必要考虑:我的数据是什么类型,哪种类型适合存储它?
您决定将 base64 放在 VARCHAR(MAX)
类型的列中。似乎是个不错的选择。但我还是更喜欢 VARBINARY(MAX)
并在需要时进行 base64 编码。