programing

C# MVC 컨트롤러가 Ajax POST 요청에서 십진수 또는 이중 값을 가져올 수 없습니다.

muds 2023. 8. 19. 10:57
반응형

C# MVC 컨트롤러가 Ajax POST 요청에서 십진수 또는 이중 값을 가져올 수 없습니다.

문제는 Ajax를 통해 두 배 또는 십진수를 C#MVC 컨트롤러로 전송하려고 할 때 값이 항상 null이라는 것입니다.나는 값을 문자열로 보낼 수 있고 정수를 문제없이 보낼 수 있습니다.소수점 이하의 값을 보낼 수 없는 이유는 무엇입니까?고객으로부터 전송된 요청을 확인하면 올바른 값이 표시됩니다(폼 데이터는price=84.50).

오류:

매개 변수 사전에 null이 불가능한 유형 'System'의 매개 변수 'price'에 대한 null 항목이 포함되어 있습니다.십진법'

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?.     
    }

문화 문제일 수 있습니다.

수행으로 보낼 문자열이 현재 Culture를 준수하는지 확인합니다.(십진수 구분 기호 확인). ,)

예제

예를 들어 프랑스 서버에서는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 호출의 데이터 매개 변수에 전달된 JSON을 문자열화해 보십시오.그것이 효과가 있어야 해요.

var data = { price: price };

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

첫째, 사용toFixed당신이 jquery 객체에 그 방법을 사용하려고 하기 때문에 이 방법은 당신에게 오류를 가져올 것입니다.

사용하다
parseFloat(value).toFixed(2)

제가 사용하는 솔루션 외에는 실제로 작동하는 것이 없습니다.당신은 서버 측에서 값을 문자열로 보내고 십진법으로 변환해야 합니다.

그래서 당신의 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" />

"en-US" 문화에 대해 백엔드 측에서 십진법 구문 분석을 강제하는 또 다른 방법은 응용 프로그램 시작 시 어딘가에 설정하는 것입니다(web.config를 통해 수행하지 않으려면).

ASP용.NET MVC일 수 있습니다. 예를 들어.Global.asax, ASP를 위한 Whie.NET Core MVC는 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?.     
    }

속성 이름 및 dataType에 대한 관심: Ajax 호출의 'json'

나에게는 오직 이 방법이 효과적입니다.

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

그것은 아마도 환경에 대한 당신의 현재 문화에 의존할 것입니다.누군가에게 도움이 되길 바랍니다.

저는 더 복잡한 모델을 바인딩해야 했기 때문에 솔루션을 스트링화하는 것은 제가 원했던 것이 아니었습니다.그래서 기본 모델 바인더를 소수점 이하로 확장하는 방법을 보여주는 이 기사를 찾았습니다.

다음은 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 ...
}

언급URL : https://stackoverflow.com/questions/32908503/c-sharp-mvc-controller-cannot-get-decimal-or-double-values-from-ajax-post-reques

반응형