jellz77
jellz77

Reputation: 354

FormCollection MVC5 not passing decimal to controller

i keep getting errors when trying to post an <input type="number"> from my view to my controller using FormCollection. the database type for expenseBackup is a decimal(8,2). I keep getting "Cannot impliticity convert string to decimal?". Then when i try expenseBackup = Int32.Parse(formValues["expenseBackup"]), i get "Input string was not in correct format". i don't want to have to convert anything in the controller i don't understand why it won't just pass as a decimal through the FormCollection.

Controller

 [HttpPost]
        public ActionResult Create(FormCollection formValues)
        {
            var data = new usr_ebillingClientDatabase()
            {
                client = formValues["client"], //is a string from form
                expenseBackup = formValues["expenseBackup"] //is a decimal from form
            };
            dataContext.table1.InsertOnSubmit(data);
            try
            {
                dataContext.SubmitChanges();                    
                return RedirectToAction("Index");
            }
            catch (Exception e)
            {
                return RedirectToAction("Index");
            }           
        }

View

<div class="form-group">
    <div class="col-md-10">
        @Html.EditorFor(model => model.expenseBackup, new { htmlAttributes = new { @class = "form-control" , , @type="number", @step=".01" } })
    </div>
</div> 

Upvotes: 0

Views: 554

Answers (2)

Tetsuya Yamamoto
Tetsuya Yamamoto

Reputation: 24957

FormCollection is a key-value pair collection (NameValueCollection) which returns values as string based from provided key, which is also a string. If you're in doubt which number format applied by numeric input during submit, use combination of decimal.TryParse() and if-condition with string.IsNullOrEmpty() to check null/empty string value:

decimal expense;
if (!string.IsNullOrEmpty(formValues["expenseBackup"]) 
    && decimal.TryParse(formValues["expenseBackup"], out expense))
{
    var data = new usr_ebillingClientDatabase()
    {
        client = formValues["client"],
        expenseBackup = expense
    };

    // insert to database
}
else
{
    // unable to parse numeric value, do something else
}

If you're sure that numeric representation passed in FormCollection uses certain decimal separator other than default, use NumberFormatInfo when parsing with decimal.Parse()/decimal.TryParse():

var numberFormat = new System.Globalization.NumberFormatInfo() { NumberDecimalSeparator = "," };

var data = new usr_ebillingClientDatabase()
{
    client = formValues["client"],
    expenseBackup = decimal.Parse(formValues["expenseBackup"], numberFormat);
};

However, I recommend using strongly-typed viewmodel over FormCollection because you're using EditorFor, and it will pass property values directly to controller when viewmodel name is included as action parameter.

Upvotes: 1

Sean T
Sean T

Reputation: 2504

when you're reading the field from formValues["expenseBackup"] it's being read as a string. Convert it to a decimal using Convert.ToDecimal().

expenseBackup = Convert.ToDecimal(formValues["expenseBackup"] ?? 0m);

Upvotes: 1

Related Questions