How to Handle Model Binding After Using DisplayFormat Attribute












0















I am working on financial software which uses a lot of currency values and percentages. Without putting any thought into usability, if you create a default TextBox and bind it to a decimal 0.00M, it appears to the user as 0.00. It is ambiguous whether they should enter 6% as 6.00 or 0.06. You also run into the problem where .065 displays as 0.06, which makes the value appear incorrect to the user.



To clarify the intent of the numbers, I am using display attributes like this:



[Display(Name = "State Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal StateRate { get; set; }

[Display(Name = "Combined Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CombinedRate { get; set; }

[Display(Name = "County Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CountyRate { get; set; }


Now 6.5% is displayed as 6.50%, which is better from a usability standpoint, but when you post the form to an ASP.Net Core MVC controller, the values do not bind. Simply stripping the percentage sign causes it to bind at 650%. The approach I am taking is to use JQuery to clean up the data before the post takes place:



// deal with percentages:
// 6.5% does not bind, but is displayed to the user.
// 6.5 binds incorrectly (650%)
// .065 is desired format
$(function () {
$('#my-form').on('submit', function (e) {
e.preventDefault(); // avoid default post routine

// change "6.50%" to 6.5
var stateRate = parseFloat($('#StateRate').val().replace('%', ''));
var combinedRate = parseFloat($('#EstCombinedRate').val().replace('%', ''));
var countyRate = parseFloat($('#EstCountyRate').val().replace('%', ''));

// change 6.5 to .065 - leave 0.065 alone.
if (stateRate > 1) {
stateRate = stateRate / 100.0;
}
if (combinedRate > 1) {
combinedRate = combinedRate / 100.0;
}
if (countyRate > 1) {
countyRate = countyRate / 100.0;
}

// put the cleaned up values back into the form fields
$('#StateRate').val(stateRate);
$('#CombinedRate').val(combinedRate);
$('#CountyRate').val(countyRate);

// make ajax request
$.post(
'/MyController/EditTaxRates'
$(this).serialize(),
function (data, status, jqXHR) {
$.notify('Data saved successfully!', { position: "top center" });
}
).fail(function () {
$.notify('Error saving data.', { position: "top center" });
});
});
});


This is working properly for the most part, but I need to implement this a lot of places, and this adds a lot of code to solve a seemingly fundamental and simple issue. Also, it fails for a county tax rate such as 0.5%, which binds as 50% when using this code as written. Are there are any built-in tricks such as attributes or Razor magic that will cause the data to bind properly without using javascript, or is there a best practice that addresses this problem?










share|improve this question

























  • You might want to look at mvc-numericinput as an option

    – user3559349
    Nov 20 '18 at 22:43











  • In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.

    – user3559349
    Nov 20 '18 at 22:46
















0















I am working on financial software which uses a lot of currency values and percentages. Without putting any thought into usability, if you create a default TextBox and bind it to a decimal 0.00M, it appears to the user as 0.00. It is ambiguous whether they should enter 6% as 6.00 or 0.06. You also run into the problem where .065 displays as 0.06, which makes the value appear incorrect to the user.



To clarify the intent of the numbers, I am using display attributes like this:



[Display(Name = "State Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal StateRate { get; set; }

[Display(Name = "Combined Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CombinedRate { get; set; }

[Display(Name = "County Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CountyRate { get; set; }


Now 6.5% is displayed as 6.50%, which is better from a usability standpoint, but when you post the form to an ASP.Net Core MVC controller, the values do not bind. Simply stripping the percentage sign causes it to bind at 650%. The approach I am taking is to use JQuery to clean up the data before the post takes place:



// deal with percentages:
// 6.5% does not bind, but is displayed to the user.
// 6.5 binds incorrectly (650%)
// .065 is desired format
$(function () {
$('#my-form').on('submit', function (e) {
e.preventDefault(); // avoid default post routine

// change "6.50%" to 6.5
var stateRate = parseFloat($('#StateRate').val().replace('%', ''));
var combinedRate = parseFloat($('#EstCombinedRate').val().replace('%', ''));
var countyRate = parseFloat($('#EstCountyRate').val().replace('%', ''));

// change 6.5 to .065 - leave 0.065 alone.
if (stateRate > 1) {
stateRate = stateRate / 100.0;
}
if (combinedRate > 1) {
combinedRate = combinedRate / 100.0;
}
if (countyRate > 1) {
countyRate = countyRate / 100.0;
}

// put the cleaned up values back into the form fields
$('#StateRate').val(stateRate);
$('#CombinedRate').val(combinedRate);
$('#CountyRate').val(countyRate);

// make ajax request
$.post(
'/MyController/EditTaxRates'
$(this).serialize(),
function (data, status, jqXHR) {
$.notify('Data saved successfully!', { position: "top center" });
}
).fail(function () {
$.notify('Error saving data.', { position: "top center" });
});
});
});


This is working properly for the most part, but I need to implement this a lot of places, and this adds a lot of code to solve a seemingly fundamental and simple issue. Also, it fails for a county tax rate such as 0.5%, which binds as 50% when using this code as written. Are there are any built-in tricks such as attributes or Razor magic that will cause the data to bind properly without using javascript, or is there a best practice that addresses this problem?










share|improve this question

























  • You might want to look at mvc-numericinput as an option

    – user3559349
    Nov 20 '18 at 22:43











  • In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.

    – user3559349
    Nov 20 '18 at 22:46














0












0








0








I am working on financial software which uses a lot of currency values and percentages. Without putting any thought into usability, if you create a default TextBox and bind it to a decimal 0.00M, it appears to the user as 0.00. It is ambiguous whether they should enter 6% as 6.00 or 0.06. You also run into the problem where .065 displays as 0.06, which makes the value appear incorrect to the user.



To clarify the intent of the numbers, I am using display attributes like this:



[Display(Name = "State Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal StateRate { get; set; }

[Display(Name = "Combined Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CombinedRate { get; set; }

[Display(Name = "County Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CountyRate { get; set; }


Now 6.5% is displayed as 6.50%, which is better from a usability standpoint, but when you post the form to an ASP.Net Core MVC controller, the values do not bind. Simply stripping the percentage sign causes it to bind at 650%. The approach I am taking is to use JQuery to clean up the data before the post takes place:



// deal with percentages:
// 6.5% does not bind, but is displayed to the user.
// 6.5 binds incorrectly (650%)
// .065 is desired format
$(function () {
$('#my-form').on('submit', function (e) {
e.preventDefault(); // avoid default post routine

// change "6.50%" to 6.5
var stateRate = parseFloat($('#StateRate').val().replace('%', ''));
var combinedRate = parseFloat($('#EstCombinedRate').val().replace('%', ''));
var countyRate = parseFloat($('#EstCountyRate').val().replace('%', ''));

// change 6.5 to .065 - leave 0.065 alone.
if (stateRate > 1) {
stateRate = stateRate / 100.0;
}
if (combinedRate > 1) {
combinedRate = combinedRate / 100.0;
}
if (countyRate > 1) {
countyRate = countyRate / 100.0;
}

// put the cleaned up values back into the form fields
$('#StateRate').val(stateRate);
$('#CombinedRate').val(combinedRate);
$('#CountyRate').val(countyRate);

// make ajax request
$.post(
'/MyController/EditTaxRates'
$(this).serialize(),
function (data, status, jqXHR) {
$.notify('Data saved successfully!', { position: "top center" });
}
).fail(function () {
$.notify('Error saving data.', { position: "top center" });
});
});
});


This is working properly for the most part, but I need to implement this a lot of places, and this adds a lot of code to solve a seemingly fundamental and simple issue. Also, it fails for a county tax rate such as 0.5%, which binds as 50% when using this code as written. Are there are any built-in tricks such as attributes or Razor magic that will cause the data to bind properly without using javascript, or is there a best practice that addresses this problem?










share|improve this question
















I am working on financial software which uses a lot of currency values and percentages. Without putting any thought into usability, if you create a default TextBox and bind it to a decimal 0.00M, it appears to the user as 0.00. It is ambiguous whether they should enter 6% as 6.00 or 0.06. You also run into the problem where .065 displays as 0.06, which makes the value appear incorrect to the user.



To clarify the intent of the numbers, I am using display attributes like this:



[Display(Name = "State Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal StateRate { get; set; }

[Display(Name = "Combined Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CombinedRate { get; set; }

[Display(Name = "County Tax Rate")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:P2}")]
public decimal CountyRate { get; set; }


Now 6.5% is displayed as 6.50%, which is better from a usability standpoint, but when you post the form to an ASP.Net Core MVC controller, the values do not bind. Simply stripping the percentage sign causes it to bind at 650%. The approach I am taking is to use JQuery to clean up the data before the post takes place:



// deal with percentages:
// 6.5% does not bind, but is displayed to the user.
// 6.5 binds incorrectly (650%)
// .065 is desired format
$(function () {
$('#my-form').on('submit', function (e) {
e.preventDefault(); // avoid default post routine

// change "6.50%" to 6.5
var stateRate = parseFloat($('#StateRate').val().replace('%', ''));
var combinedRate = parseFloat($('#EstCombinedRate').val().replace('%', ''));
var countyRate = parseFloat($('#EstCountyRate').val().replace('%', ''));

// change 6.5 to .065 - leave 0.065 alone.
if (stateRate > 1) {
stateRate = stateRate / 100.0;
}
if (combinedRate > 1) {
combinedRate = combinedRate / 100.0;
}
if (countyRate > 1) {
countyRate = countyRate / 100.0;
}

// put the cleaned up values back into the form fields
$('#StateRate').val(stateRate);
$('#CombinedRate').val(combinedRate);
$('#CountyRate').val(countyRate);

// make ajax request
$.post(
'/MyController/EditTaxRates'
$(this).serialize(),
function (data, status, jqXHR) {
$.notify('Data saved successfully!', { position: "top center" });
}
).fail(function () {
$.notify('Error saving data.', { position: "top center" });
});
});
});


This is working properly for the most part, but I need to implement this a lot of places, and this adds a lot of code to solve a seemingly fundamental and simple issue. Also, it fails for a county tax rate such as 0.5%, which binds as 50% when using this code as written. Are there are any built-in tricks such as attributes or Razor magic that will cause the data to bind properly without using javascript, or is there a best practice that addresses this problem?







jquery asp.net-core-mvc model-binding usability






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 '18 at 20:06







Elemental Pete

















asked Nov 20 '18 at 19:49









Elemental PeteElemental Pete

2,2341723




2,2341723













  • You might want to look at mvc-numericinput as an option

    – user3559349
    Nov 20 '18 at 22:43











  • In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.

    – user3559349
    Nov 20 '18 at 22:46



















  • You might want to look at mvc-numericinput as an option

    – user3559349
    Nov 20 '18 at 22:43











  • In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.

    – user3559349
    Nov 20 '18 at 22:46

















You might want to look at mvc-numericinput as an option

– user3559349
Nov 20 '18 at 22:43





You might want to look at mvc-numericinput as an option

– user3559349
Nov 20 '18 at 22:43













In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.

– user3559349
Nov 20 '18 at 22:46





In addition, a [Range] attribute can be use to limit values between 0 and 1 for percentages.

– user3559349
Nov 20 '18 at 22:46












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53400530%2fhow-to-handle-model-binding-after-using-displayformat-attribute%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53400530%2fhow-to-handle-model-binding-after-using-displayformat-attribute%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

A Topological Invariant for $pi_3(U(n))$