使用FormCollection时,MVC 3 RTM allowHtml不起作用

时间:2011-02-16 21:10:06

标签: asp.net-mvc asp.net-mvc-3

MVC 3 RTM。拥有一个具有AllowHtml属性的模型。在我的控制器操作中,如果操作将FormCollection作为参数,则会抛出异常:

 [HttpPost]
 public ActionResult Edit(FormCollection collection, int id)
 {
   var myEntity = _myRepo.Get(id);

   TryUpdateModel(myEntity);

   return DoSave(myEntity);
 }
  

潜在危险的Request.Form   从客户端检测到值

但是,如果我的控制器操作使用对象而不是FormCollection,则不会抛出异常。

 [HttpPost]
 public ActionResult Edit(MyEntity postedEntity, int id)
 {
   var myEntity = _myRepo.Get(id);

   TryUpdateModel(myEntity);

   return DoSave(myEntity);
 }

我已经设置了

  

的httpRuntime   requestValidationMode = “2.0”

使用FormCollection时为什么会失败?

2 个答案:

答案 0 :(得分:9)

您无法将AllowHtmlFormCollection一起使用。您可以使用[ValidateInput]属性,但显然禁用所有值的验证:

[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(FormCollection collection, int id)
{
    var myEntity = _myRepo.Get(id);
    TryUpdateModel(objective);
    return DoSave(objective);
}

据说我会使用以下内容:

[HttpPost]
public ActionResult Edit(MyEntity entity)
{
    if (ModelState.IsValid)
    {
        _myRepo.Save(entity);
        return RedirectToAction("Success");
    }
    return View(entity);
}

答案 1 :(得分:2)

出于安全原因,简单地禁用验证是一个很好的解决方案,因为您无意中完全禁用了该操作方法的安全性。

当您只需要一个GET或POST值时,这非常烦人 - 例如,如果您的GET / POST数据中存在任何的HTML值,Request.Params["xyz"]将会抛出,甚至如果您发布的"xyz"值不包含HTML。

(从最新的MVC 3.1版本开始就是如此。)

为了解决这个问题,我使用以下方法扩展了我的Controller基类:

    /// <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;
    }

这有效地允许您在绕过验证的同时获得单独的GET / POST值。

我认为这比完全关闭验证更好,更安全,更正确 - 您的应用程序确实可以从增加的安全性中受益,即使它的实现方式妨碍了,并且显然很难绕过它。

(我认为这不是设计,或者至少不是非常良好的设计......)