views:

233

answers:

2

Hi folks,

I'm about to start a new ASP.NET MVC application. In it we have a number of drop downs lists/boxes. I have no problem rending them to the ui etc.

My two questions are:-

  1. Is it possible to bind the selected value of a drop down list to an enumeration? Does anyone else actually do this (if this is possible)
  2. Are there any good code practices to prevent the code from throwning an exception if a user tries to inject a different value for the drop down. Eg. instead of posting the selected value which is a number/int .. they try and hack the post data and change it to a string of non numbers. And what is this security hack/exploit, called?

cheers :)

+1  A: 

From MVCContrib:

SelectListItem[] selectListItems = Enum.GetNames(propertyInfo.PropertyType).Select(
            s => new SelectListItem {Text = s, Value = s, Selected = s == value.ToString()}).ToArray();

If the enum values are always known you could use a parameter constraint in your routes: http://www.asp.net/(S(pdfrohu0ajmwt445fanvj2r3))/learn/mvc/tutorial-24-cs.aspx

That way nothing will ever be able to Get or Post to you receiving action method.

jfar
So i'll need the MVCContrib dll then? and also, is it possible to make an _enum_ route constraint?
Pure.Krome
No, just paste that code in.
jfar
+3  A: 

As jfar posted, use:

string selectedValue = "1";

SelectListItem[] selectListItems = Enum.GetNames(typeof(MyEnumeration)).Select(
        s => new SelectListItem { Text = s, Value = s, Selected = s == selectedValue}).ToArray();

which is from MVCContrib, you don't to include the DLL, this is just code found in MVCContrib.

To protect against CSRF(Cross Site Request Forgery), you can use the <%= Html.AntiForgeryToken() %> in the view under the respective form that will be posted, and decorate the appropriate action with [ValidateAntiForgeryToken]. More details on the Html.AntiForgeryToken() can be found here.

EDIT As per Comment

Well first, you'll need to place the SelectListItem[] in the ViewData so you can access it in the view:

Action

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult MyView(string enumValue)
{
    string selectedValue = "1"; // fill this with the value you want to be selected

    SelectListItem[] selectListItems = Enum.GetNames(typeof(MyEnumeration)).Select(
            s => new SelectListItem { Text = s, Value = s, Selected = s == selectedValue}).ToArray();

    ViewData["enumValue"] = selectListItems;

    return View();    
}

and in your view the following form will work.

<form method="post">
    <%= Html.AntiForgeryToken() %>
    <%= Html.DropDownList("enumValue") %>
</form>

The HTML helper will output the proper select control.

Back in your controller, this is the action that will accept the form post

[ValidateAntiForgeryToken]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyView(int enumValue)
{
    // enumValue will have the selected value
    ViewData["Message"] = "You selected the Enum name" + Enum.GetName(typeof(MyEnumeration), enumValue);

    return View();    
}
Baddie
AHHHHHHHHHHHHH!! so the keyword here is CSRF .. hot socks! what about when u wish to read the selected value? can u post some code for that (ie. what will be in the Action method). please?
Pure.Krome