c# MVC控制器无法从Ajax POST请求中获取十进制或双精度值

本文关键字:获取 十进制 双精度 请求 POST 控制器 MVC Ajax | 更新日期: 2023-09-27 18:15:54

我的问题是,当我试图通过ajax发送一个双或十进制到我的c# MVC控制器的值总是空。我可以发送值作为字符串,我可以发送整数没有问题。为什么我不能发送带有小数的值?当我检查从客户端发送的请求时,正确的值就在那里(表单数据是price=84.50)。

错误:

参数字典包含参数'price'的空条目非空类型的系统。小数的

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!");
    });
});
c#:

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

c# MVC控制器无法从Ajax POST请求中获取十进制或双精度值

这可能是文化问题

确保发送给操作的字符串符合当前区域性。(检查十进制数字分隔符. ,)

为例

。在法语服务器上,99.1不会被理解为99,1,而会被转换为0

<<p> 解决方案/strong> 在这种情况下,一个解决方案是在Web.Config 中定义文化。
  <system.web>
    ...
    <globalization uiCulture="en" culture="en-US"/>
  </system.web>

,在客户端用合适的分隔符替换分隔符

发送十进制值时需要对数据进行字符串化。

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

这是因为默认绑定器将小数视为整数。

您当然可以更改为使用DecimalModelBinder,详细信息请参见以下链接:

ASP。NET MVC3 JSON十进制绑定问题

我建议尝试将数据作为JSON传递。

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

只要注意包含内容类型即可。为了让绑定器知道如何解析请求的数据,它可能是必需的。

尝试将传递给ajax调用的data参数的JSON字符串化。那应该可以了。

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

首先,使用toFixed这种方式应该得到一个错误,因为你试图在jquery对象上使用该方法

使用


parseFloat(value).toFixed(2)

实际上什么都不起作用,但是我用的解是。您必须将value作为字符串发送,并在服务器端将其转换为十进制。

所以你的JS是完美的!

$('.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!");
    });
});
c#

public readonly CultureInfo ciEN = new CultureInfo("en-US");
 
public async Task<ActionResult> YourMVCMethod(string myDecimalValue)
{
   var message = string.Empty;
   bool result = false;
   try
   {
         decimal convertedValue = Convert.ToDecimal(myDecimalValue, ciEN);
         // process it...                   
                
   }
   catch (Exception ex)
   {
       return Json(new { success = result, msg = ex.Message }, JsonRequestBehavior.AllowGet);
   }
   return Json(new { success = result, msg = message }, JsonRequestBehavior.AllowGet);
}

网络。配置

包含您的全局文化!

<globalization uiCulture="your" culture="your-CULTURE" />

另一种在后端强制进行十进制解析的方法为"en-US"文化是在应用程序启动的某个地方设置它(如果你不想通过web.config设置)。

ASP。它可能是。NET MVC,例如Global。asax,白色表示ASP。它可以是Startup.cs.

var ci = new CultureInfo("en-US"); 
CultureInfo.CurrentCulture = ci;
CultureInfo.DefaultThreadCurrentCulture = ci;

尝试更改

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

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

尝试更改:

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

关心Ajax调用中的属性Name和dataType: 'json'

对我来说只有这样才管用:

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

这可能取决于你当前的文化环境。

我必须绑定更复杂的模型,所以stringify解决方案不是我想要的。所以我找到了这篇文章,它展示了如何扩展默认模型绑定器以接受小数。

下面是来自haacked.com的代码:

首先扩展IModelBinder:

using System;
using System.Globalization;
using System.Web.Mvc;
using System.Web.Http.Controllers;
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 ...
}