Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC ASP.NET MVC3 AllowHtml Attribute Not Working?

The question is very simple:

Say you have a model called Person

public class Person
{

       public int PersonID {get; set;}

       public string Name {get; set;}

       [AllowHtml] // Allow html in Intro property
       public string Intro {get; set;}

       [ScaffoldColumn(false)]
       public string ComplicatedValue {get; set;}

}

In controller's Create action

[HttpPost]
public ActionResult Create(Person o, FormCollection collection)
{

// whatever code here;

}

If you run it,

  1. input plain text for Intro, no problem happens.
  2. input html content for Intro, no matter how you set your configuration file, it will tells "A potential dangerous ..."

I DO find the reason of this problem.

If you change the function to

public ActionResult Create(Person o) // Get rid of the *FormCollection collection*
{

// whatever code here;

}

This will eliminate the "potential dangerous" error.

But my problem is that for my application, I have to use the secondary parameter FormCollection collection in the Create Action method, because I need to use some other control values and server variable to assign a calculated value to the ComplicatedValue property.

If any expert of ASP.NET MVC3 have met the same problem as me, and found a solution, please kindly let me know.

like image 313
carter gu Avatar asked Jan 22 '11 01:01

carter gu


2 Answers

This forum at this link discusses this issue at length and gives some workarounds.

http://forums.asp.net/p/1621677/4161637.aspx

Here is one solution from that thread that may or may not work for you:

public ActionResult Create(Person o) // Get rid of the *FormCollection collection*
{    
FormCollection form = new FormCollection(Request.Unvalidated().Form);
// whatever code here;
}

or my own recommendation:

public ActionResult Create(Person o, int otherControlValue1, int otherControlValue2, ...)
{        
      o.ComplicatedValue = CalculateComplicatedValue(otherControlValue1, otherControlValue2, ...);
      // whatever code here.

}

In my case, I am not using the FormCollection, but it was there so that I had a different footprint on my [HttpPost] method. I did this hack and put in a bogus parameter:

public virtual ActionResult Edit(int id)
{
    return View(this.repository.GetById(id));
}
[HttpPost]
public virtual ActionResult Edit(int id, int? bogusID)
{            
    var d = repository.GetById(id);
    if (TryUpdateModel(d))
    {
        repository.Save();
        return RedirectToAction("Index");
    }
    return View();
}
like image 137
Quesi Avatar answered Sep 22 '22 07:09

Quesi


Might I suggest using a custom model binder instead of pulling the complex data from a FormCollection. Scott Hanselman has a blog post on creating a custom model binder that would serve as a good template. In his post he puts together a DateTimeModelBinder that allows a DateTime property to be set either by a single input containing the date or a pair of inputs containing a date and a time.

like image 40
tvanfosson Avatar answered Sep 22 '22 07:09

tvanfosson