0

I have a from like below

<form action="/" method="get">
    <input type="radio" name="sort" value="date-desc" checked>
    <input type="radio" name="sort" value="price-desc">
    <input type="radio" name="sort" value="price-asc">
    <input type="radio" name="sort" value="like-desc">
    <input type="radio" name="sort" value="like-asc">
    <input type="checkbox" name="show-discount">
    <input type="checkbox" name="show-new">
    <input type="submit" class="btn btn-default" value="Search">
</form>

it returns url like: <site>?sort=date-desc&show-discount=on&show-new=on

i want to bind it to the controller action, the action is like below:

public ActionResult Index([Bind(Prefix = "sort")]string Sort, 
    [Bind(Prefix = "show-discount")]bool? ShowDiscount = null, 
    [Bind(Prefix = "show-new")]bool? ShowNew = null)
{

}

the problem is ShowDiscount and ShowNew parameter always null (didn't bound properly).

i think the problem caused by the checkbox when checked it written as cb-name=on instead of cb-name=true. and also when the checkbox unchecked it will not written on the url.

is there a proper way to do this?

and is there a way to map Sort parameter to enumeration?

1
  • Use a view model and strongly typed html helpers and let MVC do it all for you. Commented Sep 28, 2014 at 23:27

2 Answers 2

1

Use a view model

Model

public class MyModel
{
  public string sort { get; set; }
  public bool show-discount { get; set; }
  public bool show-discount { get; set; } // or bool? if you want it to be nullable
  public bool show-new { get; set; }
}

Controller

public ActionResult Edit()
{
  MyModel model = new MyModel();
  model.date-desc = "date-desc"; // set default
  return View(model)
}

public ActionResult Edit(MyModel model)
{
  .... // model is correctly bound with selected values

View

@model MyModel
@using (Html.BeginForm())
{
  .....
  @Html.RadioButtonFor(m => m.sort, "date-desc", new { id = "date-desc" });
  @Html.RadioButtonFor(m => m.sort, "price-desc", new { id = "price-desc" });
  @Html.RadioButtonFor(m => m.sort, "price-asc", new { id = "price-asc" });
  @Html.RadioButtonFor(m => m.sort, "like-desc", new { id = "like-desc" });
  @Html.RadioButtonFor(m => m.sort, "like-asc", new { id = "like-asc" });
  @Html.CheckBoxFor(m => m.show-discount);
  @Html.CheckBoxFor(m => m.show-new);
  <input type="submit" class="btn btn-default" value="Search">
}

Note you can make sort and enum. If the bool values are nullable, CheckBoxFor will render a dropdown list with 3 values (to allow selection of null)

Note also in your code you do not need the [Bind(Prefix... You could have used <input type="checkbox" name="show-discount" value="true"> but this would only work for non-nullable booleans since unchecked checkboxes do not post back. If you leave it unchecked you would get null, not false

Edit

If you want to use an enum

public enum MyEnum
{
  date-desc,
  price-desc,
  ....
}

public class MyModel
{
  public MyEnum sort { get; set; }
  ....

View (include @using for the assembly where you have defined the enum)

@Html.RadioButtonFor(m => m.sort, MyEnum.date-desc, new { id = "date-desc" });
@Html.RadioButtonFor(m => m.sort, MyEnum.price-desc, new { id = "date-desc" });
....
Sign up to request clarification or add additional context in comments.

4 Comments

thank you for your response, by using value="true" on checkbox like you suggested is working now. second question, is it possible to bind radio button Sort with enum instead of string but keep the value date-desc, price-desc, price-asc?
Yes, you can use an enum. I'll update answer shortly (but please get into the habit of using a view model and strongly typed html helpers - you will never have these problems)
(but please get into the habit of using a view model and strongly typed html helpers - you will never have these problems) i used view model binding well, but it is a special case and its a long story :) waiting for the update :)
OK, I've update answer based on using a view model. If you don't want that you can always convert the string to an enum using Enum.TryParse()
0

Create a ViewModel that will contain properties that match your form inputs.

public class ViewModel 
{
    public bool ShowDiscount { get; set; }
    // add additional properties
}

Then, in your form on the view, add @Html.CheckBoxFor(m => m.ShowDiscount)

<form action="/" method="get">
    @Html.CheckBoxFor(m => m.ShowDiscount)
    <input type="submit" class="btn btn-default" value="Search">
</form>

Be sure to let the view know which type of model it should be expecting. At the top of the view specify.

@model YourNamespace.ViewModel

Your controller method will now look like this:

public ActionResult Index(ViewModel v)
{
    // do work here.
}

The framework will do the binding for you.

1 Comment

thank you for your response, i know the view model binding well but i don't like the binding with default property name, my action will be called from outside website and it should be able to call from a form via get method. it is about eye candy thing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.