what the side purpose net mvc exclude data asp asp.net-mvc custom-model-binder

asp.net-mvc - the - model binding asp net



ASP.NET MVC Se detectó un valor Request.Form potencialmente peligroso desde el cliente cuando se utilizaba un modificador de modelo personalizado. (4)

Ampliando la respuesta de @DW, en mi controlador de edición, al iterar sobre los valores de formulario, tuve que reemplazar todas las instancias de Request.Params.AllKeys con Request.Unvalidated.Form.AllKeys y todas las instancias de Request[key] con Request.Unvalidated.Form[key] .

Esta fue la única solución que funcionó para mí.

Obteniendo el error aquí:

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

¿Cómo permito una selección de valores solamente? es decir

[ValidateInput(false)] public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ValueProviderResult value = bindingContext.ValueProvider.GetValue("ConfirmationMessage"); ValueProviderResult value2 = bindingContext.ValueProvider.GetValue("ConfirmationMessage2"); }


Estos son los pasos para codificar a nivel del cliente y decodificarlo a nivel del servidor:

  1. Publique el formulario usando el método de envío jquery.

  2. En el botón jquery, haga clic en el campo de codificación del método de evento que desea publicar en el servidor. Ejemplo:

    $("#field").val(encodeURIComponent($("#field").val())) $("#formid").submit();

  3. En Controlador, acceda a todos los valores de ID de formulario usando

    HttpUtility.UrlDecode(Request["fieldid"])

Ejemplo de muestra:

  • Nivel de controlador:

    public ActionResult Name(string id) { CheckDispose(); string start = Request["start-date"]; string end = Request["end-date"]; return View("Index", GetACPViewModel(HttpUtility.UrlDecode(Request["searchid"]), start, end)); }

  • Nivel del cliente:

    <% using (Html.BeginForm("Name", "App", FormMethod.Post, new { id = "search-form" })) { %> <div> <label for="search-text" style="vertical-align: middle" id="search-label" title="Search for an application by name, the name for who a request was made, or a BEMSID">App, (For Who) Name, or BEMSID: </label> <%= Html.TextBox("searchid", null, new {value=searchText, id = "search-text", placeholder = "Enter Application, Name, or BEMSID" })%> </div> <div> <input id="start-date" name="start-date" class="datepicker" type="text" placeholder="Ex: 1/1/2012"/> </div> <div> <input id="end-date" name="end-date" class="datepicker" type="text" placeholder="Ex: 12/31/2012"/> </div> <div> <input type="button" name="search" id="btnsearch" value="Search" class="searchbtn" style="height:35px"/> </div> <% } %>

En la función de Document Ready:

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


Tienes pocas opciones.

En el modelo, agregue este atributo a cada propiedad que necesite para permitir HTML: la mejor opción

using System.Web.Mvc; [AllowHtml] public string SomeProperty { get; set; }

En la acción del controlador agregue este atributo para permitir todo el HTML

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

Fuerza bruta en web.config - definitivamente no recomendado

En el archivo web.config, dentro de las etiquetas, inserte el elemento httpRuntime con el atributo requestValidationMode = "2.0". También agregue el atributo validateRequest = "false" en el elemento pages.

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

Más información: http://davidhayden.com/blog/dave/archive/2011/01/16/AllowHtmlAttributeASPNETMVC3.aspx

Lo anterior funciona para los usos del modelbinder predeterminado.

Custom ModelBinder

Parece que una llamada a bindingContext.ValueProvider.GetValue () en el código anterior siempre valida los datos, independientemente de los atributos. Al explorar en las fuentes ASP.NET MVC, se revela que DefaultModelBinder primero verifica si se requiere validación de solicitud y luego llama al método bindingContext.UnvalidatedValueProvider.GetValue () con un parámetro que indica si se requiere validación o no.

Desafortunadamente no podemos usar el código de framework porque está sellado, es privado o lo que sea para proteger a los desarrolladores ignorantes de hacer cosas peligrosas, pero no es demasiado difícil crear un encuadernador de modelo personalizado que respete los atributos AllowHtml y 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... } } }

La otra pieza requerida es una forma de recuperar un valor no validado. En este ejemplo usamos un método de extensión para la clase 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); } }

Más información al respecto en http://blogs.taiga.nl/martijn/2011/09/29/custom-model-binders-and-request-validation/


Tratar:

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