mvc - First "get" result for request.params get exception, second "get" is ok. i have a page that has a field with xml text in it. i am using validation=false. but, on post method in the controller i am trying to get the requset.params and i get an error of "A potentially dangerous Request.Form value was detected from the client". after some digging and debugging i see that first time i am trying to get the request.params i get an exception, BUT when i try to get it for the second time everything is ok.
this is the filter i am using to avoid problems with the xml (i am converting it to binary data and empty the xml string field):
public class RestAPIAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
((SimulationModel)filterContext.ActionParameters["model"]).Data = CommonConverters.StringToByteArray(((SimulationModel)filterContext.ActionParameters["model"]).StringData);
((SimulationModel)filterContext.ActionParameters["model"]).StringData = string.Empty;
base.OnActionExecuting(filterContext);
}
}
and this is the post method:
[HttpPost]
[ValidateInput(false)]
[RestAPIAttribute]
public ActionResult EditSimulation(Guid id, SimulationModel model)
{
try
{
model.RelationModel = new RelationModel(false, this.Resource("Simulations.AddToObjects"), "SimulationToObjects", id, sessionId, Request.Params, new List<ObjectTypes>() { ObjectTypes.Entity, ObjectTypes.EntityType, ObjectTypes.Universe });
}
catch (Exception ex)
{
Logger.LogException(ex);
}
/* more code here*/
return View(newModel);
}
now, as you can see one of the RelationModel's constuctor has a parameter of request.param which is giving me the problem.
my currenty workaround for this issue is just calling it twice (but i am looking for better solution or at least an explanation):
[HttpPost]
[ValidateInput(false)]
[RestAPIAttribute]
public ActionResult EditSimulation(Guid id, SimulationModel model)
{
try
{
try
{
model.RelationModel = new RelationModel(false, this.Resource("Simulations.AddToObjects"), "SimulationToObjects", id, sessionId, Request.Params, new List<ObjectTypes>() { ObjectTypes.Entity, ObjectTypes.EntityType, ObjectTypes.Universe });
}
catch
{
model.RelationModel = new RelationModel(false, this.Resource("Simulations.AddToObjects"), "SimulationToObjects", id, sessionId, Request.Params, new List<ObjectTypes>() { ObjectTypes.Entity, ObjectTypes.EntityType, ObjectTypes.Universe });
}
}
catch (Exception ex)
{
Logger.LogException(ex);
}
/* more code here*/
return View(newModel);
}
If this is ASP.NET MVC 3+ you could use the [AllowHtml]
attribute on your model property that contains the XML. This will disable request validation only for this property and not the entire request:
public class SimulationModel
{
[AllowHtml]
public string StringData { get; set; }
}
and then:
[HttpPost]
public ActionResult EditSimulation(Guid id, SimulationModel model)
{
// you could directly use model.StringData here without any
// encoding needed
return View(newModel);
}
And if this is an ASP.NET MVC 2 application running in ASP.NET 4.0 in addition to decorating your controller action with the [ValidateInput(false)]
attribute you might need to put the following in your web.config:
<httpRuntime requestValidationMode="2.0"/>
If it is an ASP.NET MVC 3 application you don't need to put this line in your web.config in order to use the [ValidateInput(false)]
attribute.