Karl Humphries
Karl Humphries

Reputation: 328

Converting string to int (2)

I am using the following action to save Nav Bar Items edited from with admin of a content management system:

    [HttpPost]
    public ActionResult aSaveNavs()
    {
        aLoggedIn();

        NavItemsDataContext navDB = new NavItemsDataContext();
        Nav n = navDB.Navs.Select(row => row.ID == Convert.ToInt32(Request.Form["ID"]));

        n.NavName = Request.Form["NavName"];
        n.NavURL = Request.Form["NavURL"];
        n.NavEnabled = (Request.Form["NavEnabled"] == "true" ? true : false);
        navDB.SubmitChanges();

        return Redirect("/Admin/aHome");
    }

I am using the following view:

@{
List<Nav> navList = HtmlHelpers.GetNavList();
}

@foreach (Nav item in navList)
{
    <tr>
        <td style="width: 150px; text-align: center;">
            @item.NavName
        </td>
        <td style="width: 150px; text-align: center;">
            <input id="NavName" name="NavName" type="text" value="@item.NavName" />
        </td>
        <td style="width: 150px; text-align: center;">
            <input id="NavURL" name="NavURL" type="text" value="@item.NavURL" />
        </td>
        <td>
            <input id="ID" name="ID" type="text" readonly="readonly" value="@item.ID" />
        </td>
    </tr>
}

Obviously the view has a few other bits in but this is the section in question.

When I try and save my changes, I get "System.FormatException: Input string was not in a correct format." and the following line is highlighted:

Nav n = navDB.Navs.FirstOrDefault(row => row.ID == Convert.ToInt32(Request.Form["ID"]));

Thanks in advance for any help with this.

Upvotes: 0

Views: 5017

Answers (3)

Shyju
Shyju

Reputation: 218732

Already people answered how to do the conversion and fixing that error. I will talk about something else.

As SLaks mentioned, you should better consider using the MVC ModelBinding. The MVC team created it for making our life better. So we should take advantage of this nice feature.

Modelbinding depends on strongly typed views. So Let's create a ViewModel(just a plain class) for your view.

public class NavigationViewModel
{
  public int ID { set;get;}
  public string Name { set;get;}
  public string URL{ set;get;}
  public bool IsEnabled{ set;get;}
}

From your GET action, Create an object of this class and pass it to your View.

public ActionResult aSaveNavs()
{
  NavigationViewModel vm=new NavigationViewModel();
  return View(vm); 
}

Now we will change our View to a strongly typed view.

@model NavigationViewModel
@using(Html.BeginForm())
{
  @Html.LabelFor(x=>x.Name) 
  @Html.TextBoxFor(x=>x.Name)

  @Html.LabelFor(x=>x.URL)
  @Html.TextBoxFor(x=>x.URL)

  @Html.LabelFor(x=>x.IsEnabled)
  @Html.CheckBoxFor(x=>x.IsEnabled)

  @Html.HiddenFor(x=>x.ID)
  <input type="submit"  />
}

Now in your POST action, read the form values from the Properties of our Model/ViewModel

[HttpPost]
public ActionResult aSaveNews(NavigationViewModel model)
{
 if(ModelState.IsValid)
 {
    //Now you will have the Value inside the model Properties
    string name=model.Name;
    string url=model.URL;
    bool isEnabled=model.IsEnabled;

    //now save to your Data base and Redirect (PRG pattern)

 }
 return View(model);
}

Also try to avoid calling your methods inside the View (you are calling the GetNavList in the view).That appraoch (mixing code and UI) will make your View ugly. One of the main goal of MVC framework is the seperation of concern. So Let us keep the UI and functionality seperate (and clean).

Have an action method for your Listing and get the Items there and pass that to your strongly typed view.

public ActionResult aHome()
{
  List<Nav> navList = HtmlHelpers.GetNavList();
  return View(navList);
}

And Change View to

@model IEnumerable<Nav>
@foreach (Nav item in navList)
{
  <p>@item.Name</p>      
}

If you have a single page where you want to update multiple records, consider using EditorTemplates also.

Upvotes: 4

Allie
Allie

Reputation: 1179

Convert.ToInt32 may still throw an error, for example when it is empty, therefore use this:

int result=0;
Int32.TryParse(Request.Form["ID"].ToString(), out result);

and then in your code:

Nav n = navDB.Navs.FirstOrDefault(row => row.ID == result);   

Upvotes: 2

JleruOHeP
JleruOHeP

Reputation: 10376

Try to check, if you can convert string to int using int.TryParse

Upvotes: 2

Related Questions