In this article I will explain with an example, how to solve the error exception occurring in ASP.Net MVC i.e. A potentially dangerous Request.Form value was detected from the client.
The error exception A potentially dangerous Request.Form value was detected from the client occurs someone tries to submit HTML or JavaScript code to server. Such exception comes since ASP.Net MVC has inbuilt mechanism to prevent XSS (Cross Site Scripting) attacks.
XSS (Cross Site Scripting) attacks
In XSS (Cross Site Scripting) attacks, a hacker tries to inject HTML or JavaScript code to a website via INPUT fields such as TextBoxes, TextAreas, etc.
Problem
Cause
ASP.Net By default validates all input controls for potentially unsafe contents that can lead to XSS (Cross Site Scripting) attacks. Thus it disallows such content by throwing the above Exception. By default it is recommended to allow this check to happen on each Form Submit unless special requirement.
Solution
Though there are security risks involved but in some cases we actually need to POST code and HTML content to the server, thus for such cases ASP.Net MVC has three solutions.
1. AllowHtml attribute [RECOMMENDED]
The AllowHtml attribute can be applied to a Model property and it will disable the validation by ASP.Net MVC only for that particular property.
Advantages
The AllowHtml attribute is developed for Model class.
The Scope is limited to specific property of the Model class.
It is the safe and recommended solution.
Example:-
Model
public class PersonModel
{
[Display(Name = "Resume:")]
[AllowHtml]
public string Resume { get; set; }
}
Controller
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(PersonModel person)
{
return View();
}
}
View
@model Potential_Dangerous_MVC.Models.PersonModel
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width"/>
<title>Index</title>
</head>
<body>
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<table>
<tr>
<td>@Html.LabelFor(m => m.Resume)</td>
<td>@Html.TextAreaFor(m => m.Resume)</td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Submit"/></td>
<td></td>
</tr>
</table>
}
</body>
</html>
2. ValidateInput attribute at Action level [SECOND BEST RECOMMENDED]
The ValidateInput attribute can be applied to a Controller’s Action method and it will disable the validation by ASP.Net MVC only for that particular Action method.
Advantages
The Scope is limited to specific Action method of the Controller class.
If you have multiple properties accepting HTML content, then this method will reduce redundancy.
When Model class is not used for designing Form elements then this attribute is needed.
Disadvantages
All the Form fields posting data to an Action method can send HTML content, though only one or few might actually needed to send.
Example:-
Model
public class PersonModel
{
[Display(Name = "Resume:")]
public string Resume { get; set; }
}
Controller
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateInput(false)]
public ActionResult Index(PersonModel person)
{
return View();
}
}
View
@model Potential_Dangerous_MVC.Models.PersonModel
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width"/>
<title>Index</title>
</head>
<body>
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<table>
<tr>
<td>@Html.LabelFor(m => m.Resume)</td>
<td>@Html.TextAreaFor(m => m.Resume)</td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Submit"/></td>
<td></td>
</tr>
</table>
}
</body>
</html>
3. ValidateInput attribute at Controller level [THIRD BEST RECOMMENDED]
The ValidateInput attribute can also be applied to a Controller and it will disable the validation by ASP.Net MVC for all the Action methods of that particular Controller.
Advantages
The Scope is limited to the specific Controller class.
If you have multiple Action methods accepting HTML content, then this method will reduce redundancy.
When Model class is not used for designing multiple Forms then this method is useful.
Disadvantages
All the Form fields posting data to all the Action methods can send HTML content, though only one or few might actually needed to send.
Example:-
Model
public class PersonModel
{
[Display(Name = "Resume:")]
public string Resume { get; set; }
}
Controller
[ValidateInput(false)]
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(PersonModel person)
{
return View();
}
}
View
@model Potential_Dangerous_MVC.Models.PersonModel
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width"/>
<title>Index</title>
</head>
<body>
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<table>
<tr>
<td>@Html.LabelFor(m => m.Resume)</td>
<td>@Html.TextAreaFor(m => m.Resume)</td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Submit"/></td>
<td></td>
</tr>
</table>
}
</body>
</html>