This question is locked. New answers and comments are not allowed.
I've got a very basic question, and I'm hoping someone out there already has a nice solution. In my model, I have a property defined as:
public
int
? LocationId {
get
;
set
; }
What I'd like to do, is have a dropdown list with items similar to the following...
Text: "--Please Select--"
, Value:
null
Text: "United States"
, Value:
"1"
,
Text: "Other"
, Value:
"2"
UPDATE: Please see my second post below with the example and updated (correct) error message. Thanks!
5 Answers, 1 is accepted
0

Jatin
Top achievements
Rank 1
answered on 31 Jul 2011, 03:50 PM
Hi,
I have used Telerik DropDownList with int? recently and it works well. The MVC passes the null value (equivalent) to the nullable int, if the option with null value is choosen. If your LocationId is of nullable int, there should'nt be any validation error in first place. When is the validation error thrown in your case ?
regards,
Nirvan.
I have used Telerik DropDownList with int? recently and it works well. The MVC passes the null value (equivalent) to the nullable int, if the option with null value is choosen. If your LocationId is of nullable int, there should'nt be any validation error in first place. When is the validation error thrown in your case ?
regards,
Nirvan.
0

Jeff
Top achievements
Rank 1
answered on 01 Aug 2011, 03:17 PM
Hi Nirvan - Thanks for the help. I did a little more research and put together a sample that shows the problem. The original error message in my post was incorrect. You asked when the validation error occurs. Specifically, what seems to happen is that the browser or drop down doesn't recognize the null value, and sends back the text of "-- Please Select --". The server side validation fires and returns the error "The value '-- Please Select --' is not valid for LocationId. "
Here's the code and flow:
Model:
ViewModel:
Controller:
View:
Main html output:
jQuery for choices (showing "Please Select" mapping to null):
When selecting "Please Select" and submitting, Fiddler shows that the browser (ie 8) is sending the string literal to the server:
Which results in this validation error being returned:
I'm assuming somewhere that I'm doing something wrong, but I just don't know what it is. :-) Hopefully seeing the code, you'll spot what I'm missing. I can also email the sample solution if you're interested in reproducing it.
Thanks again,
Jeff
Here's the code and flow:
Model:
public
class
TestEntity
{
[Key]
public
int
TestEntityId {
get
;
set
; }
public
int
? LocationId {
get
;
set
; }
}
ViewModel:
public
class
TestViewModel
{
public
IEnumerable<SelectListItem> LocationList {
get
;
set
; }
public
TestEntity MyEntity {
get
;
set
; }
public
string
Result {
get
;
set
; }
}
Controller:
public
class
HomeController : Controller
{
public
ActionResult Index()
{
TestViewModel model =
new
TestViewModel { MyEntity =
new
TestEntity() };
BuildSelectList( model );
return
View( model );
}
[HttpPost]
public
ActionResult Index( TestViewModel model )
{
model.Result =
"Model state valid = "
+ TryValidateModel( model );
BuildSelectList( model );
return
View( model );
}
private
void
BuildSelectList( TestViewModel model )
{
List<SelectListItem> locationList =
new
List<SelectListItem>();
locationList.Add(
new
SelectListItem { Text =
"-- Please Select --"
, Value =
null
} );
locationList.Add(
new
SelectListItem { Text =
"US"
, Value =
"1"
} );
locationList.Add(
new
SelectListItem { Text =
"Other"
, Value =
"2"
} );
model.LocationList = locationList;
}
}
View:
@model TelerikMvcApplication2.ViewModels.TestViewModel
@{
ViewBag.Title = "Home Page";
}
@using ( Html.BeginForm() )
{
<
p
>
Location: @(Html.Telerik().DropDownListFor( model => model.MyEntity.LocationId ).BindTo( Model.LocationList ))
@Html.ValidationMessageFor( model => model.MyEntity.LocationId )
</
p
>
<
br
/>
<
input
type
=
"submit"
value
=
"Save"
class
=
"btn-save"
/>
<
p
>
@Model.Result
</
p
>
}
Main html output:
<
p
>
Location: <
div
class
=
"t-widget t-dropdown t-header"
><
div
class
=
"t-dropdown-wrap t-state-default"
><
span
class
=
"t-input"
>-- Please Select --</
span
><
span
class
=
"t-select"
><
span
class
=
"t-icon t-arrow-down"
>select</
span
></
span
></
div
><
input
data-val
=
"true"
data-val-number
=
"The field LocationId must be a number."
id
=
"MyEntity_LocationId"
name
=
"MyEntity.LocationId"
style
=
"display:none"
type
=
"text"
value
=
"-- Please Select --"
/></
div
>
<
span
class
=
"field-validation-valid"
data-valmsg-for
=
"MyEntity.LocationId"
data-valmsg-replace
=
"true"
></
span
>
</
p
>
jQuery for choices (showing "Please Select" mapping to null):
jQuery('#MyEntity_LocationId').tDropDownList({data:[{"Text":"-- Please Select --","Value":null},{"Text":"US","Value":"1"},{"Text":"Other","Value":"2"}]});
When selecting "Please Select" and submitting, Fiddler shows that the browser (ie 8) is sending the string literal to the server:
MyEntity.LocationId=--+Please+Select+--
Which results in this validation error being returned:
The value '-- Please Select --' is not valid for LocationId.
I'm assuming somewhere that I'm doing something wrong, but I just don't know what it is. :-) Hopefully seeing the code, you'll spot what I'm missing. I can also email the sample solution if you're interested in reproducing it.
Thanks again,
Jeff
0

Jatin
Top achievements
Rank 1
answered on 01 Aug 2011, 06:45 PM
Jeff,
I had used a different approach as indicated by code below. I tried to test your code and it is indeed throwing validation error. Here is what I have used.
Entity
View
Controller
ViewModel
View Success
One more thing. You are receiving ViewModel as parameter to your post method(Index); So by the time its first statement is executed, the ViewModel is already been validated when MVC tried to push the values to the ViewModel. So instead of calling TryValidateModel() I think you should just use ModelState.IsValid property of Model to see if the validation has failed or not.
cheers,
Nirvan.
I had used a different approach as indicated by code below. I tried to test your code and it is indeed throwing validation error. Here is what I have used.
Entity
public
class
State {
public
int
? Id {
get
;
set
; }
[Required(ErrorMessage =
"State is Required"
)]
public
string
Name {
get
;
set
; }
}
View
@(Html.Telerik().DropDownListFor(m => m.SelectedStateId)
.BindTo(new SelectList(Model.States, "Id", "Name"))
.Effects(f => f.Toggle()))
Controller
using
(var context =
new
LocationContext()) {
viewModel.States.Add(
new
State { Name =
"Select State"
}); //Leave the Id Null
viewModel.States.AddRange(context.States.ToList());
}
ViewModel
public
class
HomeViewModel {
public
List<State> States {
get
;
set
; }
....
}
View Success
<div>@(Model.SelectedStateId ==
null
? -100 : Model.SelectedStateId)</div> <!-- Show -100 because MVC will print nothing
for
null
-->
One more thing. You are receiving ViewModel as parameter to your post method(Index); So by the time its first statement is executed, the ViewModel is already been validated when MVC tried to push the values to the ViewModel. So instead of calling TryValidateModel() I think you should just use ModelState.IsValid property of Model to see if the validation has failed or not.
cheers,
Nirvan.
0

Jeff
Top achievements
Rank 1
answered on 01 Aug 2011, 07:42 PM
Thanks Nirvan -
I updated my code to match what you have (I believe), but I'm still seeing validation errors. Can you try adding in a check in your project for ModelState.IsValid (thanks for that suggestion vs. TryUpdateModel) and a validation error message? I do get the -100 value displayed in the output, but it looks like the model update actually failed, and null is just the default value for SelectedStateId.
Controller:
ViewModel:
View:
Thanks again,
Jeff
I updated my code to match what you have (I believe), but I'm still seeing validation errors. Can you try adding in a check in your project for ModelState.IsValid (thanks for that suggestion vs. TryUpdateModel) and a validation error message? I do get the -100 value displayed in the output, but it looks like the model update actually failed, and null is just the default value for SelectedStateId.
Controller:
public
class
HomeController : Controller
{
public
ActionResult Index()
{
TestViewModel model =
new
TestViewModel();
BuildSelectList( model );
return
View( model );
}
[HttpPost]
public
ActionResult Index( TestViewModel model )
{
model.Result =
"Model state valid = "
+ ModelState.IsValid;
BuildSelectList( model );
return
View( model );
}
private
void
BuildSelectList( TestViewModel model )
{
model.States =
new
List<State>();
model.States.Add(
new
State { Name =
"-- Please Select --"
} );
model.States.Add(
new
State { Name =
"US"
, Id = 1 } );
model.States.Add(
new
State { Name =
"Other"
, Id = 2 } );
}
}
ViewModel:
public
class
TestViewModel
{
public
string
Result {
get
;
set
; }
public
int
? SelectedStateId {
get
;
set
; }
public
List<State> States {
get
;
set
; }
}
View:
@using ( Html.BeginForm() )
{
<
p
>
State: @(Html.Telerik().DropDownListFor(m => m.SelectedStateId)
.BindTo(new SelectList(Model.States, "Id", "Name"))
.Effects(f => f.Toggle()))
@Html.ValidationMessageFor( m => m.SelectedStateId )
</
p
>
<
br
/>
<
input
type
=
"submit"
value
=
"Save"
class
=
"btn-save"
/>
<
div
>@Model.Result</
div
>
<
br
/>
<
div
>@(Model.SelectedStateId == null ? -100 : Model.SelectedStateId)</
div
>
<!-- Show -100 because MVC will print nothing fornull-->
}
Thanks again,
Jeff
0

Jatin
Top achievements
Rank 1
answered on 02 Aug 2011, 03:08 AM
Jeff,
I am afraid I didn't test the code properly in hurry. I don't think it would be possible to use null in this case. I apologise for misguiding you. The LocationId seems to be a positive value, so you could try using a negative value for the first option. I am relatively new to MVC and Microsoft Technologies so I won't comment on the best practice, but if I were in a similar situation, I would certainly try using the negative value.
regards,
Nirvan.
I am afraid I didn't test the code properly in hurry. I don't think it would be possible to use null in this case. I apologise for misguiding you. The LocationId seems to be a positive value, so you could try using a negative value for the first option. I am relatively new to MVC and Microsoft Technologies so I won't comment on the best practice, but if I were in a similar situation, I would certainly try using the negative value.
regards,
Nirvan.