Reputation: 2431
I have created a base controller that each of my controllers inherit. In this controller I have the OnActionExecuting method. I use this to check the url for some parameters. The problem I have is that I get an exception whenever I post html data. I have setup the model using the [AllowHTML] tag and it works on all the other actions.
How do I make the OnActionExecuting method pay attention to the model validation?
This is what I have in my base controller
public abstract class BaseController : Controller
{
[ValidateInput(false)]
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if ((Request.Params["api"] == null || string.IsNullOrEmpty(Request.Params["api"])))
return;
if ((Request.Params["api"] != null && !string.IsNullOrEmpty(Request.Params["api"])))
{
if (Session["api"] == null)
{
Session["api"] = Request.Params["api"];
}
}
}
and below is an extract from my model
[MetadataType(typeof (MessagingMetaData))]
public partial class Message
{
}
public class MessagingMetaData
{
[Required]
[Display(Name = "Message")]
[DataType(DataType.Html)]
[AllowHtml]
public string Body { get; set; }
}
here is the stack trace
[System.Web.HttpRequestValidationException]
Exception Message: A potentially dangerous Request.Form value was detected from the client (Content="
sdafdsafdsafdsac__DisplayClass12.b__d(String value, String key) at Microsoft.Web.Infrastructure.DynamicValidationHelper.LazilyEvaluatedNameObjectEntry.ValidateObject() at Microsoft.Web.Infrastructure.DynamicValidationHelper.LazilyEvaluatedNameObjectEntry.GetValidatedObject() at Microsoft.Web.Infrastructure.DynamicValidationHelper.LazilyValidatingArrayList.get_Item(Int32 index) at System.Collections.Specialized.NameObjectCollectionBase.BaseGetKey(Int32 index) at System.Collections.Specialized.NameValueCollection.GetKey(Int32 index) at System.Collections.Specialized.NameValueCollection.Add(NameValueCollection c) at System.Web.HttpRequest.FillInParamsCollection() at System.Web.HttpRequest.GetParams() at System.Web.HttpRequest.get_Params() at System.Web.HttpRequestWrapper.get_Params() at ProjectX.BaseController.OnActionExecuting(ActionExecutingContext filterContext) at System.Web.Mvc.Controller.System.Web.Mvc.IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<>c__DisplayClass17.b__14() at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) at System.Web.Mvc.Controller.ExecuteCore() at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.b__5() at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.b__0() at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.b__7(IAsyncResult _) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.b__d() at System.Web.Mvc.SecurityUtil.b__0(Action f) at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
sorry for the layout would not copy new lines for some reason
Upvotes: 2
Views: 1896
Reputation: 657
I know this is 4 years late, but I'm adding this answer for future searchers.
You can just use Request.Unvalidated["api"]
public abstract class BaseController : Controller
{
[ValidateInput(false)]
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if ((Request.Unvalidated["api"] == null || string.IsNullOrEmpty(Request.Unvalidated["api"])))
return;
if ((Request.Unvalidated["api"] != null && !string.IsNullOrEmpty(Request.Unvalidated["api"])))
{
if (Session["api"] == null)
{
Session["api"] = Request.Unvalidated["api"];
}
}
}
}
Upvotes: 1
Reputation: 2431
Not sure if this is the solution to the problem, but is a work around that works.
By changing Request.Params to Request.QueryString I guess the validation is not called
public abstract class BaseController : Controller
{
[ValidateInput(false)]
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if ((Request.QueryString["api"] == null || string.IsNullOrEmpty(Request.QueryString["api"])))
return;
if ((Request.QueryString["api"] != null && !string.IsNullOrEmpty(Request.QueryString["api"])))
{
if (Session["api"] == null)
{
Session["api"] = Request.Params["api"];
}
}
}
Upvotes: 0
Reputation: 156524
I believe you should be able to use the Unvalidated()
extension method. For example, change Request.Params["api"]
to Request.Unvalidated().Params["api"]
.
Upvotes: 2