c# MVC控制器无法从Ajax POST请求中获取十进制或双精度值
本文关键字:获取 十进制 双精度 请求 POST 控制器 MVC Ajax | 更新日期: 2023-09-27 18:15:54
我的问题是,当我试图通过ajax发送一个双或十进制到我的c# MVC控制器的值总是空。我可以发送值作为字符串,我可以发送整数没有问题。为什么我不能发送带有小数的值?当我检查从客户端发送的请求时,正确的值就在那里(表单数据是price=84.50
)。
Html:参数字典包含参数'price'的空条目非空类型的系统。小数的
<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?.
}
这可能是文化问题
确保发送给操作的字符串符合当前区域性。(检查十进制数字分隔符.
,
)
为例
。在法语服务器上,99.1
不会被理解为99,1
,而会被转换为0
。
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 ...
}