我试图通过[FromForm]属性在AspNet.Core MVC中创建一个对象。
[HttpPost]
[Consumes("application/x-www-form-urlencoded")]
[Route("[action]")]
public async Task<IActionResult> Payments([FromForm]IncomingPayment dataPayment)
我的问题:我的属性Amount
从未成功设置,即始终为零。
/// <summary>
/// Объект данных запроса уведомления о поступившем платеже
/// </summary>
public class IncomingPayment
{
/// <summary>
/// Сумма поступившего платежа
/// </summary>
[Required]
[BindProperty(Name = "amount", SupportsGet = false)]
public decimal Amount { get; set; }
}
如何考虑转换为十进制值格式(680.37
)
最好使用属性?
答案 0 :(得分:0)
以这种方式解决了我的问题
/// <summary>
/// Объект данных запроса уведомления о поступившем платеже
/// </summary>
public class IncomingPayment
{
/// <summary>
/// Сумма поступившего платежа
/// </summary>
public decimal Amount { get; set; }
/// <summary>
/// Сумма поступившего платежа в строковом формате
/// </summary>
private string _amountAsString;
/// <summary>
/// Обертка суммы поступившего платежа в строковом формате
/// </summary>
[Required]
[BindProperty(Name = "amount", SupportsGet = false)]
public string AmountAsString
{
get => _amountAsString;
set
{
_amountAsString = value;
if (!decimal.TryParse(_amountAsString.Replace('.', Program.PointChar), out var doubleAmount)) return;
Amount = doubleAmount;
}
}
}
好吧,当我启动应用程序时,我得到了系统分隔符
PointChar = double.TryParse("1,2", out _) ? ',' : '.';
答案 1 :(得分:0)
自定义活页夹是前往此处的方法。这将是一个更通用的解决方案。
自定义活页夹
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using System;
using System.Globalization;
using System.Threading.Tasks;
namespace CustomBinders
{
public class DecimalBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.ModelType == typeof(decimal))
{
return new BinderTypeModelBinder(typeof(DecimalBinder));
}
if (context.Metadata.ModelType == typeof(decimal?))
{
return new BinderTypeModelBinder(typeof(DecimalBinder));
}
return null;
}
}
public class DecimalBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var valueResult = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName);
if (valueResult == ValueProviderResult.None)
{
return Task.CompletedTask;
}
object actualValue = null;
var culture = CultureInfo.CurrentCulture;
if (valueResult.FirstValue != string.Empty)
{
try
{
// Try with your local culture
actualValue = Convert.ToDecimal(valueResult.FirstValue, culture);
}
catch (FormatException)
{
try
{
// Try with your invariant culture
actualValue = Convert.ToDecimal(valueResult.FirstValue, CultureInfo.InvariantCulture);
}
catch (FormatException)
{
bindingContext.ModelState.TryAddModelError(
bindingContext.ModelName,
"You should provide a valid decimal value");
return Task.CompletedTask;
}
}
}
bindingContext.Result = ModelBindingResult.Success(actualValue);
return Task.CompletedTask;
}
}
}
并像这样使用它
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// ... rest of configuration
services.AddMvc( options=>
{
// ... rest of configuration
options.ModelBinderProviders.Insert(0, new DecimalBinderProvider());
}
);
}