ASP.NET MVC 사용자 지정 modelbinder를 사용할 때 클라이언트에서 잠재적으로 위험한 Request.Form 값이 검색되었습니다.


95

여기에 오류가 발생합니다.

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

값 선택 만 허용하려면 어떻게합니까? 즉

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


2
감사합니다.하지만 제 문제를 다른 것으로 보지 않으 셨습니다
DW

똑같은 근본 문제, 유일한 차이점은 MVC 특정 방법이있을 수 있다는 것입니다.
Erik Philips

EF를 사용하는 경우 여기에서 bizzehdee 답변을 참조하십시오. stackoverflow.com/questions/17964313/…
Petr

답변:


223

몇 가지 옵션이 있습니다.

모델에서 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

위의 내용은 기본 modelbinder 사용에 적용됩니다.

커스텀 ModelBinder

위 코드에서 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)] 에이 있고 여전히 오류가 발생합니다
DW

사용자 정의 ModelBinder를 사용하는 경우이 주위에 방법으로 내 개정 답변을 참조하십시오
ericdc

감사합니다.하지만이 줄이 마음에 들지 않습니다. bindingContext.GetValueFromValueProvider
DW

GetValueFromValueProvider는 공용 정적 클래스에 있어야합니다. 위의 편집 내용을 확인하십시오.
ericdc

Ta, valueProviderResult가 null을 반환합니까? var valueProviderResult = bindingContext.GetValueFromValueProvider (shouldPerformRequestValidation);
DW

31

시험:

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

이것을 시도 할 때 호출 할 수없는 멤버 'System.web.HttpRequestBase.Unvalidated'는 메서드처럼 사용할 수 없다는 예외가 발생합니다. 이게 바뀌 었나요?
Stack0verflow 2014-04-23

7
두 번째 줄은 정말이어야합니다var re = request.Unvalidated.Form["ConfirmationMessage"];
Stack0verflow 2014-04-23

5

@DW의 답변을 확장하여 편집 컨트롤러에서 양식 값을 반복하면서 모든 인스턴스를 Request.Params.AllKeyswith Request.Unvalidated.Form.AllKeys와 모든 인스턴스 를로 바꿔야 Request[key]했습니다 Request.Unvalidated.Form[key].

이것은 나를 위해 일한 유일한 솔루션이었습니다.


0

Mike Godin이 썼 듯이 [ValidateInput (false)] 속성을 설정하더라도 Request.Form 대신 Request.Unvalidated.Form 을 사용해야합니다. 이것은 ASP.NET MVC 5에서 저에게 효과적 이었습니다.


1
모델에이 속성이 있더라도 Request.Form에 대한 모든 액세스는 기본 컨트롤러 (즉, 로그 또는 디버그 목적)에서 데이터에 액세스하기 때문에 실제로 유용한 조언이었습니다.
nsimeonov

-5

다음은 클라이언트 수준에서 인코딩하고 서버 수준에서 디코딩하는 단계입니다.

  1. jquery 제출 방법을 사용하여 양식을 게시하십시오.

  2. jquery 버튼에서 서버에 게시하려는 이벤트 메소드 인코딩 필드를 클릭하십시오. 예:

    $("#field").val(encodeURIComponent($("#field").val()))
    $("#formid").submit();
    
  3. 컨트롤러 수준에서 다음을 사용하여 모든 양식 ID 값에 액세스합니다.

    HttpUtility.UrlDecode(Request["fieldid"])

샘플 예 :

  • 컨트롤러 레벨 :

    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));
    }
    
  • 클라이언트 수준 :

    <% 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> 
    <% } %>
    

문서 준비 기능에서 :

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

4
Jquery 및 클라이언트 측 기술은 MVC와 관련이 없으며 유효성 검사는 MVC 프레임 워크를 사용하여 서버 측에서 발생합니다. 유효한 답변이 아닙니다
diegosasw 2015 년

1
Microsoft가 말 그대로 AllowHtml 특성을 무시하고 서버 측에서 실행 가능한 유일한 솔루션이 기본 모델 바인더의 기능을 대체하는 것임을 감안할 때 클라이언트 측 인코딩이 완벽하게 유효한 옵션이라고 주장합니다.
Jonathan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.