10

I'm working with MVC recently and I've encountered a strange problem while trying to send request to my controller using ajax. I'm using JQuery (version 1.3.2) that came directly with MVC, I'm trying to send such ajax request:

$.post("Home/OpenTrade", { price: 1.5 }, function() { }, "json");

I've also tried parseFloat("1.5") instead of 1.5.
When I try to receive this value in controller using

[AcceptVerbs( HttpVerbs.Post)]
public void OpenTrade(float? price)

My price is always null. If I omit ? the controller is not called at all (which is nothing surprising), I've tried using decimal as well as double type. Furthermore, this function works when I'm sending integer data (if I send 1 this controller is called, and float? price is filled properly). Am I missing something, or is it a bug?

Ad. I can receive price as string, and then parse it manually, but I don't like this solution, as it's not elegant and it fights the whole purpose of using framework like MVC to do this for me.

Edit & Answer: Using Joel's advice, I've created a Model Binder, which I'll post, maybe someone will use it:


class DoubleModelBinder : IModelBinder
{
    #region IModelBinder Members

    public object BindModel(ControllerContext controllerContext, ModelBindingContext    bindingContext)
    {
        string numStr = bindingContext.ValueProvider[bindingContext.ModelName].AttemptedValue;
        double res;

        if (!double.TryParse(numStr, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.InvariantCulture, out res))
        {
            if (bindingContext.ModelType == typeof(double?))
                return null;
            throw new ArgumentException();
        }

        if (bindingContext.ModelType == typeof(double?))
            return new Nullable<double>(res);
        else
            return res;
    }

    #endregion
}

It may be registered as double and double? binder, for double? it will pass null to controller, if value could not have been resolved.

Btw. Any ideas why floats and doubles don't work out of the box (for me?)?

Edit2 & Solution: Ok, this is going to be funny :). It didn't work for me, because requested string was sending 1.5432 (an example value), which is perfectly ok, but... MVC was trying to decode it internally using my culture settings, which are expecting numbers to be in format 1,5432, so the conversion has failed silently.
So, thing to remember: if you are living in strange country, double-check your culture settings.

4
  • 1
    I tried chucking together a test app to see if I could recreate the original problem (cut'n'pasted both your jquery call and the action signature) but it all works fine for me. The float parameter always has the value. ....strange huh Commented Aug 17, 2009 at 2:47
  • 1
    They work for me. Use an HTTP tool like Fiddler or HttpWatch to see if your AJAX post is properly formed. Commented Aug 17, 2009 at 2:49
  • That's strange... I will take a closer look into this than, maybe I'll discover what's wrong. Commented Aug 17, 2009 at 3:01
  • +1 for a well-written question, as well as for posting the solution for other people. It was helpful for me. Thank you. Commented Aug 7, 2013 at 7:38

5 Answers 5

5

make a float model binder. That can pull the appropriate value from the form collection, parse it, and return it as the argument

Sign up to request clarification or add additional context in comments.

Comments

2
{ price: '1,5' } 

should be fine.

1 Comment

I've encountered many similar problems. Using string and converting it back in controller is the simplest, sometimes even the most elegant, way of getting it to work.
0

EDIT: Do you need to be using jQuery post? Is there any way you can use the built in support for ajax to create a link and what is the result in that case? e.g.

Ajax.ActionLink("Link Name", "OpenTrade", "Home",
                   new { price = 1.5f },
                   new AjaxOptions
                   {
                       OnSuccess = "success",
                       ....
                   })

When specifying a float value you generally have to postfix the value with 'f' e.g.

float f = 1.5f;

Have you tried this?

An alternative solution would be to change your service method to:

[AcceptVerbs( HttpVerbs.Post)]
public void OpenTrade(int dollars, int cents)

2 Comments

Ad 1. Remember, that I have number inside javascript, not inside c# code, so adding 'f' wouldn't help. Ad 2. It is a solution, but it's even less elegant than getting string imho (I'm ignoring the fact, that I'm passing money value as float number, which is almost never a good idea, but in this case, I know what I'm doing)
Ad edit. I rather need whole logic implemented in JS, as I'm not just putting few links with ajax queries, besides, I don't believe that problem lies on JS side, which is just passing data to MVC in a given format.
0

Have you checked to see what the JSON response from the server is? I notice you haven't encapsulated your price variable with double quotes, so your post to the server will look like:

{'price':1.5}

I don't know if that will be a problem with only one data parameter, but I suspect what you actually want it to look like is

"{'price':1.5}"

jQuery ajax methods being passed to ASP.Net methods should have a string for the data parameter otherwise jQuery may serialise the data incorrectly. Having the string means jQuery will leave your JSON object alone and pass the entire string to ASP.NET for parsing on the server side.

1 Comment

I don't think this is the case, when I've did what you have advised me, everything has stopped working :), like if I've tried to pass some other data, which are string - they weren't deserialized by mvc at all.
-2
UpdateImage(string rotationAngle)
        {
            double d;
            double.TryParse(rotationAngle, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.InvariantCulture, out d);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.