2009-03-12 58 views
14

Có chức năng mã hóa các chuỗi HTML trong T-SQL không? Tôi có một cơ sở dữ liệu di sản có chứa các ký tự né tránh như '<', '>' vv. Tôi có thể viết một hàm để thay thế các ký tự nhưng có cách nào tốt hơn không?Mã hóa HTML trong T-SQL?

Tôi có một ứng dụng ASP.Net và khi nó trả về một chuỗi, nó chứa các ký tự gây ra lỗi. Ứng dụng ASP.Net đang đọc dữ liệu từ một bảng cơ sở dữ liệu. Nó không ghi vào bảng.

+0

Câu trả lời dưới đây là tốt nhưng nếu những ký tự đó không có trong dữ liệu thì tôi khuyên bạn nên làm sạch dữ liệu. Nếu không thì James sẽ xuất hiện. – Lazarus

+0

Các ký tự là chính xác trong dữ liệu và nếu tôi thay đổi dữ liệu tôi có thể phá vỡ ứng dụng cũ. Vì vậy, đó không phải là một lựa chọn. –

+1

Nếu vấn đề của bạn nằm trong mã ASP.NET của bạn, thì cách 'thực hành tốt nhất' để xử lý việc này là sử dụng hàm Server.HtmlEncode() trong lớp ASP.NET. Về mặt kỹ thuật, bạn không được phép lưu trữ dữ liệu 'đã xử lý' trong DB của mình, bạn muốn dữ liệu thực, đơn giản ở đó, không được tùy chỉnh cho một hệ thống bản trình bày cụ thể (HTML).Nếu tại một thời điểm nào đó bạn chỉ cần văn bản thuần túy mà không có các thực thể HTML, bạn vẫn có một phiên bản sạch của nó trong DB của bạn. – Steve

Trả lời

20

Chúng tôi có một hệ thống kế thừa sử dụng trình kích hoạt và dbmail để gửi email được mã hóa HTML khi bảng được nhập, vì vậy chúng tôi yêu cầu mã hóa trong quá trình tạo email. Tôi nhận thấy rằng phiên bản của Leo có một lỗi nhỏ mà mã hóa các & trong &lt;&gt; tôi sử dụng phiên bản này:

CREATE FUNCTION HtmlEncode 
(
    @UnEncoded as varchar(500) 
) 
RETURNS varchar(500) 
AS 
BEGIN 
    DECLARE @Encoded as varchar(500) 

    --order is important here. Replace the amp first, then the lt and gt. 
    --otherwise the &lt will become &amp;lt; 
    SELECT @Encoded = 
    Replace(
    Replace(
     Replace(@UnEncoded,'&','&amp;'), 
    '<', '&lt;'), 
    '>', '&gt;') 

    RETURN @Encoded 
END 
GO 
+0

Cảm ơn, bạn đã đúng. Tôi đã chnage nó trong sản xuất nhưng quên cập nhật các bài trước. –

+1

@ Beniaminus: Trong khi nó loại bỏ các ký tự XML nguy hiểm nhất, đó là thực sự xa "Html-Encoded", nhưng tôi đoán bạn biết rằng mình :) –

14

Bạn không nên sửa chuỗi trong SQL. Một cách tốt hơn là sử dụng một hàm trong ASP.net được gọi là HtmlEncode, điều này sẽ nấu các ký tự đặc biệt gây ra các vấn đề bạn đang thấy, xem ví dụ bên dưới. Tôi hi vọng cái này giúp được.

string htmlEncodedStr = System.Web.HttpUtility.HtmlEncode(yourRawStringVariableHere); 
string decodedRawStr = System.Web.HttpUtility.HtmlDecode(htmlEncodedStr); 

Chỉnh sửa: Vì dữ liệu của bạn ràng buộc từ dữ liệu này. Sử dụng biểu thức nội tuyến để gọi HTMLEncode trong đánh dấu của GridView hoặc bất kỳ điều khiển nào bạn sử dụng và điều này sẽ vẫn đáp ứng yêu cầu ràng buộc dữ liệu của bạn. Xem ví dụ bên dưới. Thay thế, bạn có thể lặp lại mọi bản ghi trong đối tượng bảng dữ liệu và cập nhật từng ô bằng chuỗi được mã hóa html trước khi gắn kết dữ liệu.

<%# System.Web.HttpUtility.HtmlEncode(Eval("YourColumnNameHere")) %> 
+0

Bạn cũng có thể sử dụng một BoundField. http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.boundfield.aspx – bobince

+0

Có điều đó đúng. – James

2

Nếu bạn đang hiển thị chuỗi trên web, bạn có thể mã hóa chuỗi đó bằng Máy chủ.HTMLEncode().

Nếu bạn đang lưu trữ một chuỗi trong cơ sở dữ liệu, hãy đảm bảo trường cơ sở dữ liệu là "nchar", thay vì "char". Điều đó sẽ cho phép nó lưu trữ các chuỗi unicode.

Nếu bạn không thể kiểm soát cơ sở dữ liệu, bạn có thể "làm phẳng" chuỗi thành ASCII bằng Encoding.ASCII.GetString.

8

Tôi không nghĩ rằng dữ liệu trong cơ sở dữ liệu phải biết hoặc quan tâm đến giao diện người dùng. Các vấn đề hiển thị phải được xử lý bởi lớp trình bày. Tôi sẽ không muốn thấy bất kỳ HTML nào trộn lẫn vào cơ sở dữ liệu.

+0

Tôi đồng ý hoàn toàn, nhưng không phải lựa chọn của tôi. Một ứng dụng kế thừa của nó với các ký tự loại HTML trong Guid (hoặc những gì đi qua như Guid). –

+1

Trình bày trong khóa chính? CHÚA ƠI. Tôi sẽ tái cấu trúc nó càng nhanh càng tốt. – duffymo

+0

@duffymo: Tại sao không? Nó có thể là một trang web bận rộn. Lưu nội dung HtmlEncoded lưu mã hóa theo mọi yêu cầu. Ví dụ. Kết xuất HTML được tạo từ đánh dấu Wiki - điều này sẽ tiết kiệm thời gian hiển thị dài trên mọi yêu cầu - bạn có thể hiển thị trước khi đánh dấu thay đổi và lưu. –

0

OK đây là những gì tôi đã làm. Tôi đã tạo ra một hàm đơn giản để xử lý nó. Của nó xa hoàn thành nhưng ít nhất xử lý các tiêu chuẩn <>& ký tự. Tôi sẽ chỉ thêm vào nó khi tôi đi cùng.

CREATE FUNCTION HtmlEncode 
(
    @UnEncoded as varchar(500) 
) 
RETURNS varchar(500) 
AS 
BEGIN 
    DECLARE @Encoded as varchar(500) 
    SELECT @Encoded = Replace(@UnEncoded,'<','&lt;') 
    SELECT @Encoded = Replace(@Encoded,'>','&gt;') 
    SELECT @Encoded = Replace(@Encoded,'&','&amp;') 
    RETURN @Encoded  
END 

tôi sau đó có thể sử dụng:

Select Ref,dbo.HtmlEncode(RecID) from Customers 

này mang lại cho tôi một HTML an toàn Ghi ID. Có thể có một chức năng tích hợp nhưng tôi không thể tìm thấy nó.

0

gán nó vào văn bản tài sản của nhãn, nó sẽ được tự động mã hóa bởi .NET

+0

Chào mừng bạn đến Stack tràn! Vui lòng mở rộng câu trả lời của bạn, bao gồm thông tin khác: quá ngắn. –

0

tôi đã không thử giải pháp này bản thân mình nhưng những gì tôi sẽ cố gắng sử dụng máy chủ sql /. NET CLR hội nhập và thực sự gọi chức năng C# HTMLEncode từ T-SQL. Điều này có thể không hiệu quả nhưng tôi nghi ngờ nó sẽ cho bạn kết quả chính xác nhất.

My điểm khởi đầu để làm việc ra làm thế nào để làm điều này sẽ http://msdn.microsoft.com/en-us/library/ms254498%28VS.80%29.aspx

20

Đó là hơi muộn, nhưng dù sao, ở đây những cách thích hợp:

HTML Encode (HTML encoding = mã hóa XML):

DECLARE @s NVARCHAR(100) 
SET @s = '<html>unsafe & safe Utf8CharsDon''tGetEncoded ÄöÜ - "Conex"<html>' 
SELECT (SELECT @s FOR XML PATH('')) 

HTML mã hóa trong một truy vấn:

SELECT 
    FIELD_NAME 
    ,(SELECT FIELD_NAME AS [text()] FOR XML PATH('')) AS FIELD_NAME_HtmlENcoded 
FROM TABLE_NAME 

HTML-Decode:

SELECT CAST('<root>' + '&lt;root&gt;Test&amp;123' + '</root>' AS XML).value(N'(root)[1]', N'varchar(max)'); 

Nếu bạn muốn làm đúng cách, bạn có thể sử dụng quy trình CLR lưu trữ.
Tuy nhiên, nó hơi phức tạp một chút, vì bạn không thể sử dụng System.Web-Assembly trong CLR-lưu trữ-thủ tục (vì vậy bạn không thể làm System.Web.HttpUtility.HtmlDecode (htmlEncodedStr);). Vì vậy, bạn phải viết lớp HttpUtility của riêng bạn, mà tôi sẽ không khuyên bạn nên, đặc biệt là để giải mã.

May mắn thay, bạn có thể trích xuất System.Web.HttpUtility ra khỏi mã nguồn đơn âm (.NET cho Linux). Sau đó, bạn có thể sử dụng HttpUtility mà không cần tham chiếu system.web.

Sau đó, bạn viết này CLR-Stored-Procedure:

using System; 
using System.Collections.Generic; 
using System.Text; 

using Microsoft.SqlServer.Server; 
using System.Data.SqlTypes; 
//using Microsoft.SqlServer.Types; 


namespace ClrFunctionsLibrary 
{ 


    public class Test 
    { 


     [Microsoft.SqlServer.Server.SqlFunction] 
     public static SqlString HtmlEncode(SqlString sqlstrTextThatNeedsEncoding) 
     { 
      string strHtmlEncoded = System.Web.HttpUtility.HtmlEncode(sqlstrTextThatNeedsEncoding.Value); 
      SqlString sqlstrReturnValue = new SqlString(strHtmlEncoded); 

      return sqlstrReturnValue; 
     } 


     [Microsoft.SqlServer.Server.SqlFunction] 
     public static SqlString HtmlDecode(SqlString sqlstrHtmlEncodedText) 
     { 
      string strHtmlDecoded = System.Web.HttpUtility.HtmlDecode(sqlstrHtmlEncodedText.Value); 
      SqlString sqlstrReturnValue = new SqlString(strHtmlDecoded); 

      return sqlstrReturnValue; 
     } 


     // ClrFunctionsLibrary.Test.GetPassword 
     //[Microsoft.SqlServer.Server.SqlFunction] 
     //public static SqlString GetPassword(SqlString sqlstrEncryptedPassword) 
     //{ 
     // string strDecryptedPassword = libPortalSecurity.AperturePortal.DecryptPassword(sqlstrEncryptedPassword.Value); 
     // SqlString sqlstrReturnValue = new SqlString(sqlstrEncryptedPassword.Value + "hello"); 

     // return sqlstrReturnValue; 
     //} 

     public const double SALES_TAX = .086; 

     // http://msdn.microsoft.com/en-us/library/w2kae45k(v=vs.80).aspx 
     [SqlFunction()] 
     public static SqlDouble addTax(SqlDouble originalAmount) 
     { 
      SqlDouble taxAmount = originalAmount * SALES_TAX; 

      return originalAmount + taxAmount; 
     } 


    } // End Class Test 


} // End Namespace ClrFunctionsLibrary 

Và đăng ký nó:

GO 

/* 
--http://stackoverflow.com/questions/72281/error-running-clr-stored-proc 
-- For unsafe permission 
EXEC sp_changedbowner 'sa' 
ALTER DATABASE YOUR_DB_NAME SET TRUSTWORTHY ON 

GO 
*/ 


IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[HtmlEncode]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT')) 
DROP FUNCTION [dbo].[HtmlEncode] 
GO 


IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[HtmlDecode]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT')) 
DROP FUNCTION [dbo].[HtmlDecode] 
GO 




IF EXISTS (SELECT * FROM sys.assemblies asms WHERE asms.name = N'ClrFunctionsLibrary' and is_user_defined = 1) 
DROP ASSEMBLY [ClrFunctionsLibrary] 

GO 


--http://msdn.microsoft.com/en-us/library/ms345101.aspx 



CREATE ASSEMBLY [ClrFunctionsLibrary] 
AUTHORIZATION [dbo] 
FROM 'D:\username\documents\visual studio 2010\Projects\ClrFunctionsLibrary\ClrFunctionsLibrary\bin\Debug\ClrFunctionsLibrary.dll' 
WITH PERMISSION_SET = UNSAFE --EXTERNAL_ACCESS --SAFE 
; 

GO 




CREATE FUNCTION [dbo].[HtmlDecode](@value [nvarchar](max)) 
RETURNS [nvarchar](max) WITH EXECUTE AS CALLER 
AS 
-- [AssemblyName].[Namespace.Class].[FunctionName] 
EXTERNAL NAME [ClrFunctionsLibrary].[ClrFunctionsLibrary.Test].[HtmlDecode] 
GO 





CREATE FUNCTION [dbo].[HtmlEncode](@value [nvarchar](max)) 
RETURNS [nvarchar](max) WITH EXECUTE AS CALLER 
AS 
-- [AssemblyName].[Namespace.Class].[FunctionName] 
EXTERNAL NAME [ClrFunctionsLibrary].[ClrFunctionsLibrary.Test].[HtmlEncode] 
GO 



/* 
EXEC sp_CONFIGURE 'show advanced options' , '1'; 
GO 
RECONFIGURE; 
GO 
EXEC sp_CONFIGURE 'clr enabled' , '1' 
GO 
RECONFIGURE; 
GO 

EXEC sp_CONFIGURE 'show advanced options' , '0'; 
GO 
RECONFIGURE; 
*/ 

Sau đó, bạn có thể sử dụng nó như chức năng bình thường:

SELECT 
    dbo.HtmlEncode('helloäÖühello123') AS Encoded 
    ,dbo.HtmlDecode('hello&auml;&Ouml;&uuml;hello123') AS Decoded 

Bất kỳ ai chỉ sao chép bột nhão, xin lưu ý rằng vì lý do hiệu quả, bạn sẽ sử dụng

public const double SALES_TAX = 1.086; 

// http://msdn.microsoft.com/en-us/library/w2kae45k(v=vs.80).aspx 
[SqlFunction()] 
public static SqlDouble addTax(SqlDouble originalAmount) 
{ 
    return originalAmount * SALES_TAX; 
} 

nếu bạn sử dụng chức năng này trong quá trình sản xuất.

Xem ở đây cho các lớp mono chỉnh sửa:
http://pastebin.com/pXi57iZ3
http://pastebin.com/2bfGKBte

Bạn cần phải xác định NET_2_0 trong các tùy chọn xây dựng Build options

+0

wow không nghĩ rằng chỉ cần trở lại như xml! đẹp 1 –

+0

lừa html giải mã là thực sự tốt, cảm ơn. –

+0

@ Rez.Net: Hãy cẩn thận tuy nhiên, điều này có thể và sẽ ném vào các ký tự html hợp lệ không được chỉ định trong XML, như ä ö hoặc © hoặc & eacute; â œ & ccedil; Ω ß æ Œ & ntilde; v.v. –

1

Bạn chỉ có thể sử dụng 'PATH XML trong truy vấn của bạn. Ví dụ;

 
DECLARE @encodedString VARCHAR(MAX) 

SET @encodedString = 'give your html string you want to encode' 

SELECT @encodedString 
SELECT (SELECT @encodedString FOR XML PATH('')) 

Bây giờ bạn có thể làm điều này trong chức năng sql của riêng bạn. Hy vọng điều này sẽ giúp.

Các vấn đề liên quan