1

When I send the form from client side I can see that Nap.GetUp has a value. However when debugging I see that the controller has not gotten a value for Nap.GetUp. I don't know where the error lies or how to find it...

Client Side

While in the controller: Controller problem

This problem arises when I format the value of my input field(for editing my form). Since my database uses "," for punctuation while my input (type="number" step="0.1) in the view requires "." punctuation in order input the value to field. I solve this this way:

@{
    string getUpValue = (Model == null) ? null : Model.GetUp.ToString().Replace(",", ".");
}
@Html.LabelFor(m => m.GetUp, new { @class = "" })
@Html.TextBoxFor(m => m.GetUp, new { @type = "number", @step = "0.1", @Value = getUpValue, @class = "form-control" })

If I remove Value = getUpValue, in the TextBox there is no problem in saving the value to the database, but the value will not load into the field when editing the form later on...

--- Edit ---

Model:

 public class Nap
 {
     public int Id { get; set; }

     public Period Period { get; set; }
     public int PeriodId { get; set; }

     [Required]
     [Display(Name = "Start")]
     public DateTime Start { get; set; }

     [Required]
     [Display(Name = "Slutt")]
     public DateTime End { get; set; }

     [Display(Name = "Sovne")]
     public int? FallAsleep { get; set; }
     [Display(Name = "Våkne")]
     public double? GetUp { get; set; }
     ...

Controller:

public ActionResult Edit(int id)
{
    var nap = _context.Naps.Single(m => m.Id == id);

    if (nap == null)
        return HttpNotFound();

    return View("NapForm", nap);
}
Sondre
  • 105
  • 2
  • 11

1 Answers1

1

You haven't given us your view model but I think it should be something like this

public class NapViewModel
{
    public int  PeriodId { get; set; }
    public decimal? GetUp { get; set; }
    // other fields
}

Remove the

@{
string getUpValue = (Model == null) ? null : Model.GetUp.ToString().Replace(",",".");
}

from the view, razor is the wrong place to do this and in this case is the reason you are having this problem. Then your form code should be this

@using (Html.BeginForm())
{
    @Html.LabelFor(m => m.GetUp, new { @class = "" })
    @Html.TextBoxFor(m => m.GetUp, new { @type = "number", @step = "0.1", @class = "form-control" })

@*other form elements*@
}

Then put all the code for populating the viewmodel into the controller. I.e. transform what comes from the database for GetUp into a decimal. And then the model binding will just work as you expect. Then when the data comes back to the controller you will need to change the GetUp value to an appropriate form so that you can save to it your database.

Edit:

The problem is to do with culture. The controller is expecting the double to have a , but instead it has a full stop (period). The solution is a custom model binder.

Add this class to your project

public class DoubleModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult == null)
        {
            return base.BindModel(controllerContext, bindingContext);
        }
        return double.Parse(valueProviderResult.AttemptedValue, System.Globalization.CultureInfo.InvariantCulture);           
    }
}

Then add this to your Global.asax

   protected void Application_Start()
        {
            //other application_start code goes here

            ModelBinders.Binders.Add(typeof(double?), new DoubleModelBinder());
            ModelBinders.Binders.Add(typeof(double), new DoubleModelBinder());
        }

Then to make sure your getup value appears in the text box change the getup textbox code to

 @Html.TextBoxFor(m => m.GetUp, new {
    @type = "number",
    @step = "0.1",
    @class = "form-control",
    @Value =Model.GetUp.ToString().Replace(",",".") })
Dave Barnett
  • 2,045
  • 2
  • 16
  • 32
  • I realy tried implementing this, but I am unable to(I don't think I can change the punctuation of the data type double). However I figured out that the only problem with my previous code was that my input `type="number" step=0.1"`is sending the `GetUp` value with "." punctuation instead of "," punctuation making the model unable to recognize the input as double. Is it possible to fix this? – Sondre Aug 17 '19 at 19:36
  • @Sondre I've edited the answer based on your comment. – Dave Barnett Aug 17 '19 at 19:57
  • The database stores the double(`Nap.GetUp`) with "," punctuation. Won't this mean that `` will affect the data that is already in the database? (Btw: I am not using a view model, I am only using the Nap model) – Sondre Aug 17 '19 at 19:59
  • @Sondre Yes I see what you mean, I've removed that from my answer. I think I've found a solution for you here [Accept comma and dot as decimal separator](https://stackoverflow.com/questions/14400643/accept-comma-and-dot-as-decimal-separator) – Dave Barnett Aug 17 '19 at 20:19
  • Yea, but it looks a rather bit complicated considering I don't know how to use ModelBinding; would it not be easier to just replace the `"."` with `","` in the form submision? – Sondre Aug 17 '19 at 20:44
  • I Solved the problem by creating a ViewModel that accompanies a string value that I store the GetUp value in; I format it in the controller and pass it to Nap.GetUp. However to me it seams as it should be possible to format the FormData from client side before it is passed to the controller. Is that posible? – Sondre Aug 18 '19 at 05:04
  • @Sondre That would be possible. You could use javascript and change the value of the getup textbox on submit. I don't think that would necessarily be better than what you've done though. On the model binding its not too bad I've added some instructions to my answer as to how the answer could work. – Dave Barnett Aug 18 '19 at 08:08