How to round decimal values using Math.Round but keep trailing zeros - asp.net-mvc-3

In my application certain fields contain decimal numbers. And it is possible to enter only 2 decimal points. After doing some calculations, the result is displayed, and the answer should also contain 2 decimal points. For that I used the code below:-
obj.Revenue = 0.00m;
obj.Revenue = Math.Round(Convert.ToDecimal(obj.Revenue), 2);
[EDIT]
Inside view:-
#Html.TextBoxFor(model => model.Revenue, new { #id = "txtRevenue", #readonly = "readonly", #class = "decimalField" })
So that 300.00 should be displayed as answer. But I got 300. How can I solve this?

Use toFixed(n);
var d = 300.00;
alert(d.toFixed(2));

Use toFixed() function
For example:
(12.5).toFixed(2); // 12.50

Try this:
#Html.TextBoxFor(model => model.Revenue, new {value = Model.Revenue.ToString("#.##"), #id = "txtRevenue", #readonly = "readonly", #class = "decimalField" })

You need to implement get accessor for the model.Revenue property this way:
get{ return _revenue.ToString("#.##"); }

I know its too late to answer this question but it may help other.
You can simply write this line in your model where you have declared the property. [DisplayFormat(DataFormatString = "{0:0.###}")]
here is the practical example which i used in my code.
[DisplayFormat(DataFormatString = "{0:0.##}")]
public Decimal CreditLimit { get; set; }
this will set your value up to two decimal.
e.g.
3.3333333 => 3.33

Related

What is the correct way to define models and their validation?

I want to create a supplier model i.e code, name, address, phone
I am also going to use the aurelia-validation classes.
Using them both together with the viewmodel - SupplierMaint.js & view - SupplierMaint.html is fine but I want to keep the Supplier model in another file so that I can use it in many places to ensure a consistent validation of values lengths etc.
How should I go about this?
I suspect the #NoView annotation might have something to do with it but I am not sure how to import the external file and wire it up to the submit & validation processing in the SupplierMaint.js
Bob
Models
This is how I do it -
export class Supplier {
name = '';
modelId = '';
constructor(data) {
Object.assign(this, data);
}
}
This let's anyone consume your model and create a new instance of it. The data that is passed in will override the default values you define, but if they do not you still have those default values.
Validation
Validation is currently in a state of flux. I'm hoping to be done with the initial refactoring work by the end of this weekend but here is a preview for what I propose as the best usage, feedback welcome.
import {ValidationReporter} from 'aurelia-validate';
export class PersonViewModel {
activePerson;
static inject = [ValidationReporter];
constructor(reporter) {
this.activePerson = new PersonModel({firstName: 'Lucky Luke'});
this.reporter = reporter.subscribe(validationErrors => {
// do something with validationErrors
});
}
}
class PersonModel {
#length({ minimum: 5, maximum: 25 }) firstName = 'Luke';
#required lastName = 'Skywalker';
#date lastUpdated = new Date();
#datetime lastTimeUpdated = new Date();
#email email = 'luke#skywalker.net';
#length({ minimum: 5, maximum: 25 }) password = 'equal';
#equality confirmPassword = 'equal';
#url website = 'http://www.google.com';
#numericality friendCount = 25;
#numericality({ noStrings: true }) age = 25;
constructor(data) {
Object.assign(this, data);
}
}

How to get DropDownList text from selected value via Linq

I am quite new to MVC3, and developing a DropDownListFor which i need to get both value and text for display result purpose. Any ideas on this issue? Thanks!
In my controller:
ViewBag.vehicleSizes = totalGreenCalculator.GreenCalculator.getVehicleFuelEfficiency();
In my Model:
//Datatype: fuelEfficiency = double, vehicleSizes = string
public IEnumerable<SelectListItem> getVehicleFuelEfficiency()
{
var size = new[] {new vehicleSize {fuelEfficiency = 0.0, vehicleSizes = "Choose your vehicle size"},
//and so on
};
return size.Select(a => new SelectListItem() { Text = a.vehicleSizes, Value = a.fuelEfficiency.ToString() });
}
View:
#Html.DropDownListFor(model => model.GreenCalculator.vehicleList[i].fuelEfficiency, (IEnumerable<SelectListItem>)ViewBag.vehicleSizes)
You can recieve IDictionary on controller. Dropdownlist name must match the name of the dictionary.
Your code looks fine. It will generate the dropdownlist from the given values. But it won't preselect the default option. That's because in the first argument you have used a complex expression. If you wanted to preselect some item you could do this:
#Html.DropDownListFor(
x => x.GreenCalculator.vehicleList[i].fuelEfficiency,
new SelectList(
(IEnumerable<SelectListItem>)ViewBag.vehicleSizes,
"Value",
"Text",
Model.GreenCalculator.vehicleList[i].fuelEfficiency
)
)

MvcContrib Grid Sorting on complex object

I am trying to work with MvcContrib Grid control. But I cannot seem to get the sorting to work on complex objects that hold other objects.
I have setup my controller/classes/Views similar to the OP in this question.
Sorting with MVCContrib
I have tried to use the SortColumnName to my childobject.property but it gives me an error saying My main object does not have this property. This is my code snippet
//POCO class
class Issue {
public int ID {get; get; }
.....
public int priorityId {get; set;}
public virtual Priority priority {get; set;}
}
//Controller code
public ViewResult Index(int? pageNo, GridSortOptions sort)
{
var issues = db.issues.Include(i => i.priority);
ViewBag.sort = sort;
if (!string.IsNullOrEmpty(sort.Column))
{
issues = issues.OrderBy(sort.Column, sort.Direction);
}
return View(issues.ToList().AsPagination(pageNo ?? 1, 10));
}
//View code for the Grid
#Html.Grid(Model).Sort(ViewBag.sort as GridSortOptions).Columns(column => {
column.For(issue => Html.ActionLink(" ", "Edit", new { id = issue.ID, areas = "Issues", controller = "Main"}, new { #id="editBtn"})).Named("Edit");
column.For(issue => Html.ActionLink(issue.ID.ToString(), "Edit", new {id = issue.ID, areas = "Issues", controller = "Main"})).Named("ID").Sortable(true);
column.For(issue => issue.priority.codeDesc).Named("Priority").SortColumnName("priority.codeDesc").Sortable(true);
}).Empty("No data found")
When I try to sort on the priority string, it gives me an error saying 'priority.codeDesc is not a property of Issue'.
TIA
The issue here isn't actually related to the grid, but rather to the .OrderBy extension method provided as part of the MvcContrib sorting extensions. This extension is fairly simplistic and I only wrote it to cover simple cases where you want to sort on a direct property of the object, however in your case you're trying to order on a nested property ("priority.codeDesc") which isn't supported - you can't use dot notation with this extension.
You'd either need to switch to using a different mechanism to perform the actual sorting, or if this is a one-off situation then you could hard-code the sorting logic for this particular column (not ideal, but if it's a one off then it's simpler than writing a new sorting mechanism), eg:
if (!string.IsNullOrEmpty(sort.Column))
{
if(sort.Column == "priority.codeDesc")
{
issues = issues.OrderBy(x => x.priority.codeDesc);
}
else
{
issues = issues.OrderBy(sort.Column, sort.Direction);
}
}
OMG! Dots!
I was in the same boat but thanks God I found a brilliant solution posted by our fellow developer Jarrett Meyer. I found it after maybe 3 hours Googling in the past and just now when I decided to boost my pagination and sorting with MvcContrib Grid.
You can find the full post here:
Server-Side Sorting With Dynamic LINQ
His code saved me... :D The use of LINQ's Aggregate function was AWESOME! Kudozzz to him.
I had to change Jarretts' original code a little bit to fit it to my needs. Here's the code after I modified it:
public static IQueryable<T> OrderBy<T>(this IQueryable<T> collection, GridSortOptions sortOptions)
{
if (string.IsNullOrEmpty(sortOptions.Column))
{
return collection;
}
Type collectionType = typeof(T);
ParameterExpression parameterExpression = Expression.Parameter(collectionType, "p");
Expression seedExpression = parameterExpression;
Expression aggregateExpression = sortOptions.Column.Split('.').Aggregate(seedExpression, Expression.Property);
MemberExpression memberExpression = aggregateExpression as MemberExpression;
if (memberExpression == null)
{
throw new NullReferenceException(string.Format("Unable to cast Member Expression for given path: {0}.", sortOptions.Column));
}
LambdaExpression orderByExp = Expression.Lambda(memberExpression, parameterExpression);
const string orderBy = "OrderBy";
const string orderByDesc = "OrderByDescending";
Type childPropertyType = ((PropertyInfo)(memberExpression.Member)).PropertyType;
string methodToInvoke = sortOptions.Direction == MvcContrib.Sorting.SortDirection.Ascending ? orderBy : orderByDesc;
var orderByCall = Expression.Call(typeof(Queryable), methodToInvoke, new[] { collectionType, childPropertyType }, collection.Expression, Expression.Quote(orderByExp));
return collection.Provider.CreateQuery<T>(orderByCall);
}
Now you can call this extension method like this in your controller method:
var users = Database.Memberships.OrderBy(sort);
where sort is GridSortOptions that lives in MvcContrib.UI.Grid.
sort.ColumnName can contain strings like these ones now:
User.UserName
User.MyRelatedEntity.RelatedEntityProperty
User.MyRelatedEntity.RelatedEntityProperty.AndSoON
Note that when you create your Grid columns you can specify
.SortColumnName("User.UserName")

How can I create an Expression within another Expression?

Forgive me if this has been asked already. I've only just started using LINQ. I have the following Expression:
public static Expression<Func<TblCustomer, CustomerSummary>> SelectToSummary()
{
return m => (new CustomerSummary()
{
ID = m.ID,
CustomerName = m.CustomerName,
LastSalesContact = // This is a Person entity, no idea how to create it
});
}
I want to be able to populate LastSalesContact, which is a Person entity.
The details that I wish to populate come from m.LatestPerson, so how can I map over the fields from m.LatestPerson to LastSalesContact. I want the mapping to be re-useable, i.e. I do not want to do this:
LastSalesContact = new Person()
{
// Etc
}
Can I use a static Expression, such as this:
public static Expression<Func<TblUser, User>> SelectToUser()
{
return x => (new User()
{
// Populate
});
}
UPDATE:
This is what I need to do:
return m => (new CustomerSummary()
{
ID = m.ID,
CustomerName = m.CustomerName,
LastSalesContact = new Person()
{
PersonId = m.LatestPerson.PersonId,
PersonName = m.LatestPerson.PersonName,
Company = new Company()
{
CompanyId = m.LatestPerson.Company.CompanyId,
etc
}
}
});
But I will be re-using the Person() creation in about 10-15 different classes, so I don't want exactly the same code duplicated X amount of times. I'd probably also want to do the same for Company.
Can't you just use automapper for that?
public static Expression<Func<TblCustomer, CustomerSummary>> SelectToSummary()
{
return m => Mapper.Map<TblCustomer, CustommerSummary>(m);
}
You'd have to do some bootstrapping, but then it's very reusable.
UPDATE:
I may not be getting something, but what it the purpose of this function? If you just want to map one or collection of Tbl object to other objects, why have the expression?
You could just have something like this:
var customers = _customerRepository.GetAll(); // returns IEnumerable<TblCustomer>
var summaries = Mapper.Map<IEnumerable<TblCustomer>, IEnumerable<CustomerSummary>>(customers);
Or is there something I missed?
I don't think you'll be able to use a lambda expression to do this... you'll need to build up the expression tree by hand using the factory methods in Expression. It's unlikely to be pleasant, to be honest.
My generally preferred way of working out how to build up expression trees is to start with a simple example of what you want to do written as a lambda expression, and then decompile it. That should show you how the expression tree is built - although the C# compiler gets to use the metadata associated with properties more easily than we can (we have to use Type.GetProperty).
This is always assuming I've understood you correctly... it's quite possible that I haven't.
How about this:
public static Person CreatePerson(TblPerson data)
{
// ...
}
public static Expression<Func<TblPerson, Person>> CreatePersonExpression()
{
return d => CreatePerson(d);
}
return m => (new CustomerSummary()
{
ID = m.ID,
CustomerName = m.CustomerName,
LastSalesContact = CreatePerson(m.LatestPerson)
});

Object initialization syntax

I'm just starting out with F# and I can't find the syntax to do object initialization like in C# 3.
I.e. given this:
public class Person {
public DateTime BirthDate { get; set; }
public string Name { get; set; }
}
how do I write the following in F#:
var p = new Person { Name = "John", BirthDate = DateTime.Now };
You can do it like this:
let p = new Person (Name = "John", BirthDate = DateTime.Now)
the answer from CMS is definitely correct. Here is just one addition that may be also helpful. In F#, you often want to write the type just using immutable properties. When using the "object initializer" syntax, the properties have to be mutable. An alternative in F# is to use named arguments, which gives you a similar syntax, but keeps things immutable:
type Person(name:string, ?birthDate) =
member x.Name = name
member x.BirthDate = defaultArg birthDate System.DateTime.MinValue
Now we can write:
let p1 = new Person(name="John", birthDate=DateTime.Now)
let p2 = new Person(name="John")
The code requires you to specify the name, but birthday is an optional argument with some default value.
You can also omit the new keyword and use less verbose syntax:
let p = Person(BirthDate = DateTime.Now, Name = "John")
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/members/constructors

Resources