ChatGPT解决这个技术问题 Extra ChatGPT

ASP.NET MVC 使用自定义模型绑定器时从客户端检测到潜在危险的 Request.Form 值

在这里得到错误:

ValueProviderResult value = bindingContext.ValueProvider.GetValue("ConfirmationMessage");

如何仅允许选择值? IE

[ValidateInput(false)]
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    ValueProviderResult value = bindingContext.ValueProvider.GetValue("ConfirmationMessage");
    ValueProviderResult value2 = bindingContext.ValueProvider.GetValue("ConfirmationMessage2");
}
A potentially dangerous Request.Form value was detected from the client 的可能重复项,不管它是 Webforms 还是 MVC。
谢谢,但你还没有把我的问题看作是不同的
完全相同的根本问题,唯一的区别是可能有 MVC 特定的方法来处理它。
使用 EF 时,请在此处查看 bizzehdee 答案stackoverflow.com/questions/17964313/…

e
ericdc

你有几个选择。

在模型上将此属性添加到您需要允许 HTML 的每个属性 - 最佳选择

using System.Web.Mvc;

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

在控制器操作上添加此属性以允许所有 HTML

[ValidateInput(false)]
public ActionResult SomeAction(MyViewModel myViewModel)

web.config 中的蛮力 - 绝对不推荐

在 web.config 文件的标记中,插入属性为 requestValidationMode="2.0" 的 httpRuntime 元素。还要在 pages 元素中添加 validateRequest="false" 属性。

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>

更多信息:http://davidhayden.com/blog/dave/archive/2011/01/16/AllowHtmlAttributeASPNETMVC3.aspx

以上适用于默认模型绑定器的用法。

自定义模型绑定器

似乎在上面的代码中调用 bindingContext.ValueProvider.GetValue() 总是验证数据,不管任何属性。深入研究 ASP.NET MVC 源代码会发现,DefaultModelBinder 首先检查是否需要验证请求,然后使用指示是否需要验证的参数调用 bindingContext.UnvalidatedValueProvider.GetValue() 方法。

不幸的是,我们不能使用任何框架代码,因为它是密封的、私有的或其他任何东西来保护无知的开发人员免于做危险的事情,但创建一个尊重 AllowHtml 和 ValidateInput 属性的工作自定义模型绑定器并不难:

public class MyModelBinder: IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        // First check if request validation is required
        var shouldPerformRequestValidation = controllerContext.Controller.ValidateRequest && bindingContext.ModelMetadata.RequestValidationEnabled;

        // Get value
        var valueProviderResult = bindingContext.GetValueFromValueProvider(shouldPerformRequestValidation);
        if (valueProviderResult != null)
        {
            var theValue = valueProviderResult.AttemptedValue;

            // etc...
        }
    }
}

另一个必需的部分是检索未验证值的方法。在此示例中,我们使用 ModelBindingContext 类的扩展方法:

public static class ExtensionHelpers
{
    public static ValueProviderResult GetValueFromValueProvider(this ModelBindingContext bindingContext, bool performRequestValidation)
    {
        var unvalidatedValueProvider = bindingContext.ValueProvider as IUnvalidatedValueProvider;
        return (unvalidatedValueProvider != null)
          ? unvalidatedValueProvider.GetValue(bindingContext.ModelName, !performRequestValidation)
          : bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
    }
}

http://blogs.taiga.nl/martijn/2011/09/29/custom-model-binders-and-request-validation/ 上的更多信息


我在控制器上有这个 [HttpPost, ValidateInput(false)] 我仍然得到错误
使用自定义模型绑定器时,请参阅我修改后的答案
谢谢,但它不喜欢这一行 bindingContext.GetValueFromValueProvider
GetValueFromValueProvider 需要在公共静态类中。查看上面的编辑。
Ta,valueProviderResult 返回 null 吗? var valueProviderResult = bindingContext.GetValueFromValueProvider(shouldPerformRequestValidation);
D
DaveD

尝试:

HttpRequestBase request = controllerContext.HttpContext.Request;
string re = request.Unvalidated.Form.Get("ConfirmationMessage")

当我尝试这个时,我得到一个异常,上面写着:不可调用的成员 'System.web.HttpRequestBase.Unvalidated' 不能像方法一样使用。这件事变了吗?
第二行应该是 var re = request.Unvalidated.Form["ConfirmationMessage"];
M
Mike Godin

扩展来自@DW 的答案,在我的 Edit 控制器中,在迭代表单值时,我必须将 Request.Params.AllKeys 的所有实例替换为 Request.Unvalidated.Form.AllKeys,并将 Request[key] 的所有实例替换为 Request.Unvalidated.Form[key]

这是唯一对我有用的解决方案。


R
Ryozzo

正如 Mike Godin 所写,即使您设置 [ValidateInput(false)] 属性,您也必须使用 Request.Unvalidated.Form 而不是 Request.Form 这对我来说适用于 ASP.NET MVC 5


这实际上是一个有用的建议,因为从基本控制器访问数据(即出于日志或调试目的)对 Request.Form 的任何访问都会引发异常,即使模型具有此属性也是如此。
v
vard

以下是在客户端级别进行编码并在服务器级别对其进行解码的步骤:

使用 jquery submit 方法发布表单。在 jquery 按钮中单击要发布到服务器的事件方法编码字段。示例: $("#field").val(encodeURIComponent($("#field").val())) $("#formid").submit();在控制器级别使用 HttpUtility.UrlDecode(Request["fieldid"]) 访问所有表单 id 值

示例:

控制器级别:public ActionResult Name(string id) { CheckDispose();字符串开始 = 请求[“开始日期”];字符串结束=请求[“结束日期”]; return View("Index", GetACPViewModel(HttpUtility.UrlDecode(Request["searchid"]), start, end)); }

客户端级别:<% using (Html.BeginForm("Name", "App", FormMethod.Post, new { id = "search-form" })) { %>

<%= Html.TextBox("searchid", null, new {value=searchText, id = "search-text", placeholder = "Enter Application, Name, or BEMSID" })%>
<% } %>

在文档就绪功能中:

$(function () {     
  $("#btnsearch").click(function () {  
    $("#search-text").val(encodeURIComponent($("#search-text").val()));
    $("#search-form").submit();
  });
});

Jquery 和客户端技术与 MVC 无关,验证发生在 MVC 框架的服务器端。这不是一个有效的答案
鉴于微软实际上忽略了 AllowHtml 属性,并且考虑到服务器端唯一可行的解决方案是替换默认模型绑定器的功能,我认为客户端编码是一个完全有效的选项。

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅