MVC 3 RTM. Have a model that has an attribute with AllowHtml. In my controller action, if the action has FormCollection as parameter, it throws the exception:
[HttpPost]
public ActionResult Edit(FormCollection collection, int id)
{
var myEntity = _myRepo.Get(id);
TryUpdateModel(myEntity);
return DoSave(myEntity);
}
A potentially dangerous Request.Form value was detected from the client
However if my controller action uses an object instead of FormCollection it doesn't throw the exception.
[HttpPost]
public ActionResult Edit(MyEntity postedEntity, int id)
{
var myEntity = _myRepo.Get(id);
TryUpdateModel(myEntity);
return DoSave(myEntity);
}
I've already setup
httpRuntime requestValidationMode="2.0"
Why does it fail when using FormCollection?
You can't use AllowHtml
with FormCollection
. You could use the [ValidateInput]
attribute but obviously this disabled validation for all values:
[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(FormCollection collection, int id)
{
var myEntity = _myRepo.Get(id);
TryUpdateModel(objective);
return DoSave(objective);
}
This being said I would use the following:
[HttpPost]
public ActionResult Edit(MyEntity entity)
{
if (ModelState.IsValid)
{
_myRepo.Save(entity);
return RedirectToAction("Success");
}
return View(entity);
}
For security-reasons, simply disabling validation is not a good solution, as you're inadvertently disabling security for that action-method entirely.
When you need just one GET or POST value, this is extremely annoying - for example, Request.Params["xyz"]
will throw if there's an HTML-value anywhere in your GET/POST data, even if the "xyz"
value you posted does not contain HTML.
(This is true as of the latest MVC 3.1 release.)
To get around this issue, I extended my Controller base-class with the following method:
/// <summary>
/// Gets a value from the current Controller's ValueProvider, bypassing post-data validation.
/// </summary>
public string GetUnvalidatedValue(string key)
{
ValueProviderResult result;
if (ValueProvider is IUnvalidatedValueProvider)
{
result = ((IUnvalidatedValueProvider)ValueProvider)
.GetValue(key, skipValidation: true);
}
else
{
result = ValueProvider.GetValue(key);
}
return result == null ? null : result.AttemptedValue;
}
This effectively allows you to get an individual GET/POST value while bypassing the validation.
I believe this is better, safer and more correct than turning off validation altogether - your application does benefit from the added security, even if the way it's implemented gets in the way, and apparently is pretty painful to get around.
(I don't think this is by design, or at least not by very good design...)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.