С# MVC Controller не может получить десятичные или двойные значения из запроса AJAX POST

Моя проблема в том, что когда я пытаюсь отправить двойной или десятичный код через ajax в мой контроллер MVC MVC, значение всегда равно нулю. Я могу отправить значение как строку, и я могу отправить целые числа без проблем. Почему я не могу отправлять значения с десятичными знаками? Когда я проверяю запрос, который отправляется от клиента, есть правильное значение (данные формы price=84.50).

Ошибка:

Словарь параметров содержит нулевую запись для параметра "цена" неэлементного типа "System.Decimal"

Html:

 <input type="number" step="1" class="form-control" name="price" id="price">
 <button type="button" class="btn btn-success">Send</button>

JavaScript:

$('.btn-success').click(function () {

    //var price = $('#price').val(); - Did not work
    //var price = Number($('#price').val()); Did not work
    var price = Number($('#price').val()).toFixed(2); // Does not work

    $.ajax({
        url: 'PriceFunction',
        type: 'POST',
        data: {
            price: price,
        }
    }).done(function () {

    }).fail(function () {
        console.log("Error in ajaxfunction!");
    });
});

С#:

    [HttpPost]
    public void PriceFunction(decimal price)
    {
     // I have tried with decimal, double and double?.     
    }

Ответ 1

Вам нужно сжать ваши данные, когда вы отправляете десятичные значения.

data: JSON.stringify({ Price: 5.0 })

Это потому, что десятичное число считается целым числом по умолчанию.

Вы можете, конечно, перейти на использование DecimalModelBinder, которое подробно описано по следующей ссылке:

Ошибки привязки ASP.NET MVC3 JSON

Ответ 2

Это может быть проблемой культуры

Убедитесь, что строка, которую вы отправляете в свое действие, соответствует текущей культуре. (проверьте разделители десятичных чисел . ,)

Exemple

например на французском сервере 99.1 не будет пониматься как 99,1, но будет преобразован в 0.

Решение

В этом случае одним из решений является определение культуры в вашем Web.Config

  <system.web>
    ...
    <globalization uiCulture="en" culture="en-US"/>
  </system.web>

Или, заменив разделитель на соответствующий на стороне клиента.

Ответ 3

Попробуйте подстроить JSON, переданный параметру данных вызова ajax. Это должно сделать трюк.

var data = { price: price };

$.ajax({
    url: 'PriceFunction',
    type: 'POST',
    data: JSON.stringify(data)
}).

Ответ 4

Во-первых, использование toFixed таким образом должно привести к ошибке, поскольку вы пытаетесь использовать этот метод для объекта jquery

использовать
parseFloat(value).toFixed(2)

Ответ 5

Я предлагаю попробовать передать данные как JSON.

data: JSON.stringify({ price: price }),
contentType: "application/json; charset=utf-8"

Просто обратите внимание, чтобы включить тип содержимого. Это может потребоваться, чтобы связующее знает, как анализировать данные вашего запроса.

Ответ 6

Попробуйте изменить

var price = Number($('#price').val().toFixed(2));

Для

var price = parseFloat($('#price').val()).toFixed(2);

Ответ 7

Ошибка говорит ваши данные о цене: {цена: цена} на самом деле данные: {цена: null} во время публикации.

Итак, этот код,

Номер ($ ( '# цена') Вал() toFixed (2).).

возвращает значение null. Чтобы быть более точным, измените вызов Number() на parseFloat(), чтобы получить правильный результат. Ниже приведен тестовый и рабочий код.

введите описание изображения здесь

Ajax Call:

    <script language="javascript">
    function TriggerAction()
    {
        alert($('#price').val());
        var price = parseFloat($('#price').val()).toFixed(2);
        alert(price);
        callAjax("PriceFunction", price);
    }

    function ajaxCallResult(result, action)
    {
        if (action==="PriceFunction")
        {
            alert(result);
        }
        else if (action==="error")
        {
            alert("Error: "+action+" call failed!");
        }
    }

    function callAjax(action, param) {

        $.ajax({
            type: "POST",
            url: "/Home/"+action,    
            data: {param: param},
            success: function (result) {
                ajaxCallResult(result, action);
            },
            error: function (req, status, error) {
                ajaxCallResult("error", action);
            }
        });
    }
</script>

<input type="number" step="1" class="form-control" name="price" id="price">
<button type="button" class="btn btn-success" onclick="TriggerAction();">Send</button>

Код MVC:

        [HttpPost]
        public ActionResult PriceFunction(decimal param)
        {
            return Json("OK Got the value:" + param.ToString());
        }

Ответ 8

Попробуйте изменить:

    public class test
    {
        public decimal Price { get; set; }
    }

    [HttpPost]
    public void Test(test whatever)
    {
        // I have tried with decimal, double and double?.     
    }

Уход за свойством Name и dataType: 'json' в вызове Ajax

Ответ 9

У меня только так работает:

type: "POST",
data: 'price': parseFloat($(#price).val()).toFixed(2).replace(".", ","),
success: function(data){
...
}

Это, вероятно, зависит от вашей нынешней культуры в окружающей среде. Я надеюсь, что это поможет кому-то.

Ответ 10

Мне пришлось связать более сложную модель, поэтому решение с использованием stringify оказалось не тем, что я хотел. Итак, я нашел эту статью, в которой показано, как расширить механизм связывания модели по умолчанию, чтобы принимать десятичные дроби.

Вот код от haacked.com:

Сначала вы расширяете IModelBinder:

using System;
using System.Globalization;
using System.Web.Mvc;

public class DecimalModelBinder : IModelBinder {
    public object BindModel(ControllerContext controllerContext, 
        ModelBindingContext bindingContext) {
        ValueProviderResult valueResult = bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName);
        ModelState modelState = new ModelState { Value = valueResult };
        object actualValue = null;
        try {
            actualValue = Convert.ToDecimal(valueResult.AttemptedValue, 
                CultureInfo.CurrentCulture);
        }
        catch (FormatException e) {
            modelState.Errors.Add(e);
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }
}

Затем вы регистрируете эту папку:

protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();

    ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());

    // All other stuff ...
}