1

I am having the same problem many people already had - Model Binder doesn't accept localized decimal input. In all of the threads, here and other forums, the recommended solution is implementing a custom ModelBinder.

My problem is that those solutions somehow don't work for me. Let's use this solution for example: comma decimal seperator in asp.net mvc 5

When I reference all namespaces, two errors remain:

Error CS0115 'DecimalModelBinder.BindModel(ControllerContext, ModelBindingContext)': no suitable method found to override ...

and

Error CS0173 Type of conditional expression cannot be determined because there is no implicit conversion between 'bool' and 'decimal'

Where the second one references the entire return statement.

Did something change in the MVC Framework, so this code is outdated, or am I doing something wrong?

The code I ended up with is:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.ModelBinding;
using System.Web.Mvc;

namespace AetMuzickaOprema.App_Start
{
    public class DecimalModelBinder : System.Web.ModelBinding.DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext, System.Web.ModelBinding.ModelBindingContext bindingContext) //first error
        {
            var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

            return valueProviderResult == null ? base.BindModel(controllerContext, bindingContext) : Convert.ToDecimal(valueProviderResult.AttemptedValue); //second error

        }
    }
}

Model property in question:

[Required]
[Range(typeof(decimal), "0", "999999999")]
public decimal Price { get; set; }
3
  • 1
    Here it is explained how to do a custom model binder in an updated manner. learn.microsoft.com/en-us/aspnet/core/mvc/advanced/… . If you have problems, I'll build for you but try first. Commented Aug 20, 2017 at 19:45
  • Thanks, I'll try it and let you know :) I appreciate it Commented Aug 20, 2017 at 20:17
  • @PedroSouki I am looking at the article since you posted your comment, but am I too new to MVC to make use of it in my case. If you were willing to show me how to implement it so decimal values would accept both "1,25" and "1.25", I would be very grateful. Commented Aug 22, 2017 at 18:09

2 Answers 2

1

It seems ultimately what you are trying to achieve is property-level binding such as this?:

[PropertyBinder(typeof(PropertyBBinder))]
public IList<int> PropertyB {get; set;}

If that is correct, this post offers a solution: Custom model binder for a property

Thanks.

Sign up to request clarification or add additional context in comments.

1 Comment

Actually, it's a single decimal property which I will include in the question. I don't know if this applies non the less. Thanks for your answer in any case :)
1

In ASP.NET Core 1.1 (Microsoft.AspNetCore.Mvc.Core.Abstraction, 1.0.1.0) you'll see the following interface

using System.Threading.Tasks;

namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
    //
    // Summary:
    //     Defines an interface for model binders.
    public interface IModelBinder
    {
        //
        // Summary:
        //     Attempts to bind a model.
        //
        // Parameters:
        //   bindingContext:
        //     The Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext.
        //
        // Returns:
        //     A System.Threading.Tasks.Task which will complete when the model binding process
        //     completes.
        //     If model binding was successful, the Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext.Result
        //     should have Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult.IsModelSet
        //     set to true.
        //     A model binder that completes successfully should set Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext.Result
        //     to a value returned from Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult.Success(System.Object).
        Task BindModelAsync(ModelBindingContext bindingContext);
    }
}

Model binders are defined in Microsoft.AspNetCore.Mvc.ModelBinding.Binders namespace, assembly Microsoft.AspNetCore.Mvc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60. None of them seem to expose BindModel() method, even less a virtual one. It looks like you are trying to override a non-existing method.

A better approach is to take an existing ModelBinder, one that best suits your needs, inherit from it, and override ModelBindAsync().

2 Comments

Thank you for your response. Could I bother you a bit further by asking where do I find existing ModelBinders in my project?
"Model binders are defined in Microsoft.AspNetCore.Mvc.ModelBinding.Binders namespace, assembly Microsoft.AspNetCore.Mvc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60". Strictly speaking, this means that there are no MBs in your project.But you can define one and put it wherever you need, say, in Helpers folder or something like this. Just inherit from DefaultModelBinder and override BindModelAsync. Or simply, rename ModelBind to ModelBindAsync taking signature into account.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.