Reputation: 91
I have an ASP.NET MVC app wherein I want a certain radio button to be checked based on information supplied in the URL. But (and this is key...), I want the right radio button to be checked regardless of the case of the supplied route parameter.
I thought I could easily do this with a bit of code in the controller that would take the route parameter of any case and transform it to always be upper case (to match the values assigned to the radio buttons), but so far I have been unsuccessful (and have discovered some things that make me suspect that I do not know exactly how model information is supplied to my view).
My route is set up like so in the RouteConfig:
routes.MapRoute(
name: "LegSearch",
url: "{controller}/{action}/{requestType}/{billNumber}/{sessionNumber}",
defaults: new { controller = "FNSPublicSearch", action = "Search", requestType = UrlParameter.Optional, billNumber = UrlParameter.Optional, sessionNumber = UrlParameter.Optional }
);
The Search action in my controller looks like this:
[HttpGet]
public ActionResult Search(string requestType, string billNumber, string sessionNumber)
{
var searchModel = new SearchModel();
string requestTypeUpperCase = null;
if (!string.IsNullOrWhiteSpace(requestType))
{
requestTypeUpperCase = char.ToUpper(requestType[0]) + requestType.Substring(1);
searchModel.RequestType = requestTypeUpperCase;
}
//other search-related code
}
My model:
public class SearchModel : ISearchModel
{
[DisplayName("Session year")]
public string SessionYear { get; set; }
[DisplayName("Bill or initiative number")]
public string BillNumber { get; set; }
[DisplayName("Bill or initiative title")]
public string BillTitle { get; set; }
[DisplayName("Bill or initiative")]
public string RequestType { get; set; }
public List<ISearchResult> Results { get; set; }
public List<string> BillNumbers { get; set; }
public List<SelectListItem> SessionYears { get; set; }
}
And finally, here's how the radio buttons are set up on my view:
@model FNSPublicSearch.Models.SearchModel
@using (Html.BeginForm("Search", "FNSPublicSearch", FormMethod.Post, new { id = "SearchForm" }))
{
//some other markup...
@Html.LabelFor(model => model.RequestType, new { @class = "control-label", style="margin-left: 5px"})
@Html.RadioButtonFor(model => model.RequestType, "Bill") Bill
@Html.RadioButtonFor(model => model.RequestType, "Initiative") Initiative
@Html.RadioButtonFor(model => model.RequestType, "Both") Both
//some more markup...
}
I've also discovered a couple of things with a little bit of JavaScript at the bottom of my view, and that's what makes me think I don't fully know how these radio buttons are getting selected...
For instance,
var selectedType = "@Model.RequestType";
comes out as "Bill," for instance, regardless of whether "Bill" or "bill" is supplied to the route. I assume that's due to the code I've written in the controller, which is supposed to pass an upper-cased version of the requestType parameter over to the view.
Where I get confused, though, is when I do
console.log($('input:radio[name="RequestType"]:checked').val());
the output is "Bill" when "Bill" is supplied to the route (great!), but "undefined" when I supply "bill" (huh? what happened to my controller code?).
So, we have expected result: hitting "{controller}/{action}/Bill/{billNumber}/{sessionNumber}" results in the same radio button being checked as ""{controller}/{action}/bill/{billNumber}/{sessionNumber}".
Actual result: uppercase "Bill" in the URL, which matches the value of the Bill radio button, works; that radio button will be checked. Lowercase "bill" results in none of the radio buttons being checked, I guess because "bill" does not equal the button's value of "Bill" (even though I thought I accounted for that in the controller).
I'm fairly new to MVC, so any help is appreciated, thanks!
Upvotes: 0
Views: 187
Reputation: 91
Well, I figured out a solution, but I feel like it's pretty hacky. I would much prefer someone who knows explain how those radio buttons really receive model information in the original scenario I posted, but anyway...
I added a new model property:
public string TypeRadio { get; set; }
Then I altered the controller to set that differently-named property based on the original route parameter:
[HttpGet]
public ActionResult Search(string requestType, string billNumber, string sessionNumber)
{
var searchModel = new SearchModel();
string requestTypeLowerCase = string.Empty;
if (!string.IsNullOrWhiteSpace(requestType))
{
requestTypeLowerCase = requestType.ToLower();
searchModel.RequestType = requestTypeLowerCase;
searchModel.TypeRadio = requestTypeLowerCase;
}
//etc...
}
Then I bound my radio buttons to that new, differently-named property:
@Html.RadioButtonFor(model => model.TypeRadio, "bill") Bill
@Html.RadioButtonFor(model => model.TypeRadio, "initiative") Initiative
@Html.RadioButtonFor(model => model.TypeRadio, "both") Both
Left the route the same, and everything worked, since (I guess?) now the radio button names have nothing to do with the route parameters.
Thanks for looking, but definitely feel free to enlighten me if you know why my original code didn't work!
Upvotes: 0