我的问题是,当我尝试通过ajax将double或decimal发送到我的C#MVC Controller时,该值始终为null。我可以将值作为字符串发送,我可以毫无问题地发送整数。为什么我不能发送带小数的值?当我检查从客户端发送的请求时,存在正确的值(表单数据为price=84.50
)。
错误:
参数字典包含参数'price'的空条目 非可空类型'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!");
});
});
C#:
[HttpPost]
public void PriceFunction(decimal price)
{
// I have tried with decimal, double and double?.
}
答案 0 :(得分:10)
发送小数值时,需要对数据进行字符串化。
data: JSON.stringify({ Price: 5.0 })
这是因为默认绑定器将十进制视为整数。
您当然可以更改为使用DecimalModelBinder
,详情请参阅以下链接:
答案 1 :(得分:6)
这可能是文化问题
确保您发送到您的操作的字符串符合当前的Culture。 (选中十进制数字分隔符.
,
)
<强>为例强>
e.g。在法语服务器上,99.1
不会被理解为99,1
,但会转换为0
。
<强>解决方案强>
在这种情况下,一种解决方案是在Web.Config
<system.web>
...
<globalization uiCulture="en" culture="en-US"/>
</system.web>
或,用客户端的正确替换分隔符。
答案 2 :(得分:2)
尝试对传递给ajax调用的data参数的JSON进行字符串化。这应该可以解决问题。
var data = { price: price };
$.ajax({
url: 'PriceFunction',
type: 'POST',
data: JSON.stringify(data)
}).
答案 3 :(得分:1)
首先,使用toFixed
这种方式会导致错误,因为您尝试在jquery对象上使用该方法
使用
parseFloat(value).toFixed(2)
答案 4 :(得分:1)
我建议尝试将数据作为JSON传递。
data: JSON.stringify({ price: price }),
contentType: "application/json; charset=utf-8"
请注意包含内容类型。为了让活页夹知道如何解析您的请求数据,可能需要它。
答案 5 :(得分:0)
尝试更改
var price = Number($('#price').val().toFixed(2));
要
var price = parseFloat($('#price').val()).toFixed(2);
答案 6 :(得分:0)
错误表示您的价格数据:{price:price}实际上是数据:{price:null}在发布时。
所以这段代码,
数($( '#价格')VAL()toFixed(2));
返回 null 值。更准确地说,将Number()调用更改为parseFloat()以获得正确的结果。以下是经过测试和运行的代码。
Ajax致电:
<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());
}
答案 7 :(得分:0)
尝试更改:
public class test
{
public decimal Price { get; set; }
}
[HttpPost]
public void Test(test whatever)
{
// I have tried with decimal, double and double?.
}
关注财产名称和数据类型:&#39; json&#39;在Ajax调用中
答案 8 :(得分:0)
For me only this way works:
type: "POST",
data: 'price': parseFloat($(#price).val()).toFixed(2).replace(".", ","),
success: function(data){
...
}
It probably depend from your current culture in environment. I hope it will helps someone.
答案 9 :(得分:0)
我必须绑定更复杂的模型,因此字符串化解决方案不是我想要的。 因此,我找到了这篇文章,其中展示了如何扩展默认模型活页夹以接受小数。
这是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 ...
}
答案 10 :(得分:0)
实际上什么都没有,但是 我使用的解决方案是。 您必须将值作为字符串发送,并在服务器端将其转换为十进制。
所以您的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);
}
Web.Config
它包含您的全球文化!
<globalization uiCulture="your" culture="your-CULTURE" />
答案 11 :(得分:0)
为“ en-US”文化在后端强制进行十进制分析的另一种方法是在应用程序启动时将其设置在某个位置(如果您不想通过 web.config进行操作)。
对于ASP.NET MVC,它可能是 Global.asax ,对于ASP.NET Core MVC,它可能是 Startup.cs 。
var ci = new CultureInfo("en-US");
CultureInfo.CurrentCulture = ci;
CultureInfo.DefaultThreadCurrentCulture = ci;