ASP.NET MVC Özel bir model bağlayıcı kullanılırken istemciden potansiyel olarak tehlikeli bir Request.Form değeri algılandı


97

Hatayı buradan almak:

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

Yalnızca belirli bir değer seçimine nasıl izin veririm? yani

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

1
Potansiyel olarak tehlikeli bir Request.Form değerinin olası kopyası istemciden algılandı, Webforms veya MVC olması fark etmez.
Erik Philips

2
Teşekkürler, ama sorunuma farklı gözüyle bakmadınız
DW

Aynı kök problemi, tek fark, bununla başa çıkmanın MVC'ye özgü yolları olabileceğidir.
Erik Philips

EF kullanırken, bizzehdee cevabına buradan bakın stackoverflow.com/questions/17964313/…
Petr

Yanıtlar:


227

Birkaç seçeneğiniz var.

Modelde, HTML'ye izin vermeniz gereken her özelliğe bu özelliği ekleyin - en iyi seçim

using System.Web.Mvc;

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

Denetleyici eyleminde, tüm HTML'ye izin vermek için bu özniteliği ekleyin

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

Web.config dosyasında kaba kuvvet - kesinlikle önerilmez

Web.config dosyasında, etiketlerin içine requestValidationMode = "2.0" niteliğine sahip httpRuntime öğesini ekleyin. Ayrıca, pages öğesine validateRequest = "false" özniteliğini ekleyin.

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

Daha fazla bilgi: http://davidhayden.com/blog/dave/archive/2011/01/16/AllowHtmlAttributeASPNETMVC3.aspx

Yukarıdakiler, varsayılan model ciltleyicinin kullanımları için çalışır.

Özel ModelBinder

Yukarıdaki kodda bağlamaContext.ValueProvider.GetValue () çağrısının, özniteliklerden bağımsız olarak verileri her zaman doğruladığı görülmektedir. ASP.NET MVC kaynaklarına derinlemesine incelemek, DefaultModelBinder'in önce istek doğrulamasının gerekli olup olmadığını kontrol ettiğini ve ardından doğrulamanın gerekli olup olmadığını gösteren bir parametre ile bindingContext.UnvalidatedValueProvider.GetValue () yöntemini çağırdığını ortaya çıkarır.

Ne yazık ki, kapalı, özel veya cahil geliştiricileri tehlikeli şeyler yapmaktan korumak için herhangi bir çerçeve kodu kullanamıyoruz, ancak AllowHtml ve ValidateInput niteliklerine saygı duyan çalışan bir özel model bağlayıcı oluşturmak çok zor değil:

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

Diğer gerekli parça, doğrulanmamış bir değeri almanın bir yoludur. Bu örnekte ModelBindingContext sınıfı için bir genişletme yöntemi kullanıyoruz:

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

Bununla ilgili daha fazla bilgi için http://blogs.taiga.nl/martijn/2011/09/29/custom-model-binders-and-request-validation/


bunu denetleyicide görüyorum [HttpPost, ValidateInput (false)] ve hala hatayı alıyorum
DW

Özel bir modelbinder kullanırken bunun etrafında bir yolla gözden geçirilmiş cevabımı görün
ericdc

Teşekkürler, ancak bu satır bağlamaContext.GetValueFromValueProvider
DW

GetValueFromValueProvider'ın genel bir statik sınıfta olması gerekir. Yukarıdaki düzenlemelere göz atın.
ericdc

Ta, valueProviderResult null tho? var valueProviderResult = bindingContext.GetValueFromValueProvider (shouldPerformRequestValidation);
DW

31

Deneyin:

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

Bunu denediğimde, şöyle bir istisna alıyorum: Çağrılamayan üye 'System.web.HttpRequestBase.Unvalidated' bir yöntem gibi kullanılamaz. Bu şey değişti mi?
Stack0verflow

7
İkinci satır gerçekten şöyle olmalıvar re = request.Unvalidated.Form["ConfirmationMessage"];
Stack0verflow

5

Form değerleri üzerinde yineleme içinde, benim Düzenleme denetleyicisi, @DW gelen cevap üzerine Genişleyen, ben tüm örneklerini değiştirmek zorunda Request.Params.AllKeysolan Request.Unvalidated.Form.AllKeysve tüm örneklerini Request[key]birlikte Request.Unvalidated.Form[key].

Benim için işe yarayan tek çözüm buydu.


0

Mike Godin'in yazdığı gibi, [ValidateInput (false)] özniteliğini ayarlasanız bile, Request.Form yerine Request.Unvalidated.Form kullanmanız gerekir Bu, ASP.NET MVC 5 ile benim için çalıştı


1
Bu aslında yararlı bir tavsiyeydi, çünkü bir temel denetleyiciden verilere erişmek (yani, günlük veya hata ayıklama amacıyla) Request.Form'a herhangi bir erişim, model bu özniteliğe sahip olsa bile istisna atar.
nsimeonov

-4

İstemci düzeyinde kodlama ve sunucu düzeyinde çözme adımları şunlardır:

  1. Formu jquery gönderme yöntemini kullanarak gönderin.

  2. Jquery düğmesinde sunucuya göndermek istediğiniz olay yöntemi kodlama alanını tıklayın. Misal:

    $("#field").val(encodeURIComponent($("#field").val()))
    $("#formid").submit();
    
  3. Denetleyici Düzeyinde, kullanarak tüm form kimliği değerlerine erişin

    HttpUtility.UrlDecode(Request["fieldid"])
    

Örnek örnek:

  • Denetleyici seviyesi:

    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));
    }
    
  • İstemci seviyesi:

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

Belge Hazır işlevinde:

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

4
Jquery ve istemci tarafı teknolojisinin MVC ile ilgisi yoktur, doğrulama MVC çerçevesi ile sunucu tarafında gerçekleşir. Bu geçerli bir cevap değil
diegosasw

2
Microsoft'un AllowHtml özniteliğini tam anlamıyla görmezden geldiği ve uygulanabilir tek çözümün sunucu tarafı varsayılan model bağlayıcının işlevselliğini değiştirmek olduğu göz önüne alındığında, istemci tarafı kodlamanın mükemmel bir şekilde geçerli bir seçenek olduğunu iddia ediyorum.
Jonathan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.