Cho phép người dùng nhập HTML trong ASP.NET MVC - ValidateInput hoặc AllowHtml


120

Làm cách nào để cho phép người dùng nhập HTML vào một trường cụ thể bằng ASP.net MVC.

Tôi có một biểu mẫu dài với nhiều trường được ánh xạ tới đối tượng phức tạp này trong bộ điều khiển.

Tôi muốn tạo một trường (mô tả) cho phép HTML mà tôi sẽ tạo sẵn hệ thống vệ sinh của riêng mình sau này.


3
Đối với khách truy cập trong tương lai: Câu trả lời của IMHO, Chris J hoặc Eugene Bosikov tốt hơn câu trả lời được chấp nhận cho các phiên bản sau của ASP.NET MVC, đặc biệt nếu bạn chỉ muốn cho phép HTML trong một trường.
lc.

Câu trả lời:


163

Thêm thuộc tính sau cho hành động (bài đăng) trong bộ điều khiển mà bạn muốn cho phép HTML:

[ValidateInput(false)] 

Chỉnh sửa: Theo Charlino nhận xét của :

Trong web.config của bạn, hãy đặt chế độ xác thực được sử dụng. Xem MSDN :

<httpRuntime requestValidationMode="2.0" />

Chỉnh sửa tháng 9 năm 2014: Theo sprinter252 nhận xét:

Bây giờ bạn nên sử dụng [AllowHtml]thuộc tính. Xem bên dưới từ MSDN :

Đối với các ứng dụng ASP.NET MVC 3, khi bạn cần đăng HTML trở lại mô hình của mình, không sử dụng ValidateInput (false) để tắt Yêu cầu xác thực. Chỉ cần thêm [AllowHtml] vào thuộc tính mô hình của bạn, như sau:

public class BlogEntry {
    public int UserId {get;set;}
    [AllowHtml] 
    public string BlogText {get;set;}
 }

1
Nếu bạn đang sử dụng .NET 4, bạn cũng sẽ phải thiết lập <httpRuntime requestValidationMode="2.0" />tệp web.config của mình.
Charlino

3
Thực sự không có giải pháp nào cho .NET 4 không bao gồm hạ cấp chế độ xác thực yêu cầu?
bzlm

20
MSDN ( msdn.microsoft.com/de-de/magazine/hh708755.aspx ) nói rằng bạn không nên sử dụng ValidateInpute và thay vào đó hãy sử dụng AllowHtmlAttribute. (Did'nt tìm thấy phiên bản tiếng Anh)
Alexander Schmidt

8
Thực hiện chỉnh sửa để hy vọng giải quyết 3 phiếu bầu giảm gần đây đã được thực hiện ... đó là một câu trả lời cũ 4 năm :)
Kelsey

1
@ djack109 Thông thường, bạn không sử dụng mô hình EF làm mô hình xem của mình. Bạn sẽ viết một lớp riêng biệt đại diện cho dữ liệu thực tế cho các hoạt động CRUD của bạn. Bằng cách này khi mô hình EF6 của bạn được tạo lại, không có gì bị mất. Bạn cũng nên thu nhỏ các mô hình để chỉ có các thuộc tính bạn cần để thực hiện nhiệm vụ trong tầm tay.
Allen Clark Copeland Jr

131

Còn [AllowHtml]thuộc tính ở trên thì sao?


5
Đây dường như là một cách tốt hơn nhiều đối với tôi, tránh thay đổi bất kỳ hành vi toàn cầu nào. Tôi vừa giải quyết vấn đề của mình bằng cách thêm thuộc tính này vào một thuộc tính trên mô hình của mình.
Jonathan Sayce

2
Hoàn toàn đồng ý với giải pháp của Chris ở đây, không có lý do gì để vô hiệu hóa xác thực html cho toàn bộ ứng dụng nếu bạn chỉ cần một thuộc tính trong một mô hình để có thể chấp nhận đầu vào html. Việc xóa xác thực trong web.config sẽ mở ra một lỗ hổng bảo mật lớn trong ứng dụng của bạn.
Miguel

1
Rất tiếc, điều này không hoạt động nếu bạn đang sử dụng MetadataTypeAttribute
dav_i

@dav_i: Giải pháp này hoạt động tốt MetadataTypeAttributevà thích hợp hơn vì nó chỉ cho phép HTML trên các trường riêng lẻ chứ không phải toàn bộ đối tượng.
Gone Coding

@TrueBlueAussie, tôi đã cố gắng hàng giờ trong môi trường mvc 4.0 của mình và mặc dù AllowHtml sẽ không hoạt động. Tôi đã phải thừa nhận thất bại và đi với một lựa chọn kém an toàn hơn đó là quần dài. AllowHtml dường như không hoạt động với việc sử dụng MetadataTypeAttribute
julian guppy

42

Thêm vào mô hình:

using System.Web.Mvc;

Và tài sản của bạn

        [AllowHtml]
        [Display(Name = "Body")]
        public String Body { get; set; }

Mã này theo quan điểm của tôi là cách tốt nhất để tránh lỗi này. Nếu bạn đang sử dụng trình soạn thảo HTML, bạn sẽ không gặp vấn đề về bảo mật vì nó đã bị hạn chế.


9

Thêm [AllowHtml] vào thuộc tính cụ thể là giải pháp được khuyến nghị vì có rất nhiều blog và nhận xét đề xuất giảm mức độ bảo mật, điều này không thể chấp nhận được.

Bằng cách thêm vào đó, khuôn khổ MVC sẽ cho phép Bộ điều khiển được đánh và mã trong bộ điều khiển đó được thực thi.

Tuy nhiên, nó phụ thuộc vào mã của bạn, bộ lọc, v.v. cách phản hồi được tạo và liệu có bất kỳ xác thực nào khác có thể gây ra một lỗi tương tự khác hay không.

Trong mọi trường hợp, thêm [AllowHtml]thuộc tính là câu trả lời đúng, vì nó cho phép html được giải mã hóa trong bộ điều khiển. Ví dụ trong mô hình xem của bạn:

[AllowHtml]
public string MessageWithHtml {get; set;}

8

Tôi gặp phải vấn đề tương tự mặc dù tôi đã thêm [System.Web.Mvc.AllowHtml]vào thuộc tính liên quan như được mô tả trong một số câu trả lời.

Trong trường hợp của tôi, tôi có một UnhandledExceptionFilterlớp truy cập đối tượng Yêu cầu trước khi xác thực MVC diễn ra (và do đó AllowHtml không có hiệu lực) và quyền truy cập này tăng a [HttpRequestValidationException] A potentially dangerous Request.Form value was detected from the client.

Điều này có nghĩa là, việc truy cập các thuộc tính nhất định của một đối tượng Yêu cầu sẽ ngầm kích hoạt xác thực (trong trường hợp của tôi là Params ).

Một giải pháp để ngăn chặn xác thực được ghi lại trên MSDN

Để tắt xác thực yêu cầu cho một trường cụ thể trong yêu cầu (ví dụ: đối với phần tử đầu vào hoặc giá trị chuỗi truy vấn), hãy gọi phương thức Request.Unvalidated khi bạn nhận được mục, như được hiển thị trong ví dụ sau

Do đó, nếu bạn có mã như thế này

var lParams = aRequestContext.HttpContext.Request.Params;
if (lParams.Count > 0)
{
  ...

thay đổi nó thành

var lUnvalidatedRequest = aRequestContext.HttpContext.Request.Unvalidated;

var lForm = lUnvalidatedRequest.Form;
if (lForm.Count > 0)
{
  ...

hoặc chỉ sử dụng thuộc Formtính dường như không kích hoạt xác thực

var lForm = aRequestContext.HttpContext.Request.Form;
if (lForm.Count > 0)
{
  ...

1
Cảm ơn! Request.Unvalidated là giải pháp duy nhất phù hợp với tôi.
Petter Ivarsson

3

Nếu bạn cần cho phép đầu vào html cho tham số action-method (trái ngược với "thuộc tính mô hình") thì không có cách nào được tích hợp sẵn để làm điều đó nhưng bạn có thể dễ dàng đạt được điều này bằng cách sử dụng trình kết nối mô hình tùy chỉnh:

public ActionResult AddBlogPost(int userId,
    [ModelBinder(typeof(AllowHtmlBinder))] string htmlBody)
{
    //...
}

Mã AllowHtmlBinder:

public class AllowHtmlBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var request = controllerContext.HttpContext.Request;
        var name = bindingContext.ModelName;
        return request.Unvalidated[name]; //magic happens here
    }
}

Tìm mã nguồn hoàn chỉnh và giải thích trong bài đăng trên blog của tôi: https://www.jitbit.com/alexblog/273-aspnet-mvc-allowing-html-for-particular-action-parameters/


1
Unvalidated dường như chỉ có sẵn trong framework 4.5 trở lên.
Ben

@Ben chính xác! Vui lòng kiểm tra giải pháp đã sửa đổi này. stackoverflow.com/questions/59483284/…
om-ha

3

URL Mã hóa dữ liệu cũng hoạt động đối với tôi

Ví dụ

var data = '<b> Xin chào </b>'

Trong mã hóa cuộc gọi Trình duyệtURIComponent (dữ liệu) trước khi đăng

Trên Máy chủ, hãy gọi HttpUtility.UrlDecode (dữ liệu nhận_dữ liệu) để giải mã

Bằng cách đó, bạn có thể kiểm soát chính xác khu vực trường nào được phép có html


cách dễ nhất cho đến nay
N1gthm4r3

1

Tôi đã gặp phải vấn đề này trong quá trình phát triển trang Thương mại điện tử bằng NopCommerce, tôi đã nhận được giải pháp này bằng 3 cách khác nhau giống như các câu trả lời trước. Nhưng theo cấu trúc NopCommerce, tôi không tìm thấy ba cái đó cùng một lúc. Tôi vừa thấy rằng ở đó họ đang sử dụng [AllowHtml]và nó hoạt động tốt ngoại trừ bất kỳ vấn đề nào. Như câu hỏi đã hỏi trước đây

Cá nhân tôi không thích [ValidateInput(false)]vì tôi đang bỏ qua kiểm tra tổng thể thực thể mô hình, điều này không an toàn. Nhưng nếu ai mới viết hãy xem ở đây

[AllowHtml] 
public string BlogText {get;set;}

thì nó chỉ bỏ qua một thuộc tính duy nhất và chỉ cho phép một thuộc tính cụ thể và hầu như không kiểm tra tất cả các thực thể khác. Vì vậy, nó có vẻ thích hơn đối với tôi.


1

Trong trường hợp của tôi, thuộc tính AllowHtml không hoạt động khi được kết hợp với bộ lọc hành động OutputCache. Câu trả lời này đã giải quyết vấn đề cho tôi. Hy vọng điều này sẽ giúp ai đó.


1

Bạn có thể sử dụng [AllowHtml]cho dự án của mình để làm ví dụ

 [AllowHtml]
 public string Description { get; set; }

Để sử dụng mã này cho thư viện lớp, bạn cài đặt gói này

Install-Package Microsoft.AspNet.Mvc

Sau khi sử dụng cái này using

using System.Web.Mvc;

0

Thật không may, không có câu trả lời nào ở đây phù hợp với tôi.

Tôi đã sử dụng Ràng buộc mô hình tùy chỉnh và sử dụng Trình vệ sinh của bên thứ ba.

Xem câu hỏi tự trả lời của tôi ở đây .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.