tag:blogger.com,1999:blog-53864360846009838222024-03-21T15:56:37.917-07:00Development PassionThings i have experienced (C#, asp.net, linq,mvc 4, jquery and much more)Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.comBlogger63125tag:blogger.com,1999:blog-5386436084600983822.post-65734174562405703632018-03-22T15:24:00.000-07:002018-03-25T02:50:07.118-07:00Implement Equality for Reference Types in C#<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="https://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=9711012" rel="tag" style="display: none;">CodeProject</a>
<br />
<h2>
Introduction</h2>
<div>
<div>
In the last post we discussed about why to implement equality for our value types in c# and we saw how it can help writing more efficient code when writing our own value types as the default implementation in <b>.NET framework</b> for value types uses reflection to check for equality of two value types on the basis of the values they contain so it is always a better option to override the equality behavior for our value types which of course will be a performance gain during execution. </div>
<h2 style="text-align: left;">
What we will learn ?</h2>
<div>
We didn't discussed about implementing equality for reference types so in this post we will be just focusing on overriding the equality behavior for reference types, as with references types there are other complications involved too which are needed to be addressed when implementing equality for reference types which includes inheritance as unlike value types we have inheritance feature available in case of reference types and another thing is handling nulls to as reference types can be null but is not the case for value types. </div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Another thing that we will see is what are the use cases where we should implement equality for reference types, we already saw the reasons why we need to do this in case of value types. </div>
<div>
<br /></div>
<div>
</div>
<div>
We will be overriding equality for a reference type to demonstrate the concepts the same way as we did in case of value types to have clear understanding of the concepts here. We will see what the necessary steps are to do when implementing equality for a reference type and another important thing we will learn is how to implement it when we have inheritance involved too in reference types. For example, class <b>A </b>implements equality for itself but in future a class <b>B </b>inherits from <b>A</b>, in the case how the class <b>B </b>would implement the equality for itself without breaking the equality behavior of class <b>A</b>. </div>
</div>
<div>
<br /></div>
<h2 style="text-align: left;">
Let's get Started</h2>
<div>
<div>
The way we implement equality for reference types is little different than what we do in case of value types. As we discussed above in case reference types we also have to deal with inheritance too, which we never need to handle in case of value types as they are by default marked as sealed in the .NET framework, so expecting the implementation of equality for reference types would be more complicated than of value types. </div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Now let's create a reference type for which we will implement equality in this post next. So let’s start creating the class for which we will implement equality in this post. </div>
<div>
</div>
<div>
<br /></div>
<div>
We will use the Car class as example as we want to understand it for Reference types. The following is the implementation of our Car class: </div>
</div>
<div>
<br />
<pre class="brush: csharp"> public class Car
{
public int MakeYear { get; private set; }
public Decimal Price { get; private set; }
public Car(int makeYear, Decimal price)
{
MakeYear = makeYear;
Price = price;
}
public override string ToString()
{
return $"Model: {MakeYear}, Price: {Price}";
}
}
</pre>
</div>
<div>
<br />
<br />
We know that classes are <b>Reference types</b> and because of that we the ability to use <b>Object Orientation principles</b> in it and one of the important part of which is <b>Inheritance </b>and we will be looking in to how two objects are checked for equality when inheritance is also in play and for that we will consider the <b>Car </b>type as base class and we will extend it with a subclass to understand the behavior how it behaves and how we can implement it.<br />
<br />
<br />
Now we will create a derived class which will have <b>overridden implementation</b> which will be of course different than the base class. Let’s say we create a class called <b>LeaseCar </b>which will have an extra property which will hold the information of Lease options that are available for the lease car and the object will hold the specific options chosen at time of object creation.<br />
<br />
<br />
Our <b>LeaseCar </b>class will look like following:<br />
<br /></div>
<div>
<pre class="brush: csharp"> public class LeaseCar : Car
{
public LeaseOptions Options { get; set; }
public LeaseCar(int makeYear, Decimal price, LeaseOptions options) : base(makeYear, price)
{
Options = options;
}
public override string ToString()
{
return $"{nameof(DownPayment)}: {DownPayment}, {nameof(InstallmentPlan)}: {InstallmentPlan.ToString()}, {nameof(MonthlyInstallment)}: {MonthlyInstallment}";
}
}
</pre>
</div>
<div>
<br />
Our <b>LeaseCar </b>contains one new property which will hold the options select for the car to be leased and we have provided overridden implementation for <b><i>ToString() </i></b>method too which will return the name of down payment information, Installment Plan and Monthly Installment for the car in comma separated form.<br />
<br />
<br />
And our LeaseOptions implementation looks like :<br />
<br /></div>
<div>
<pre class="brush: csharp"> public class LeaseOptions
{
public Decimal DownPayment { get; }
public InstallmentPlan InstallmentPlan { get; }
public Decimal MonthlyInstallment { get; }
public LeaseOptions(Decimal downPayment, InstallmentPlan installmentPlan, Decimal monthlyInstallment)
{
DownPayment = downPayment;
InstallmentPlan = InstallmentPlan;
MonthlyInstallment = monthlyInstallment;
}
}
</pre>
</div>
<div>
<br />
First, we will write some basic code to see what the default behavior for is comparing two reference types for equality when there is no implementation being provided specifically about how to compare two. Following is the code for our <b><i>Main</i></b> <b>Program</b>:<br />
<br /></div>
<div>
<pre class="brush: csharp"> static void Main(string[] args)
{
Car carA = new Car(2018, 100000);
Car carA2 = new Car(2018, 100000);
Car carB = new Car(2016, 2500000);
</pre>
<pre class="brush: csharp"> LeaseCar leasedCarA = new LeaseCar(2014, 2500000, new LeaseOptions(1000000,InstallmentPlan.FiveYears, 10000));
LeaseCar leasedCarA2 = new LeaseCar(2014, 2500000, new LeaseOptions(1000000, InstallmentPlan.FiveYears, 10000));
LeaseCar leasedCarB = new LeaseCar(2016, 2500000, new LeaseOptions(1000000, InstallmentPlan.FiveYears, 10000));
Console.WriteLine(carA == carA2);
Console.WriteLine(carA == carB);
Console.WriteLine(leasedCarA == leasedCarA);
Console.WriteLine(leasedCarB == carB);
Console.Read();
}
</pre>
</div>
<div>
<br />
We can see that there are five different objects created all of which are either of type Car or their type inherits from Car due to which we can actually say that all objects are of type Car and we are comparing all of those with each other one by one for equality and the output is not any surprise, it is what we were expecting, all other comparison operations returned false except <b><i>leaseCarA == leaseCarA </i></b>which is quite obvious as we are comparing the <b><i>leaseCarA </i></b>object reference with itself and we are clear here that it is comparing the references for equality not values in it as class is a reference type. Following is the output of the above program:
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhagGz0jTO7gniYKxQuamKmBe-nuXXtPLEIAHdeSnMqpJPzK1rIG6lrVqLQEjYKmomLNJRXMuU9xaFFwO5_wtBFBJzfAiu_m7zG723oVHvlwYRyLak16Pf6AevGU9EUm9cTvAeaJEloYSk5/s1600/ref+types+equality.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="270" data-original-width="403" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhagGz0jTO7gniYKxQuamKmBe-nuXXtPLEIAHdeSnMqpJPzK1rIG6lrVqLQEjYKmomLNJRXMuU9xaFFwO5_wtBFBJzfAiu_m7zG723oVHvlwYRyLak16Pf6AevGU9EUm9cTvAeaJEloYSk5/s1600/ref+types+equality.PNG" /></a></div>
<br />
We can also check using <b><i>Object.Equals()</i></b> method instead of <b>== operator</b> in the above example program but the output will remain same as both will check for the references of two objects are pointing to same memory location or not.<br />
<br />
One thing more to note is that we saw previously that for value types for <b>== operator</b> to get working for doing comparison we had to define overloads for <b>==</b> and<b> !=</b> in that value type but for reference types we don’t need to define those as it is a reference type and the base type <b><i>Object </i></b>already takes care of doing reference comparison for any reference type except <b><i>String </i></b>as it’s case is little different which we have seen in one of the past post.<br />
<br />
<h2 style="text-align: left;">
Motivation for Overriding Equality for Reference Types</h2>
</div>
<div>
<div>
The motivation to provide the overridden implementation for value types is now pretty clear to all of us i.e. the performance of the code as if we don’t provide own implementation for our value-types the framework will use reflection to compare the fields, properties of both objects for equality, but some of us might be having question in mind that Why do we need to implement for Reference types as well?<br />
<h3 style="text-align: left;">
Here's the answer</h3>
</div>
<div>
The answer to it is that there can be cases where we don’t want to just rely on the reference equality for two objects of a particular reference, we might want to consider two objects to be equal if let’s say two of the properties in the reference type are having same value in both objects, in these kind of situations we would need to implement equality for those reference types ourselves instead of depending on the default behavior of framework for reference types.</div>
<div>
<br /></div>
<div>
So, we can say it this way as well that when we want our objects to be checked for equality on the basis of values in it instead of the reference of the objects. In general, it is not commonly needed to implement equality for reference types than value types. </div>
</div>
<div>
<br /></div>
<h2 style="text-align: left;">
Possible Use Cases for Overriding Reference Equality</h2>
<div>
One example for this kind of case can be a class named <b>Marks </b>which holds the marks of each subject for a student and let’s say we frequently need to compare the marks of students with each other for any reason, in that case we can override the implementation for <b>Marks </b>class to compare the marks of each subject between two objects. Another case can be that we might have a class holding the location details as Latitude Longitude and we would want to check for equality on the basis of those values to be equal.<br />
<h3 style="text-align: left;">
Examples</h3>
</div>
<div>
Another good example can be of a Model class or any class which holds string properties and we want the equality check to be done by comparing the string values. Let’s take the following class as example:<br />
<br /></div>
<div>
<pre class="brush:csharp">public class User
{
public string FirstName {get;set;}
public string LastName {get;set;}
public string EmailAddress {get;set;}
}
</pre>
</div>
<div>
<br />
Let's write the following code in Main method:<br />
<br /></div>
<div>
<pre class="brush: csharp"> void Main()
{
User user1 = new User()
{
FirstName="ehsan",
LastName="sajjad",
EmailAddress="ehsansajjad@yahoo.com"
};
User user2 = new User()
{
FirstName="ehsan",
LastName="sajjad",
EmailAddress="ehsansajjad@yahoo.com"
};
Console.WriteLine(user1 == user2);
}
</pre>
</div>
<div>
<br />
we will see that these two objects are not considered equal though both are equal if we consider the values in the properties they are all exactly same and equal but as the User is a reference type so it is doing reference equality here not value.<br />
<br />
<h2 style="text-align: left;">
Expected Consequences of Overriding Equality</h2>
</div>
<div>
<div>
We should watch closely before implementing value equality in a reference type as most of the developers would be expecting the equality comparison to do reference equality check not value based, so there should be a good reason to override the default behavior of framework for reference types. </div>
<div>
<br /></div>
<div>
<br /></div>
<div>
The cases that we discussed above might also not be a good reason to override equality for reference types sometimes. If we are considering overriding equality for reference types we should first think about the usage of the class that we are writing and we use take into account that does overriding the equality for it will make it more easy for the consumers of it or not, the result can be either one depending on what is the actual purpose of the that reference type and how the consumer code would be utilizing it. </div>
</div>
<div>
<br /></div>
<h2 style="text-align: left;">
Alternative Approach for Overriding Reference Type Equality</h2>
<div>
<div>
.NET framework also provided another way to provide other developers the ability to compare the objects of your class using value equality to check if they contain the same values, so we can do that without overriding the equality for the reference type. </div>
<div>
<br /></div>
<div>
<br /></div>
<div>
We would need to write a <i><b>EqualityComparer</b> </i>class which would inherit from <b><i>IEqualityComparer<T> </i></b> and we would write the logic there to compare the reference type objects as value based. This actually allows developers to plug in for value equality check when needed otherwise the default behavior would be the reference equality check which is also default behavior in .NET framework for reference types. So, using this approach gives more flexibility when doing equality check, but one thing to note is that using this approach we would not be able to do value equality check using <b>== operator</b> and we will need to call the <b><i>Equals</i> method</b> on the instance of equality comparer and passing both objects as parameter in for comparing them. </div>
</div>
<div>
<br /></div>
<h2 style="text-align: left;">
Overriding Equals() in Base Class</h2>
<div>
<div>
So Now we will first define the equality behavior for our base class Car in which the first thing that will include is overriding the Object.Equals method so that it would compare two car objects using the values of its properties. </div>
<div>
<br /></div>
<div>
<br /></div>
<div>
The following will be the code for our base class Employee as overridden implementation of Equals method of Object. </div>
</div>
<div>
<br /></div>
<div>
<pre class="brush:csharp"> public override bool Equals(object obj)
{
if (obj == null)
return false;
if (ReferenceEquals(obj, this))
return true;
if (obj.GetType() != this.GetType())
return false;
Car carToCheck = obj as Car;
return this.MakeYear == carToCheck.MakeYear
&& this.Price == carToCheck.Price;
} <span style="font-family: "times new roman";"><span style="white-space: normal;">
</span></span></pre>
</div>
<div>
<br />
The code is pretty simple, first of all it makes sure the passed in parameter is not null and if it's null we simply tell the caller that both objects are not equal and we would be comparing it with the object which actually called this instance method so it's obvious that this wouldn't be <b><i>null</i></b>.<br />
<br />
Then we check if using <b><i>ReferenceEquals()</i></b> method that if both instances are reference to same object which means we are comparing the object to itself and that obviously get us to the result that both objects are equal of course, so we return true in that case. This check is useful in giving little performance benefit as eventually our latter check will also evaluate true so it's good if we get the result early within the method call and save ourselves from comparing multiple properties values of our type.<br />
<br />
Another thing that we need to make sure before performing the values equality is that that type of passed in parameter object is same that of the this and that's what we are trying if they both have different type that simply means that they are not same object so we just return false as instances of two reference types wouldn't be equal normally.<br />
<br />
<br />
Lastly, we have code which would check that if both objects have same values for the properties that we are checking then we can say that both objects are same and we return true as result.<br />
<br />
<br />
<br />
We also need to provide the implementation of <b><i>GetHashCode()</i></b> method so that it aligns with our implementation of <b><i>Equals() </i></b>method, it would be quite same the way we did for value types before, here is the code for it:<br />
<br /></div>
<div>
<pre class="brush: csharp"> public override int GetHashCode()
{
return this.MakeYear.GetHashCode() ^ this.Price.GetHashCode();
}
</pre>
</div>
<div>
<br />
<br />
We are just getting the values of the three properties and doing <b>XOR </b>of them. We will not go in to the details in this post about why we do this and other details, we will see details about this in some later post.<br />
<br />
<br />
<br />
We have discussed this in one of previous posts too about what are the essential steps to do when overriding equality for a type, so here we have implemented two method, we also need to <b>overload </b>the <b><i>== operator</i></b> and <b><i>!= operator</i></b> methods, as if we don't it would result in inconsistent and contradictory results for devs using this type. So, let’s write the overloads:<br />
<br /></div>
<div>
<pre class="brush:csharp"> public static bool operator ==(Car carA, Car carB)
{
return Object.Equals(carA, carB);
}
public static bool operator !=(Car carA, Car carB)
{
return !Object.Equals(carA, carB);
}
</pre>
</div>
<div>
<br />
We are just calling <b><i>static Equals()</i></b> method which will first check both the parameters to make sure that either of them is not null and then eventually will call the <b><i>virtual Equals</i></b> method of <b><i>Object </i></b>class and in return the <b>overridden </b>implementation of our type will get called which is what we want here and for <b><i>!= operator</i></b> we are just inverting the result of <b><i>Object.Equals()</i></b> method.<br />
<br />
So, we are almost done with all the things needed to be implemented when overriding equality for a Reference type.<br />
<br />
<h2 style="text-align: left;">
Overriding Derived Class Equality</h2>
<div>
Now, we will implement the equality in <b><i>LeaseCar </i></b>class which inherits from <b><i>Car </i></b>class. First of all like we did for Parent class we will provide the <b><i>Equals() </i></b>method override and here is the implementation for it:<br />
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp"> public override bool Equals(object obj)
{
if (!base.Equals(obj))
return false;
LeaseCar objectToCompare = (LeaseCar)obj;
return this.Options == objectToCompare.Options;
}
</pre>
</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
For the derived type we need to do it differently than for the base reference type. In Base we were checking equality of all the properties that we consider to be checked when comparing two objects of Car so here we will be reusing the base class method to do initial checking. So first we call the Equals implementation of Base and see what it returns. If the base implementation call results shows that both instances are not equal, we do not proceed for further derived class properties checking, as the base class already told us that the two objects are not same so, they are different it means.<br />
<br />
But if the base class implementation tells that that both objects are equal then we proceed further for derived class checks to be executed for which the code starts from Line 5 in the above method and what base class Equals is doing is we already saw that above that it makes sure both instances are of same type and have same values in them and then we check the derived class properties for value equality to decide if the objects are equal or not.<br />
<br />
<br />
But if we look at the property <b><i>Options </i></b>here it is also a reference type and object of type <b><i>LeaseOptions </i></b>class. So, we will need implement the Equality for that as well so that we can use it in the <b><i>LeaseCar </i></b>in a better manner. The following is the implementation for <b><i>LeaseOptions</i></b>:<br />
<br />
<br /></div>
<div>
<pre class="brush: csharp"> public class LeaseOptions
{
public Decimal DownPayment { get; }
public InstallmentPlan InstallmentPlan { get;}
public Decimal MonthlyInstallment { get; }
public LeaseOptions(Decimal downPayment,InstallmentPlan installmentPlan,Decimal monthlyInstallment)
{
DownPayment = downPayment;
InstallmentPlan = InstallmentPlan;
MonthlyInstallment = monthlyInstallment;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (ReferenceEquals(obj, this))
return true;
if (obj.GetType() != this.GetType())
return false;
LeaseOptions optionsToCheck = obj as LeaseOptions;
return this.DownPayment == optionsToCheck.DownPayment
&& this.InstallmentPlan == optionsToCheck.InstallmentPlan
&& this.MonthlyInstallment == optionsToCheck.MonthlyInstallment;
}
public override int GetHashCode()
{
return this.DownPayment.GetHashCode()
^ this.InstallmentPlan.GetHashCode()
^ this.MonthlyInstallment.GetHashCode();
}
public static bool operator ==(LeaseOptions optionsA, LeaseOptions optionsB)
{
return Object.Equals(optionsA, optionsB);
}
public static bool operator !=(LeaseOptions optionsA, LeaseOptions optionsB)
{
return !Object.Equals(optionsA, optionsB);
}
public override string ToString()
{
return $"{nameof(DownPayment)}: {DownPayment}, {nameof(InstallmentPlan)}: {InstallmentPlan.ToString()}, {nameof(MonthlyInstallment)}: {MonthlyInstallment}";
}
}
</pre>
</div>
<div>
<br />
<br />
So, now when we will call equality check for <b><i>LeaseOptions </i></b>it will be checked using the implementation provided and we will be reusing it in the other overloads that we need to write for Derived class and also would be used in <b><i>GetHashCode() </i></b>implementation of <b><i>LeaseCar</i></b>.<br />
<br />
<br />
<br />
We don't need to take care of null handling as we first call the base.Equals and in the implementation of that we are already taking care of nulls. Now, let’s implement the <b><i>GetHashCode() </i></b>method for <b><i>LeaseCar</i></b>:<br />
<br /></div>
<div>
<pre class="brush: csharp"> public override int GetHashCode()
{
return base.GetHashCode() ^ this.Options.GetHashCode();
}
</pre>
</div>
<div>
<br />
<br />
So, what we are doing here is calling the base implementation to get the hash code of it and then <b>XOR </b>it with the field Options of <b>LeaseCar </b>and as we have also provided the implementation for LeaseOptions class too to generated the <b><i>GetHashCode() </i></b>the same way using all the fields that we want.<br />
<br />
<br />
<br />
Now we also need to provide the <b>==</b> and <b>!= operator overloads</b> as well which would be similar to what we did in base class to call the static object.Equals method which will eventually call the overridden implementation of <b><i>LeaseCar </i></b>via call to virtual Equals method of Object class.<br />
<br />
The methods implemented would be like:</div>
<div>
<pre class="brush: csharp"> public static bool operator ==(LeaseCar carA, LeaseCar carB)
{
return object.Equals(carA, carB);
}
public static bool operator !=(LeaseCar carA, LeaseCar carB)
{
return object.Equals(carA, carB);
}
</pre>
</div>
<div>
<br />
If we notice our above overloads are having same implementation what we have in the base class, so if we want to skip implementing these two we can and the result would be same what we will get using these. But for the sake of giving the whole implementation for derived class too we are adding it for this post.<br />
<br />
<br />
<br />
Now as we are done with the implementation of both of our classes. Let's write some code to test for the correctness of our equality implementations. Following is the code to add in the <b>Main method</b>:<br />
<br />
<br /></div>
<div>
<pre class="brush:csharp"> class Program
{
static void Main(string[] args)
{
Car carA = new Car(2018, 100000);
Car carA2 = new Car(2018, 100000);
Car carB = new Car(2016, 2500000);
LeaseCar leasedCarA = new LeaseCar(2014, 2500000, new LeaseOptions(1000000,InstallmentPlan.FiveYears, 10000));
LeaseCar leasedCarA2 = new LeaseCar(2014, 2500000, new LeaseOptions(1000000, InstallmentPlan.FiveYears, 10000));
LeaseCar leasedCarB = new LeaseCar(2016, 2500000, new LeaseOptions(1000000, InstallmentPlan.FiveYears, 10000));
Console.WriteLine(carA == carA2);
Console.WriteLine(carA == carB);
Console.WriteLine(leasedCarA == leasedCarA);
Console.WriteLine(leasedCarB == carB);
}
}
</pre>
</div>
<div>
<br />
Now we can observe form the console output that our objects are getting evaluated not on the basis of reference but using the values contained in the Field/Properties that we have dictated the type to use when comparing for equality.
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirGWVrEGGpCkyze6E_lh8oboLhj3IjAMbpDaKb4Df3nOigSASgFoUGCLYUQN5VvCu96dueRN_0h9JD1NiwdIUbeibKB5DVjvT-nG55nzOqB1rY5RSgIjxDfJ-U69FjHiK-bb1FDgmLGwg0/s1600/equality+ref+2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="294" data-original-width="489" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirGWVrEGGpCkyze6E_lh8oboLhj3IjAMbpDaKb4Df3nOigSASgFoUGCLYUQN5VvCu96dueRN_0h9JD1NiwdIUbeibKB5DVjvT-nG55nzOqB1rY5RSgIjxDfJ-U69FjHiK-bb1FDgmLGwg0/s1600/equality+ref+2.PNG" /></a></div>
<br />
<h2 style="text-align: left;">
Summary</h2>
</div>
</div>
<div style="text-align: left;">
In this post, we learned the following things: </div>
<div style="text-align: left;">
</div>
<ul style="text-align: left;">
<li>We saw that how we can implement equality behavior for reference types so that they can act as value-types when comparing two objects. </li>
<li>Due to inheritance feature that is supported in Reference Types it's more complex than Value Types to implement our Equality check behavior.</li>
<li>Another thing to remember is that it is not always a good idea to implement Equality for Reference types as by default they are compared using the object reference but in case of Value Types we should be implementing as that will give us performance hit as we will be able to eliminate the default behavior which uses reflection for custom Value Types. </li>
<li>For implementing equality following are the thing to be done: </li>
<ul>
<li>Override the <b><i>Equals() </i></b>method of Object class in the Reference Type </li>
<li>Override the <b><i>GetHashCode()</i> </b>method of Object class in the Reference Type</li>
<li>Implement overloads for == and != operator for the type </li>
</ul>
</ul>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-46505983261594532332017-11-27T14:45:00.000-08:002017-12-06T12:00:05.642-08:00First .NET Core Console Application using Command Prompt<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 20pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Introduction </span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In this post, we will create our very first console application in </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b>.NET Core</b></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, we will see how we can build .NET Core based applications without using any </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b>IDE</b></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> or </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b>Visual Studio</b></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. We will be using Command Line to create, build and run the application. If we don’t need all the fancy features that Visual Studio and Visual Studio Code offers, then we can build a .NET Core application with just a note pad, the only thing we would need is the </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b>.NET Core SDK </b></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">installed on the machine, and all other actions that we do with Visual Studio all can be invoked using the </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b>CLI </b></span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">which we will see how it can be done.</span></div>
<b id="docs-internal-guid-50c88132-ffa3-c518-0410-8fa9f92f3d34" style="font-weight: normal;"><br /></b>
<br />
<h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 20pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Checking .NET Core Installation</span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Before creating the .NET Core project, it is obvious thing that we should have .NET Core installed on our machine which can be checked by opening a Command Prompt Window or Powershell window and typing in it the </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 12pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">dotnet</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> command, if the .NET Core is not already installed on the machine we will get a error as it will not be able to recognize the command:</span><br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="316" src="https://lh3.googleusercontent.com/5Qz3yG5OzdVaBumyUYZwj5UoDSQ5RjYXdOIeOLRcR6cBk9djeXgQUgaUI0vLQAHzDxFFknDbYOIy5YRnlSJoE70YBZQ8qf-j6CIZLV263GT1FEu10B_VNECFU7cdwOHO2EfUWWsC" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span></div>
<h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 20pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Installing .NET Core SDK on Windows</span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">As .NET Core is all about cross platform, so the SDK is available for different platforms which includes Windows 32-bit and 64-bit, MacOS and Linux, if we go to the </span><a href="https://www.microsoft.com/net/download/core#/sdk" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">official download link</span></a><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> we can see multiple options available from which can choose as per our need or convenience.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The following is the list taken from official .NET Core download link :</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img alt=".NET Core List.PNG" height="337" src="https://lh3.googleusercontent.com/LjQ7E7_aQtIIQPFl8fWYvoRoyur6YipHHZg_5kZEnseX5uv61K79H3-lJ-OH2sxZC6jAsxbNdDcYDz4ALj5CCL2jjLRVnZ4GovsHVVY7sOJSVo7cWrY542xSUZ08NrWZekCnOhfI" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> We will be creating the application using Windows so let’s download the sdk installer executable for Windows, i downloaded the Installer of </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Windows (x64)</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> as on my machine i have 64-bit Windows installed.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img alt=".NET SDK x64.png" height="351" src="https://lh6.googleusercontent.com/TCSOaxxrgm_b0_Jonu6IfId5FwVB9W3dKqXBaCC_HgHhaPC0G-UpuX81PgQgi7h1S5-uSuusz8Kqa8-NbL-Kjm9S_Mt0iPV59_c9r4hP1IEl6BobmLNwjE5kbHtvaWvwyeyI8uqo" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">After downloading the installer, proceed to install the SDK :</span><br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="461" src="https://lh5.googleusercontent.com/I5ZRFVBmxp3asaw111eXObCxm2CQgi2nWa3yl6c7tOEQs2mjD0NkrevXOgRY1ogd6NqzWw1_HjD-FTMvE2XENSGsDFskJxWNzfx2DrdtVK8da_HQC4BPc_eiOWRNeATJpGQXKo1v" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="465" src="https://lh4.googleusercontent.com/JVe4-HXzdPCrzPtMoJuVAxltMjrEMIfeEpN-0QkUIm8V7UsKvUcr-tOy44WhQRExEJPKMDnUSgW_xTcIOaWyculWWBldzvyMtnPjufoTQY-OGG-Xag8wnzBYtPqQgu5q7KOCV_rB" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">This installer will install all the necessary components need to develop .NET Core application and running it which includes </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.NET Core</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">RunTime</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">SDK </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">and other things as well. The installation will take 2 - 3 minutes to do the installation, and if all the things go right in installation you will see the following window acknowledging the successful installation :</span><br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="465" src="https://lh6.googleusercontent.com/YmjyCTgrGuGtF-kJmU9EEAqx1WvN6lJ7DcQ4WSUbEc4dE2sH4qLrOZIzDiSTCZI27MwdJFMnefZL4-d0wej22c4puBJnBoAfo45lB13hEyN858Z3Hn55gndsPm9HLY85QrGB2yrw" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">As we were able to install the SDK successfully, now open the command prompt again and type </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">dontnet</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> command again, i am using powershell for this and executing the command gives you back some output that means .NET Core is being setup correctly:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="217" src="https://lh3.googleusercontent.com/4B7OpYr0DGDLZyGIEE5P45cy8yhrQ8qhfBA9_ceEYP40dNYZuI2bATJDxrkMwcgbrKJB7SHvnyh_8NlfWlwks_O7LNpKEzjunE-8TZLZ9tZZJKvDMpaw0EWg9S_vzzxEyuS6Q7VV" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.NET Core CLI provides different commands to create new project, build, clean and all other commands that we normally invoke using </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Visual Studio, </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">there is a complete list of commands documented on the </span><a href="https://docs.microsoft.com/en-us/dotnet/core/" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">official documentation page</span></a><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> and all the commands can be seen at </span><a href="https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">this link</span></a><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></div>
<h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 20pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Creating Console Application</span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now let’s create the simplest famous </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Hello World </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">console application using command prompt in .NET Core. If all the previous steps have been completed correctly, open the Command Prompt and create a new directory which will contain the source code for the application.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Write the following command on cmd to create the directory:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: center;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><i>mkdir First DotNetCoreApp</i></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="308" src="https://lh4.googleusercontent.com/nnYW_xV_wSvfjg-gD7E3cShLW2HGJbhUtDdWlvl0A-2UpmrOgZKEU37C4P8vOnXUw02zbD8kVZdX5D1nbC71GHRYuWeEV9DxFBBRILqiHm7Ftf936SwhmWc0rKsxXe7M4clm_NgK" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="488" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now open the directory using the following command:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: center;">
<span style="background-color: transparent; font-family: "arial"; font-size: 11pt; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b><i>cd First DotNetCoreApp</i></b></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="385" src="https://lh4.googleusercontent.com/zuSvAZIKERiG8pN59SSMEgwuJwOYD6eYL-s4-RF6RBlIymTYWJ8OGO33rxSCX44QOlA1nqjr1VMN90XfajIVpMMx5JmFKGeWAJq9AsKiEeWHZFh1AK9wryTL8XPDvCdJTPXXzfEA" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="478" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Fromt the above image we can verify that we have opened the correct directory.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 20pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Adding Project Template </span></h1>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.NET Core comes with it’s own CLI tools enables to create new project using commands in Command Prompt or Powershell without even opening up the IDE either Visual Studio or VS Code.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">We will type </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">dotnet new</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">on command line and press enter which will list down all the templates that can be created using this command.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">After running the command, we will see few things listed which includes the different flags which are available to do different things which are also available within Visual Studio but the support is added via Command Line too which is great.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="129" src="https://lh5.googleusercontent.com/3Y6uBMAHWXZNvNaMVj_gWrfTCFzoCjGeYW_UeqiNoZ9BlRZEbGVGIGEFn-wfCcbtCEdybCBgiFBEaC2PislFcVEt0LF5g8xBK9NMqxsPTkloIltqiABFOQu505K6mGu3Rp05liCY" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">If we go little down, we can see all the templates listed which are available via CLI tools:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="313" src="https://lh3.googleusercontent.com/ndqjxQbb_O7x6wk3UN66XTXdcrdCUZlpVi339EXz9QfBN4cy8CAT13dEuG1Szv58TZTHyPKkns_CXfQ9_UhofkmRHB3DZ_VdxdkfSuItza23C09-Oz7P-hdFoUxc5_VJRLv0PRk0" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now let’s run the command for creating a new Console Application, so write </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">dotnet new</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> and press enter key and this will create new Console Application project in our working directory:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="184" src="https://lh4.googleusercontent.com/b65MdxM474bqYJIdPbrImvxdZpton0mROeP5m8T-B3BoCd8I4XOjrYkHkA27bOO6r6pyblH68hgu2EwUkNt3GUnnDKva7TcGr6OAo2ezudyMiowDMea0YdF7njNnPP3SchLh591L" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="624" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Our project has been created successfully, but to double check and make sure the command worked fine, we can list the directory content and we should be able to see </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">csproj, Program.cs</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> and other files for the application.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="239" src="https://lh3.googleusercontent.com/zSB34l8HmgVX2rwAc-H2ZfoMXDjuZLPVxpIzM_RPZwiwQCO8kYSBCFHuYRnx-dbSeIjp68LTrX-FdUAHd8ZWTv34U4iR73hIK_Y5eqDmQYIVuxVPkUCa7ZLxjvp8ZQM7lnXXpVGp" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="543" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now let’s run the application by executing the </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">dotnet run</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> command in CMD:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><img height="68" src="https://lh6.googleusercontent.com/Yg4NW5rdkiKPfryoTX1uH1-SXdCWxONZ8OvzR_oxA1Id0nzGRfIRonp_y1pgLuhTZRL5orurXliHsXl_H_nXzBVtFV3dwk-I4NDvQRYD4ajTA3bZNH08RSSJvK5Kb_7LNomp6aI2" style="-webkit-transform: rotate(0.00rad); border: none; transform: rotate(0.00rad);" width="447" /></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">One thing to remember here is that if you are creating the project using .NET Core 1.0 SDK, then before the </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">dotnet run</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> command you would need to execute the </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">dotnet restore</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> command which will restore all the </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">NuGet </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">package dependencies of the project, but for .NET Core 2.0 we don’t need to execute this command as calling the </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">dotnet run</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> makes sure to restore the </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">NuGet</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> package dependencies before running the code.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In actual the </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">restore</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> command was called when we execute the command </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">dotnet new</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> and NuGet packages were restored that time, but it is also called on </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">run</span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> as well, which can be verified from </span><a href="https://github.com/dotnet/announcements/issues/23" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">this GitHub announcement </span></a><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></div>
<h1 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 20pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 20pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Resources</span></h1>
<ul style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<a href="https://docs.microsoft.com/en-us/dotnet/core/" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://docs.microsoft.com/en-us/dotnet/core/</span></a></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<a href="https://www.microsoft.com/net/download/windows#/sdk" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://www.microsoft.com/net/download/windows#/sdk</span></a></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<a href="https://docs.microsoft.com/en-us/dotnet/core/tools/?wt.mc_id=DXLEX_EDX_DEV275x&tabs=netcore2x#cli-commands" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://docs.microsoft.com/en-us/dotnet/core/tools/?wt.mc_id=DXLEX_EDX_DEV275x&tabs=netcore2x#cli-commands</span></a></div>
</li>
<li dir="ltr" style="background-color: transparent; color: black; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<a href="https://docs.microsoft.com/en-us/dotnet/core/get-started" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">https://docs.microsoft.com/en-us/dotnet/core/get-started</span></a></div>
</li>
</ul>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-37245739183514912082017-07-29T13:30:00.001-07:002017-08-02T07:07:32.061-07:00Implement Equality for Value Types in C#<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<h2 style="text-align: left;">
Introduction</h2>
<div style="text-align: left;">
This post is to focus on implementing Equality in Value Types <b>i.e.</b> overriding Equality behavior for our own implemented Value Types which is basically defining that how to decide two objects of a type are equal or not. </div>
<h2 style="text-align: left;">
Background</h2>
<div style="text-align: left;">
As we are now aware of the fact that the technique for checking equality for Value Types and Reference Types is different, so it would be better if we discuss both of them separately, that’s why we will be focusing on each of them in separate posts to have clear understanding on how we can override the Equality for both of these.</div>
<div style="text-align: left;">
<br />
This post will particularly focus on the Value Types and for Reference Types we will see in some future post.</div>
<div style="text-align: left;">
</div>
<h2 style="text-align: left;">
Why we need it?</h2>
<div style="text-align: left;">
The first question that might come in mind is <b>“Why we should override the Equality for Value Type”</b>, we will see with a simple example and it will help you understand that fact that overriding the Equality behavior for Value Types is always a good idea indeed. We will define a <i><b>struct </b></i>later down the road and will implement the Equality of it.</div>
<h2 style="text-align: left;">
Steps to Implement Equality for Value Type</h2>
<div style="text-align: left;">
For overriding the Equality for a Value Type, there are some necessary steps that should be performed which are mentioned below.</div>
<div style="text-align: left;">
<br />
We will need to:</div>
<ul style="text-align: left;">
<li><i><b>override </b></i>the virtual Equals method of Object</li>
<li>implement <i><b>IEquatable<T></b></i> interface and provide the implementation of <i><b>Equals() </b></i>method of it</li>
<li>provide the overloaded implementation for <b><span style="font-size: small;">==</span></b> and <b>!=</b> operator method</li>
<li><i><b>override </b></i>the <i><b>GetHashCode </b></i>method of <i><b>Object </b></i>class</li>
</ul>
<h2 style="text-align: left;">
Possible Reasons for implementing Equality</h2>
<div style="text-align: left;">
So before we start discussing how we can implement Equality for a Value Type, let’s think a little on what are the possible reasons that would make us think that we should define our own Equality behavior for a Value Type instead of using the default one that framework already provides.<br />
So why would you want to override it, the following are the main reasons for that:</div>
<ul style="text-align: left;">
<li>We want to be able use <b>== operator</b> for comparing the objects of our Value Type. If you remember we discussed previously that <b>== operator</b> does not work for value types and to make it work we need to do some implementation (i.e. overload <b>== operator</b>) in our particular Value Type</li>
<li>We have also seen previously that the framework provided implementation uses <b>Reflection </b>for checking the values of each field of that type which is obviously affect the <b>performance </b>as Reflection is <b>slow </b>which results in <b>poor performance</b> of code.</li>
<li>We also need sometimes different behavior for comparison of a particular type, though this is not usually required but can be needed in some cases, as the default behavior for Value Types considers two objects to be equal if all of their fields also have the same content which is absolutely fine most of the time.</li>
</ul>
<div style="text-align: left;">
<br />
It is recommended approach to implement Equality for your own defined Value Types that would be used further in your code base. Other developers using your defined Value Type would not get surprised or frustrated when trying to compare two objects of it by using <b>== operator</b> and came to know that they can’t do it.<br />
<br />
We can skip overriding the equality for those types that we know we will be using internally in the code base and won’t be exposed to complete code base for usage and we know what we wouldn’t be needing to compare the objects frequently, so implementing equality for those types is not that much needed and would be a waste of time as a result.</div>
<h2 style="text-align: left;">
Example</h2>
<div style="text-align: left;">
We will create an example <i><b>struct </b></i>named <i><b>Employee </b></i>to illustrate about implementing Equality for a Value Type. This is how our Employee <i><b>struct </b></i>looks like now:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp"> public struct Employee
{
public string Name { get; }
public Gender Gender { get; set; }
public Department Department { get; set; }
public Employee(string name, Gender gender, Department department)
{
Name = name;
Gender = gender;
Department = department;
}
public override string ToString()
{
return Name;
}
}
public enum Department
{
HumanRecource,
QualityAssurance,
SoftwareDevelopment,
ProjectManagement,
ITOperations
}
public enum Gender
{
Male,
Female
}
</pre>
</div>
<br />
We have a very simple Employee type as example which has a <i><b>String </b></i>property which will contain the name of employee and one enumeration property to hold the gender of employee and another enumeration for Department which will be used to track the Department of the employee. We will define our own implementation later to dictate that how to decide if two employee instances are equal or not.<br />
<br />
There are multiple things that we need to take care and implement in our Employee type for implementing Equality. The first thing that we need to do is override the <i><b>Object.Equals()</b></i> method so that instead of default implementation getting invoked which is obviously slow because of Reflection involved, by providing implementation for this method it will enhance the performance of the Type, so <b>overriding <i>Equals</i></b> method will eliminate the equality check using Reflection and will make it efficient and we will be able to see significant performance improvement.<br />
<br />
But wait, <i><b>Object.Equals()</b></i> method takes parameter of type <i><b>Object </b></i>which means that boxing will happen and we know it also hurts the performance of our code, as boxing and <i><b>unboxing </b></i>has its own cost involved, so here we would want to avoid that one as well some way.<br />
<br />
For avoiding both Reflection and boxing we will need to implement the <i><b>IEquatable<Employee></b></i> interface for our type Employee. Now we will have efficient implementation of <i><b>Equals() </b></i>method in comparison with the framework provided one and another plus point of doing this is that now we have a much better implementation which is also type safe.<br />
<br />
We will need to provide the overloaded implementation for <b>==</b> and <b>!=</b> operators as it is normally considered a good practice to do all of the following things when overriding Equality:<br />
<ul style="text-align: left;">
<li><i><b>Object.Equals</b></i> method overriding</li>
<li>Implementing <i><b>IEquatable<T></b></i> interface for that type</li>
<li>Implementing <b>== </b>and <b>!=</b> overloaded methods</li>
<li><i><b>Object.GetHashCode</b></i> method overriding</li>
</ul>
This is important to do because it will make sure that checking for equality for two objects of that type will give the same result, otherwise it can be confusing for the calling code who will be utilizing our type and can cause problems in future.<br />
<br />
<i><b>For Example,</b></i> if we just implement the overloads for == and != operator and we don’t provide the <i><b>override </b></i>for <i><b>Object.Equals</b></i> method then what will happen is that the result of Equals method can be different from the result of == operator which will be troublesome for the code that will be utilizing our types.<br />
<br />
There is also another method in <i><b>Object </b></i>class called <i><b>GetHashCode</b></i>, whenever we override the Object.Equals method for a type then another thing that must be done is overriding the <i><b>GetHashCode</b></i> method as well. <br />
<h2 style="text-align: left;">
Step1 - Implementing IEquatable<T> Interface</h2>
<div style="text-align: left;">
Now let’s jump in to the Visual Studio and let’s start implementing the <i><b>IEquatable<Employee> </b></i>interface for out Person type. We will need to inherit our <i><b>struct </b></i>from <i><b>IEquatable<Employee></b></i> and using the code refactoring feature of <b>Visual Studio</b>:</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8XbaOZuTICNH5ki9Jf9ppzbOzpxM2IRweCVBTP5SPGrO2QNmOx0Rr383VYNbdyDm0kRrUxHoF65PsULEjXcK5WjUOg6NkwzElwwR4NnXOIznz_4KN5T_x0ZfOCpymwmCuilSpD4KoY_19/s1600/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="484" data-original-width="914" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8XbaOZuTICNH5ki9Jf9ppzbOzpxM2IRweCVBTP5SPGrO2QNmOx0Rr383VYNbdyDm0kRrUxHoF65PsULEjXcK5WjUOg6NkwzElwwR4NnXOIznz_4KN5T_x0ZfOCpymwmCuilSpD4KoY_19/s1600/1.png" /></a></div>
<div style="text-align: left;">
It will add the <i><b>Equals </b></i>method without any implementation for the <i><b>IEquatable<Employee></b></i> which would look like:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp"> public bool Equals(Employee other)
{
throw new NotImplementedException();
}
</pre>
</div>
<br />
Now we just need to provide the logic which would be used to identify that the two objects of <i><b>Employee </b></i>are equal or not which for this particular example we will do by checking the name and department of the employee is same, or we can also add the <i><b>Gender </b></i>if we like as this is just for getting understanding how we can implement it so it doesn’t matter much.<br />
<br />
After implementing the <i><b>Equals </b></i>method, here is how the method now looks like:<br />
<br />
<br />
<pre class="brush: csharp"> public bool Equals(Employee other)
{
var IsEqual = this.Name == other.Name && this.Department == other.Department;
return IsEqual;
}
</pre>
<br />
<br />
So the two objects of <i><b>Employee </b></i>will be considered Equal if they both contain in <i><b>Name </b></i>field and <i><b>Department </b></i>field same value. Our one field is of type <i><b>String </b></i>which does the value equality for <b>== operator</b> and the other is <i><b>Enum </b></i>which is a primitive type in C# so we know that in case of primitive type also <b>== operator</b> checks for value Equality, so the both operations will check for value equality which is what we are trying to do here.<br />
<h2 style="text-align: left;">
Step 2 - Overriding Object.Equals Method</h2>
<div style="text-align: left;">
As we are done with the <i><b>IEquatable<Employee></b></i> part, let’s now <i><b>override </b></i>the <i><b>Equals </b></i>method so that it also returns the same result that we would get when checking for equality via <i><b>IEquatable<Employee></b></i>, the implementation for which would be:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp"> public override bool Equals(object obj)
{
var IsEqual = false;
if(obj is Employee)
{
IsEqual = Equals((Employee)obj);
}
return IsEqual;
}
</pre>
</div>
<br />
What we are doing here is that first we need to make sure that the object that is passed in as parameter is of type <i><b>Employee </b></i>which totally makes sense as <i><b>Object.Equals</b></i> is not type safe and it is possible to pass an object of type <i><b>Person </b></i>instead of <i><b>Employee </b></i>and the compiler will not give any compile time error but the code would fail at run-time in that case, but adding that if block would save us from breaking the code at run-time and the method will simply return <b>false </b>which is the correct result as object of type <i><b>Person </b></i>and <i><b>Employee </b></i>can never be equal.<br />
<br />
The thing to note here is that this <i><b>Object.Equals </b></i>override will be less efficient than <i><b>Equals </b></i>method implementation of <i><b>IEquatable<T></b></i> because the former one has cost of <i><b>Boxing </b></i>when it will get called and then we are <i><b>unboxing </b></i>it back to <i><b>Employee </b></i>which <i><b>IEquatable<Employee></b></i> implementation saves us from these.<br />
<br />
What we can do is try to always call using the <i><b>IEquatable<T></b></i> method, if we are concerned about performance and memory cost.<br />
<br />
<h2 style="text-align: left;">
Step 3 - Overloading == and != Operator</h2>
<div style="text-align: left;">
Now let’s also implement the <b>==</b> and <b>!= operator</b> for <i><b>Employee </b></i>which would make sure that checking for Equality using these will return consistent result what we were getting using <i><b>Object.Equals</b></i> or <i><b>IEquatable<Employee></b></i> Equals method. So let’s add the implementation for <b>== operator</b> first which is:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp"> public static bool operator ==(Employee employee,Employee otherEmployee)
{
var IsEqual = employee.Equals(otherEmployee);
return IsEqual;
}
</pre>
</div>
<br />
The method is pretty simple, it is also reusing the Equals method implementation that we did for <i><b>IEquatable<Employee></b></i>, if we build the code it would not build and will give error saying that it hasn’t found the implementation of <b>!= operator</b>, in C# if we overload <b>== operator</b> for a type it is mandatory to provide the implementation for inverse of it <b>i.e. != operator</b> implementation as well, otherwise we will get the following compile time error:<br />
<br />
<h3 style="text-align: center;">
<b><span style="color: red;">Error CS0216: The operator 'Employee.operator ==(Employee, Employee)' requires a matching operator '!=' to also be defined</span></b></h3>
<div style="text-align: left;">
<b><span style="color: red;"> </span></b>If we have overloaded any one of the operator either == or != we would need to implement the other one as well, so let’s implement the other one as well:</div>
<div style="text-align: left;">
<br />
<pre class="brush: csharp"> public static bool operator !=(Employee employee, Employee otherEmployee)
{
var IsNotEqual = !employee.Equals(otherEmployee);
return IsNotEqual;
}
</pre>
</div>
<div style="text-align: left;">
We can see that it is just inverting the result returned the <i><b>Equals </b></i>method of <i><b>IEquatable<Employee></b></i> and passing it back to the caller. Now if we again build our Solution we will be able to build it successfully without any errors.<br />
<h2 style="text-align: left;">
Step 4 - Implementing GetHashCode</h2>
<div style="text-align: left;">
It is a practice and considered mandatory that if we override the Equals method for a type then we must also provide the overridden implementation for <i><b>GetHashCode()</b></i>.</div>
<div style="text-align: left;">
If we peek in to the implementation of <i><b>Object </b></i>we will see that there is a <i><b>virtual </b></i>method present in it named <i><b>GetHashCode</b></i>, its purpose is to return the <b>32-bit hash</b> of the value which is contained in the object itself.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLbQ9dHKczcnkPBqCvpdSNUX19JEVCjCsXymKgVDJPapPFK7-7SMP8w_KLs7yt0LtwBKx704n5AWCn4d5QQFRO_s9sNWWyZuv-UxTrdDuvym-gqK9iqnQhc8YDkFQQ-TbKj9sDhPCldIos/s1600/2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="664" data-original-width="893" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLbQ9dHKczcnkPBqCvpdSNUX19JEVCjCsXymKgVDJPapPFK7-7SMP8w_KLs7yt0LtwBKx704n5AWCn4d5QQFRO_s9sNWWyZuv-UxTrdDuvym-gqK9iqnQhc8YDkFQQ-TbKj9sDhPCldIos/s1600/2.PNG" /></a></div>
<br />
<br />
you might be wondering what is the purpose of this code, the <i><b>GetHashCode </b></i>method is used by types that internally use <b>HashTables </b>to store the objects which are normally <b>Collections </b>so they consume this method and get the hash value of the object to be used in the hash table as <b>HashTables </b>utilize the hash codes of the objects. In <b>Framework Class Libraries</b> the <i><b>Dictionary<TKey,TValue></b></i> also uses HashTable internally.<br />
</div>
<div style="text-align: left;">
Hash Codes is a complete topic on which a full article can be written to cover its aspects and we will not not be focusing in details on it. How Hash Tables work is that if two objects return true when called Equals method on them, then the Hash Codes for both objects should also be returned same when we call <i><b>GetHashCode </b></i>method on both which in our case would mean that the following line should return true as well.<br />
</div>
<div style="text-align: left;">
So what it actually means is that If <span style="color: #444444;"><i><b><span style="color: black;">employee.Equals(OtherEmployee</span>)</b></i></span> results in true then <i><b>employee.GetHashCode() == otherEmployee.GetHasCode()</b></i> should also return true as result. If the GetHashCode method is not implemented how it is required then the using Dictionary on our type wouldn’t work properly and can cause problems.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Now let’s add the implementation for our <i><b>Employee </b></i>type <i><b>GetHashCode </b></i>method which would be:</div>
<div style="text-align: left;">
<pre class="brush: csharp"> public override int GetHashCode()
{
return Name.GetHashCode() ^ Department.GetHashCode();
}
</pre>
</div>
<br />
So it is quite simple to understand that what we are doing above, we are just taking the HashCode for our <i><b>String </b></i>field <i><b>Name </b></i>and <i><b>Department </b></i>Enumeration and combining them using <i><b>XOR </b></i>as both the framework provided types so there is already implementation presentation for generating the Hash Code for these types, so we are just reusing the Hash Codes that are already available and provided by framework.<br />
<br />
Now let’s add some code in the <i><b>Main</b></i> method to verify what we have implemented is working as expected, add the following code in the Main and run it:<br />
<br />
<br />
<pre class="brush: csharp"> static void Main(string[] args)
{
Employee ehsan = new Employee("Ehsan Sajjad", Gender.Male, Department.SoftwareDevelopment);
Employee ehsan2 = new Employee("Ehsan Sajjad", Gender.Female, Department.SoftwareDevelopment);
Employee bilal = new Employee("Bilal Asghar", Gender.Male, Department.QualityAssurance);
object ehsanObj = ehsan;
Console.WriteLine(ehsan.Equals(ehsan2));
Console.WriteLine(ehsanObj.Equals(ehsan2));
Console.WriteLine(ehsan == ehsan2);
Console.WriteLine(ehsan.Equals(bilal));
Console.WriteLine(ehsanObj.Equals(bilal));
Console.WriteLine(ehsan == bilal);
Console.ReadKey();
}
</pre>
<br />
The following is the result which was printed on the Console:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5FsRGKx0hNRvV4q4LPJ0bEfGK1Qn5rXZA25CT6HpaNu-jTrvzK5P2wUjyvaK-LNTdRSScaeKrSIxIffrO_1CiVmU8S3BI2c0t4a357La0OR_v9opP9uHm1cGwToS4tZT1Q6ZQ3GxJV-5b/s1600/3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="303" data-original-width="641" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5FsRGKx0hNRvV4q4LPJ0bEfGK1Qn5rXZA25CT6HpaNu-jTrvzK5P2wUjyvaK-LNTdRSScaeKrSIxIffrO_1CiVmU8S3BI2c0t4a357La0OR_v9opP9uHm1cGwToS4tZT1Q6ZQ3GxJV-5b/s1600/3.PNG" /></a></div>
<br />
We can observe the for <i><b>ehsan </b></i>and <i><b>ehsan2 </b></i>objects all the three conditions have evaluated to return <i><b>true </b></i>which of course means that both are equal which was expected as this is how we defined to check for equality in our type, though we defined <i><b>Gender </b></i>field different in both objects but it has evaluated that both are equal as we are not considering <i><b>Gender </b></i>field when deciding that if two are equal or not.<br />
<h2 style="text-align: left;">
Summary</h2>
<div style="text-align: left;">
Following are the points that we learned in this post:</div>
<ul style="text-align: left;">
<li>We learned how to provide Custom implementation for Equality checking of Value Types</li>
<li>Implementing Equality for Value Types is normally good to do as it would improve performance by eliminating <b>boxing/unboxing</b> and <b>reflection </b>cost which can make our code inefficient.</li>
<li>There are multiple things to take care of when overriding equality for Value Types which includes:</li>
<ul>
<li>Implementing <i><b>IEquatable<T></b></i> interface of that Value Type which will have type safe Equals method for checking two object of a type T</li>
<li>Overriding the <i><b>Object.Equals</b></i> method which in turn calls the <i><b>Equals </b></i>method which we implemented for <i><b>IEquatable<T></b></i></li>
<li>Implementing the <b>==</b> and <b>!= operator</b> overloads which also call the <i><b>Equals </b></i>method on <i><b>IEquatable<T></b></i></li>
<li>Implementing <i><b>GetHashCode </b></i>of <i><b>Object </b></i>for our value type <i><b>T</b></i></li>
</ul>
<li>This is the recommended approach for implementing Equality for Value Types and this is not recommended way in case of Reference Types.</li>
</ul>
<div style="text-align: left;">
</div>
</div>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-73115160634347150202017-06-11T17:36:00.002-07:002017-06-13T13:16:22.226-07:00AJAX CRUD in Grid using JQuery DataTables in ASP.NET MVC 5<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<br />
<h2 style="text-align: left;">
Introduction</h2>
<div style="text-align: left;">
I frequently come across questions on online forums like <b>StackOverflow </b>in which the questioners are able to create CRUD operations for their entity which is a normal form post, but they struggle implementing the CRUD via ajax so that page does not reloads completely for better User Experience.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
In this post, I will be addressing this problem and we will learn that how can implement CRUD using <b>JQuery DataTables</b> in one page without any full page reloads.</div>
<h2 style="text-align: left;">
Background </h2>
<div style="text-align: left;">
I had been writing in last few posts about the usage of <i><b>JQuery DataTables</b></i> and it can be leveraged to build a <i><b>GridView </b></i>like functionality in asp.net mvc, we saw how we can install it using <i><b>NuGet Package Manager</b></i> and implement a simple gird using the plugin which provides us the essential features like Sorting, Searching and Pagination, then we saw how we can implement the paging, filtering and Ordering, then we proceeded to see how advanced search can be added for more better user experience.</div>
<div style="text-align: left;">
<br />
If someone wants to have refresher or interested to read the previous posts related, they can be found here:</div>
<div style="text-align: left;">
<br /></div>
<ul style="text-align: left;">
<li><a href="http://developmentpassion.blogspot.nl/2016/07/beginners-guide-for-creating-gridview.html">Beginners Guide for Creating GridView in ASP.NET MVC 5</a></li>
<li><a href="http://developmentpassion.blogspot.nl/2016/08/grid-view-with-server-side-filtering.html">Grid View with Server Side Filtering, Sorting and Paging in ASP.NET MVC 5</a></li>
<li><a href="http://developmentpassion.blogspot.com/2017/02/gridview-with-server-side-advacned.html">Grid View With Server Side Advanced Search Using jQuery DataTables In ASP.NET MVC 5</a></li>
</ul>
In this post we will learn how we can add create, update and delete operations support in the grid that we already implemented using JQuery DataTables. The end result will look something like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVEsAcMKqdTTQFC5X5y1_KujjP4dOnKUk7mVhBCTFQibwfaeCLoZQ-IzndWQhrQicP2VcyF_7RmYHka7jSQTDraNh5vDMIz6oin3x4OPejCFRpx2axHQF5QncGfmVBV397ZZqeaMkSiCNV/s1600/GridAjaxCRUDDemo.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="702" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVEsAcMKqdTTQFC5X5y1_KujjP4dOnKUk7mVhBCTFQibwfaeCLoZQ-IzndWQhrQicP2VcyF_7RmYHka7jSQTDraNh5vDMIz6oin3x4OPejCFRpx2axHQF5QncGfmVBV397ZZqeaMkSiCNV/s1600/GridAjaxCRUDDemo.gif" /></a></div>
<br />
<h2 style="text-align: left;">
Database Creation using Script</h2>
<div style="text-align: left;">
First of all we will run the script for database and tables creation that would be essential for this post. Following is the script for that:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: sql">CREATE DATABASE [AdvancedSearchGridExampleMVC]
GO
CREATE TABLE [dbo].[FacilitySites] ([FacilitySiteID] UNIQUEIDENTIFIER NOT NULL,
[FacilityName] NVARCHAR (MAX) NULL,
[IsActive] BIT NOT NULL,
[CreatedBy] UNIQUEIDENTIFIER NOT NULL,
[CreatedAt] DATETIME NOT NULL,
[ModifiedBy] UNIQUEIDENTIFIER NULL,
[ModifiedAt] DATETIME NULL,
[IsDeleted] BIT NOT NULL
);
GO
CREATE TABLE [dbo].[Assets] (
[AssetID] UNIQUEIDENTIFIER NOT NULL,
[Barcode] NVARCHAR (MAX) NULL,
[SerialNumber] NVARCHAR (MAX) NULL,
[PMGuide] NVARCHAR (MAX) NULL,
[AstID] NVARCHAR (MAX) NOT NULL,
[ChildAsset] NVARCHAR (MAX) NULL,
[GeneralAssetDescription] NVARCHAR (MAX) NULL,
[SecondaryAssetDescription] NVARCHAR (MAX) NULL,
[Quantity] INT NOT NULL,
[Manufacturer] NVARCHAR (MAX) NULL,
[ModelNumber] NVARCHAR (MAX) NULL,
[Building] NVARCHAR (MAX) NULL,
[Floor] NVARCHAR (MAX) NULL,
[Corridor] NVARCHAR (MAX) NULL,
[RoomNo] NVARCHAR (MAX) NULL,
[MERNo] NVARCHAR (MAX) NULL,
[EquipSystem] NVARCHAR (MAX) NULL,
[Comments] NVARCHAR (MAX) NULL,
[Issued] BIT NOT NULL,
[FacilitySiteID] UNIQUEIDENTIFIER NOT NULL
);
GO
CREATE NONCLUSTERED INDEX [IX_FacilitySiteID]
ON [dbo].[Assets]([FacilitySiteID] ASC);
GO
ALTER TABLE [dbo].[Assets]
ADD CONSTRAINT [PK_dbo.Assets] PRIMARY KEY CLUSTERED ([AssetID] ASC);
GO
ALTER TABLE [dbo].[Assets]
ADD CONSTRAINT [FK_dbo.Assets_dbo.FacilitySites_FacilitySiteID] FOREIGN KEY ([FacilitySiteID]) _
REFERENCES [dbo].[FacilitySites] ([FacilitySiteID]) ON DELETE CASCADE;
GO
</pre>
</div>
<br />
You can find the script in attached source code in file name dbScript.sql which also contains sample data to get started quickly, running it will create the DB and will add some sample data in the tables as well.<br />
<h2 style="text-align: left;">
Create/Insert Operation</h2>
<div style="text-align: left;">
For the insertion part, first of all we need to create a partial view in <i><b>Views >> Asset</b></i> by right clicking the <i><b>Asset </b></i>folder and navigate to <i><b>Add >> MVC 5 Partial Page (Razor)</b></i> like the below screen shot:</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAGKVlB-vf7d57IS_w9FxLSGAwHEJ7FDkrDBM5-t-R1BGA7UiH9175hOg-1l7gtkXqJQRkdqTt-qMGE1JrbuKvB7pDIXqiHkosiI34U8GNd8BNPgKcr7qh38Wv1V6mmWqiGhwEk_UMLXZk/s1600/Screen1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="757" data-original-width="1289" height="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAGKVlB-vf7d57IS_w9FxLSGAwHEJ7FDkrDBM5-t-R1BGA7UiH9175hOg-1l7gtkXqJQRkdqTt-qMGE1JrbuKvB7pDIXqiHkosiI34U8GNd8BNPgKcr7qh38Wv1V6mmWqiGhwEk_UMLXZk/s320/Screen1.png" width="320" /></a></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Open the container view in which asset rows are being rendered which <i><b>_AssetsPartial.cshtml</b></i> located in <i><b>Views >> Asset</b></i> directory and add the html for the Add Asset button which will open up a popup for inserting a new asset row in database:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: html"><button type="button" class="btn btn-default btn-md" data-toggle="modal" data-url="@Url.Action("Create","Asset")" id="btnCreateAsset">
<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span> Add Asset
</button>
</pre>
</div>
<br />
Now, open the Index View of Asset which is <i><b>Views >> Asset >> index.csthtml</b></i> and in scripts section add the following jQuery code for the button click event which we just created above, it will call the create get action and will display the partial view in bootstrap modal to user, the code for which is:<br />
<br />
<pre class="brush: js">$("#btnCreateAsset").on("click", function () {
var url = $(this).data("url");
$.get(url, function (data) {
$('#createAssetContainer').html(data);
$('#createAssetModal').modal('show');
});
});
</pre>
<br />
We also need to add bootstrap modal with container div in which we will be loading create partial view of Asset, so we will add the following html at the end of <i><b>Index.cshtml</b></i> view:<br />
<br />
<pre class="brush: html"><div class="modal fade" id="createAssetModal" tabindex="-1" role="dialog" aria-labelledby="CreateAssetModal" aria-hidden="true" data-backdrop="static">
<div id="createAssetContainer">
</div>
</div>
</pre>
<br />
<h2 style="text-align: left;">
Implementing Add GET Action </h2>
<div style="text-align: left;">
Add action method for Asset Creation get request in the Asset controller file located at <i><b>Controllers >> AssetController.cs</b></i> which would be called by the above jQuery code, inside the action method we are populating the ViewModel and passing the instance back to PartialView as normally we do in mvc based application:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">public ActionResult Create()
{
var model = new AssetViewModel();
model.FacilitySitesSelectList = GetFacilitiySitesSelectList();
return View("_CreatePartial", model);
}
</pre>
<br />
<h2 style="text-align: left;">
Add Partial View Creation:</h2>
<div style="text-align: left;">
Add a new Partial view in project in Asset Views for Create form, for that right click the <i><b>Asset </b></i>folder under <i><b>Views </b></i>in the <i><b>Solution Explorer</b></i>: </div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgfPgYhnxXY1G4I3y09UN9E0LPTd1swwmqJGkDJnlI-rAapUvTb4K0I51HWRB0xc0n37mfhv_eB-sstRdkKv2x2se9Sv4OLa2JPogoZcj9Lakr-ck_0VLgZONqigS-T66cx-Ka6c8qtXcW/s1600/Screen1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="757" data-original-width="1289" height="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgfPgYhnxXY1G4I3y09UN9E0LPTd1swwmqJGkDJnlI-rAapUvTb4K0I51HWRB0xc0n37mfhv_eB-sstRdkKv2x2se9Sv4OLa2JPogoZcj9Lakr-ck_0VLgZONqigS-T66cx-Ka6c8qtXcW/s320/Screen1.png" width="320" /></a></div>
</div>
<div style="text-align: left;">
Enter the name of partial view to be <i><b>_CreatePartial</b></i> in textbox or whatever name you think would be better in your case.<br />
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwyDSIYub1sUrSwN3tVuZxFsAym2k4M1k5LiXyVb9CInIIUqjaBGOdI37-qWdOQJkVh-N26OYY2o2UltsVAtWmN2GLTmmg3Y3BXUvPAolyAQ7KlO3gNx_vT1h3n4l_caihMjcy-3L_KnjW/s1600/Screen2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="524" data-original-width="1046" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwyDSIYub1sUrSwN3tVuZxFsAym2k4M1k5LiXyVb9CInIIUqjaBGOdI37-qWdOQJkVh-N26OYY2o2UltsVAtWmN2GLTmmg3Y3BXUvPAolyAQ7KlO3gNx_vT1h3n4l_caihMjcy-3L_KnjW/s320/Screen2.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKl2MI5fzYjnZIuAj-_8eWqnTWsce_oJf9O1uW6UkhUIjdeTqMUSGdoUE3AhU4GRhKvU-rgG8119THi9EGX3CaZU7YvWSbAUUbEJ93e1okk-fVm28xcTUILm5Kua6-DMoiqTBybbQkqIgD/s1600/Screen3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="190" data-original-width="1178" height="51" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKl2MI5fzYjnZIuAj-_8eWqnTWsce_oJf9O1uW6UkhUIjdeTqMUSGdoUE3AhU4GRhKvU-rgG8119THi9EGX3CaZU7YvWSbAUUbEJ93e1okk-fVm28xcTUILm5Kua6-DMoiqTBybbQkqIgD/s320/Screen3.png" width="320" /></a></div>
<div style="text-align: left;">
</div>
</div>
<div style="text-align: left;">
<div style="text-align: left;">
<br /></div>
<h2 style="text-align: left;">
Implementing Add Partial View</h2>
<div style="text-align: left;">
Now we will write the partial view that we created in previous step <i><b>_CreatePatial</b></i>, add the following code in that View:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: html">@model GridAjaxCRUDMVC.Models.AssetViewModel
@{
Layout = null;
}
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Add Asset</h4>
</div>
@using (Ajax.BeginForm("Create", "Asset", null, new AjaxOptions { HttpMethod = "Post", OnSuccess = "CreateAssetSuccess" }, new { @class = "form-horizontal", role = "form" }))
{
<div class="modal-body">
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.AssetID, new { Value = Guid.NewGuid() })
<div class="form-group">
@Html.LabelFor(model => model.Barcode, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Barcode, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Barcode, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.SerialNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.SerialNumber, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.SerialNumber, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.FacilitySiteID, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.FacilitySiteID, Model.FacilitySitesSelectList, "Select One", new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FacilitySiteID, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PMGuide, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PMGuide, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PMGuide, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.AstID, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.AstID, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.AstID, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ChildAsset, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ChildAsset, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ChildAsset, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.GeneralAssetDescription, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.GeneralAssetDescription, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.GeneralAssetDescription, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.SecondaryAssetDescription, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.SecondaryAssetDescription, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.SecondaryAssetDescription, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Quantity, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Quantity, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Manufacturer, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Manufacturer, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Manufacturer, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ModelNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ModelNumber, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ModelNumber, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Building, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Building, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Building, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Floor, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Floor, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Floor, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Corridor, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Corridor, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Corridor, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.RoomNo, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.RoomNo, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.RoomNo, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.MERNo, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.MERNo, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.MERNo, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.EquipSystem, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.EquipSystem, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.EquipSystem, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Comments, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Comments, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Comments, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Issued, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
@Html.EditorFor(model => model.Issued)
@Html.ValidationMessageFor(model => model.Issued, "", new { @class = "text-danger" })
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="submit" class="btn btn-primary" value="Save" />
</div>
</div>
</div>
}
</div>
</div>
</pre>
<br />
<h2 style="text-align: left;">
Implementing Add/Create Post Action </h2>
<div style="text-align: left;">
The important thing to note in the view code is the <i><b>Ajax.BeginForm</b></i> helper portion as the class <i><b>Ajax</b></i> should be enough to understand that it will post the model back to controller action via Ajax, which means that whole will not refresh i.e. no full postback will happen in terms on asp.net web forms.</div>
<div style="text-align: left;">
<br />
The post action is simply mapping ViewModel object to the Model and then saving it in the repository:</div>
<div style="text-align: left;">
<pre class="brush: csharp">[HttpPost]
public async Task<ActionResult> Create(AssetViewModel assetVM)
{
if (!ModelState.IsValid)
return View("_CreatePartial", assetVM);
Asset asset = MaptoModel(assetVM);
DbContext.Assets.Add(asset);
var task = DbContext.SaveChangesAsync();
await task;
if (task.Exception != null)
{
ModelState.AddModelError("", "Unable to add the Asset");
return View("_CreatePartial", assetVM);
}
return Content("success");
}
</pre>
</div>
<br />
We are trying to save the newly entered asset in the database and tracking if it is saved successfully or not and if it saves successfully we are returning a string message <b>“success”</b> back to client side and in the success call back of Ajax Form we will be checking if operation was successful or not to do UI changes according to that.<br />
<div style="text-align: left;">
<br /></div>
<h2 style="text-align: left;">
Implementing Ajax Callback Function</h2>
We can see that in <i><b>BeginForm </b></i>helper method parameters we are specifying JavaScript function to be called when the Ajax Form successfully returns back from server i.e. <i><b>OnSuccess = <span style="color: #990000;">"CreateAssetSuccess"</span></b></i><br />
<br />
Now let’s go to the <i><b>index.cshtml</b></i> view of Asset and define the success callback implementation:<br />
<br />
<pre class="brush: js">function CreateAssetSuccess(data) {
if (data != "success") {
$('#createAssetContainer').html(data);
return;
}
$('#createAssetModal').modal('hide');
$('#createAssetContainer').html("");
assetListVM.refresh();
}
</pre>
</div>
<br />
What we are doing here is if the operation is not successful we are updating the client side html to notify the user about the failure of creation and if the insert goes successful we are closing the modal popup and refreshing the Grid to display the up to date information.<br />
<br />
<h2 style="text-align: left;">
Edit/Update Operation:</h2>
Until now we should be able to run the application and successfully add new assets in the database via Ajax using the bootstrap modal which we created above, now let’s move to the update part of the Asset.<br />
We will be adding another column in the datatable columns collection which will contain hyper link that will navigate to Edit View, but as we are using Ajax and bootstrap modal, we will be doing updates as well same way, so no redirect will be involved. Let’s get started.<br />
Open the <i><b>Index.csthml</b></i> file and add a new column in the columns collection in jQuery datatable initialization, after updating the columns array our code would look like:<br />
<br />
<pre class="brush: js">"columns": [
{ "title": "Bar Code", "data": "BarCode", "searchable": true },
{ "title": "Manufacturer", "data": "Manufacturer", "searchable": true },
{ "title": "Model", "data": "ModelNumber", "searchable": true },
{ "title": "Building", "data": "Building", "searchable": true },
{ "title": "Room No", "data": "RoomNo" },
{ "title": "Quantity", "data": "Quantity" },
{
"title": "Actions",
"data": "AssetID",
"searchable": false,
"sortable": false,
"render": function (data, type, full, meta) {
return '<a href="@Url.Action("Edit","Asset")?id=' + data + '" class="editAsset">Edit</a>';
}
}
]
</pre>
</div>
<br />
We are setting the header of new column to display Actions as title and we would need to disable the searching and sorting for this column, as it is for edit operation and it does not makes sense to enable sorting and searching on this column. Next we are defining the render method of the column and we are generating anchor link html which could call the Edit action of Asset controller and will pass the current asset id to pull the information of it and display in the Edit View. <br />
<h2 style="text-align: left;">
Defining Edit/Update GET Action:</h2>
After doing the datatable js changes, now we need to create a get action method which will pull the asset record from the database and will display it for editing to the user in a popup.<br />
Let’s implement the Edit get action of it:<br />
<br />
<pre class="brush:csharp">public ActionResult Edit(Guid id)
{
var asset = DbContext.Assets.FirstOrDefault(x => x.AssetID == id);
AssetViewModel assetViewModel = MapToViewModel(asset);
if (Request.IsAjaxRequest())
return PartialView("_EditPartial",assetViewModel);
return View(assetViewModel);
}
</pre>
<br />
The action simply retrieves the row from the database and after converting it to ViewModel passes it to back to partial view to rendered or returned back to the client side for processing, as no post backs would happen it will generate the html and will send the html back in response of ajax call which client side will handle and decide where to put that html.<br />
<h2 style="text-align: left;">
Handling Action Links Events on Client Side using JQuery:</h2>
From the column render function you can see that there is class applied on anchor link called <i><b>EditAsset</b></i>, it is defined because jQuery event handler will be applied to the anchor link and Ajax call will be sent to server, let’s define the event handler for that in Index View:<br />
<br />
<pre class="brush: js">$('#assets-data-table').on("click", ".editAsset", function (event) {
event.preventDefault();
var url = $(this).attr("href");
$.get(url, function (data) {
$('#editAssetContainer').html(data);
$('#editAssetModal').modal('show');
});
});
</pre>
<br />
<h2 style="text-align: left;">
Addition of Bootstrap Modal</h2>
Now add the bootstrap modal html in the Index View which will be placeholder for loading the Edit View, define it just after create bootstrap modal html:<br />
<br />
<pre class="brush: html"><div class="modal fade" id="editAssetModal" tabindex="-1" role="dialog" aria-labelledby="EditAssetModal" aria-hidden="true" data-backdrop="static">
<div id="editAssetContainer">
</div>
</div>
</pre>
<h2 style="text-align: left;">
</h2>
<h2 style="text-align: left;">
Edit/Update Partial View Creation:</h2>
Create another new partial view following the same steps which we did for adding <i><b>_CreatePartial.cshtml</b></i> which was for Create Asset, So add a new Partial View in the Asset folder in <i><b>Views </b></i>with name <i><b>_EditPartial.cshtml</b></i> and add the following code in it:<br />
<br />
<pre class="brush: html">@model TA_UM.ViewModels.AssetViewModel
@{
Layout = null;
}
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Edit Asset</h4>
</div>
@using (Ajax.BeginForm("Edit", "Asset", null, new AjaxOptions { HttpMethod="Post", OnSuccess = "UpdateAssetSuccess" }, new { @class = "form-horizontal", role = "form" }))
{
<div class="modal-body">
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.AssetID)
<div class="form-group">
@Html.LabelFor(model => model.Barcode, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Barcode, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Barcode, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.SerialNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.SerialNumber, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.SerialNumber, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.FacilitySiteID, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.FacilitySiteID,Model.FacilitySitesSelectList, "Select One", new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FacilitySiteID, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PMGuide, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PMGuide, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PMGuide, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.AstID, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.AstID, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.AstID, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ChildAsset, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ChildAsset, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ChildAsset, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.GeneralAssetDescription, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.GeneralAssetDescription, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.GeneralAssetDescription, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.SecondaryAssetDescription, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.SecondaryAssetDescription, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.SecondaryAssetDescription, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Quantity, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Quantity, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Manufacturer, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Manufacturer, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Manufacturer, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ModelNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ModelNumber, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ModelNumber, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Building, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Building, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Building, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Floor, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Floor, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Floor, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Corridor, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Corridor, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Corridor, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.RoomNo, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.RoomNo, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.RoomNo, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.MERNo, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.MERNo, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.MERNo, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.EquipSystem, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.EquipSystem, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.EquipSystem, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Comments, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Comments, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Comments, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Issued, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
@Html.EditorFor(model => model.Issued)
@Html.ValidationMessageFor(model => model.Issued, "", new { @class = "text-danger" })
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="submit" class="btn btn-primary" value="Save changes"/>
</div>
</div>
</div>
}
</div>
</div>
</pre>
<br />
The Edit View is also pretty same as we had for Insert except it would be posting to different action which would be responsible for handling the updates of a particular Asset row.<br />
<h2 style="text-align: left;">
Implementing Edit/Update Post Action:</h2>
Now let’s implement the post action of Edit:<br />
<br />
<pre class="brush: csharp"> [HttpPost]
public async Task<ActionResult> Edit(AssetViewModel assetVM)
{
assetVM.FacilitySitesSelectList = GetFacilitiySitesSelectList(assetVM.FacilitySiteID);
if (!ModelState.IsValid)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return View(Request.IsAjaxRequest() ? "_EditPartial" : "Edit", assetVM);
}
Asset asset = MaptoModel(assetVM);
DbContext.Assets.Attach(asset);
DbContext.Entry(asset).State = EntityState.Modified;
var task = DbContext.SaveChangesAsync();
await task;
if (task.Exception != null)
{
ModelState.AddModelError("", "Unable to update the Asset");
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return View(Request.IsAjaxRequest() ? "_EditPartial" : "Edit", assetVM);
}
if(Request.IsAjaxRequest())
{
return Content("success");
}
return RedirectToAction("Index");
}
</pre>
<br />
<h2 style="text-align: left;">
Handling Update Ajax Success CallBack</h2>
In <i><b>Index.cshtml</b></i> implement the <i><b>OnSuccess </b></i>callback function which will be called when the asset gets updated successfully, in the call back function modal would be closed and the form will be cleared so that if user opens for editing again the fresh html would be fetched and updated information will be displayed in View and of course datatable will also be refreshed to display the latest updates:<br />
<br />
<pre brush:="" class="" js=""> /**** Edit Asset Ajax Form CallBack ********/
function UpdateAssetSuccess(data) {
if (data != "success") {
$('#editAssetContainer').html(data);
return;
}
$('#editAssetModal').modal('hide');
$('#editAssetContainer').html("");
assetListVM.refresh();
}
</pre>
<br />
The same approach will be followed for the details and delete action, let’s see the delete portion, first of all open the Index view and let’s add the details and delete action hyperlinks in the render function where we defined the edit link above:<br />
<br />
<pre class="brush:js">"render": function (data, type, full, meta) {
return '<a href="@Url.Action("Edit","Asset")?id=' + data + '" class="editAsset">Edit</a> | <a href="@Url.Action("Details","Asset")?id=' + data + '">Details</a> | <a href="@Url.Action("Delete","Asset")?id=' + data + '">Delete</a>';
}
</pre>
<br />
Now the action column will contain three hyperlinks for Edit, Details and Delete of Asset.<br />
<br />
<h2 style="text-align: left;">
Retrieve and Delete Operation:</h2>
At this stage we should be able to see the insert and update functionality working correctly, now we will move to the deletion part to see how we implement the Deletion part for Assets. For doing that, we will need to add class to the hyperlinks which we are generated in the render function for the column in which links will be appearing, let’s do that first, we need to define the <b>render </b>property for the last column in <b>columns </b>array of the DataTables initialization code, and we will define the how the column value should be rendered:<br />
<br />
<pre class="brush: js">"render": function (data, type, full, meta) {
return '<a href="@Url.Action("Edit","Asset")?id=' + data + '" class="editAsset">Edit</a> | <a href="@Url.Action("Details","Asset")?id=' + data + '" class="detailsAsset">Details</a> | <a href="@Url.Action("Delete","Asset")?id=' + data + '" class="deleteAsset">Delete</a>';
}
</pre>
<br />
We have added the <b>detailsAsset </b>and <b>deleteAsset </b>classes to the respective anchor tags so that we can bind the events using jQuery and do some logic to display details or delete particular asset.<br />
<br />
After doing the above step, now we will be writing the events to handle the click of these two hyperlinks. We will have to write the following code to achieve it :<br />
<br />
<pre class="brush: js">$('#assets-data-table').on("click", ".detailsAsset", function (event) {
event.preventDefault();
var url = $(this).attr("href");
$.get(url, function (data) {
$('#detailsAssetContainer').html(data);
$('#detailsAssetModal').modal('show');
});
</pre>
Now as the handler for details tag is placed, let’s move to the view part and write the needed razor code in the respective view. So, Create a new partial view named <b>_detailsPartial</b> which will be responsible for displaying the details of the particular asset selected. For that again Right click the Asset folder in Views directory in Solution Explorer and do the same steps as previously and create the partial with the name mentioned above and add the following code in it.<br />
<pre class="brush: html">@model GridAdvancedSearchMVC.Models.AssetViewModel
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Asset Details</h4>
<hr/>
</div>
<div class="modal-body">
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Barcode)
</dt>
<dd>
@Html.DisplayFor(model => model.Barcode)
</dd>
<dt>
@Html.DisplayNameFor(model => model.SerialNumber)
</dt>
<dd>
@Html.DisplayFor(model => model.SerialNumber)
</dd>
<dt>
@Html.DisplayNameFor(model => model.FacilitySite)
</dt>
<dd>
@Html.DisplayFor(model => model.FacilitySite)
</dd>
<dt>
@Html.DisplayNameFor(model => model.PMGuide)
</dt>
<dd>
@Html.DisplayFor(model => model.PMGuide)
</dd>
<dt>
@Html.DisplayNameFor(model => model.AstID)
</dt>
<dd>
@Html.DisplayFor(model => model.AstID)
</dd>
<dt>
@Html.DisplayNameFor(model => model.ChildAsset)
</dt>
<dd>
@Html.DisplayFor(model => model.ChildAsset)
</dd>
<dt>
@Html.DisplayNameFor(model => model.GeneralAssetDescription)
</dt>
<dd>
@Html.DisplayFor(model => model.GeneralAssetDescription)
</dd>
<dt>
@Html.DisplayNameFor(model => model.SecondaryAssetDescription)
</dt>
<dd>
@Html.DisplayFor(model => model.SecondaryAssetDescription)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Quantity)
</dt>
<dd>
@Html.DisplayFor(model => model.Quantity)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Manufacturer)
</dt>
<dd>
@Html.DisplayFor(model => model.Manufacturer)
</dd>
<dt>
@Html.DisplayNameFor(model => model.ModelNumber)
</dt>
<dd>
@Html.DisplayFor(model => model.ModelNumber)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Building)
</dt>
<dd>
@Html.DisplayFor(model => model.Building)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Floor)
</dt>
<dd>
@Html.DisplayFor(model => model.Floor)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Corridor)
</dt>
<dd>
@Html.DisplayFor(model => model.Corridor)
</dd>
<dt>
@Html.DisplayNameFor(model => model.RoomNo)
</dt>
<dd>
@Html.DisplayFor(model => model.RoomNo)
</dd>
<dt>
@Html.DisplayNameFor(model => model.MERNo)
</dt>
<dd>
@Html.DisplayFor(model => model.MERNo)
</dd>
<dt>
@Html.DisplayNameFor(model => model.EquipSystem)
</dt>
<dd>
@Html.DisplayFor(model => model.EquipSystem)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Comments)
</dt>
<dd>
@Html.DisplayFor(model => model.Comments)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Issued)
</dt>
<dd>
@Html.DisplayFor(model => model.Issued)
</dd>
</dl>
</div>
</div>
</div>
</pre>
<br />
<h2 style="text-align: left;">
Details Get Action Implementation:</h2>
Now it’s the time to define the controller action code which will retrieve the asset information from the data source and will pass it back to view to be displayed to the user. Here is the code for controller action:<br />
<br />
<pre class="brush: csharp"> public async Task<ActionResult> Details(Guid id)
{
var asset = await DbContext.Assets.FirstOrDefaultAsync(x => x.AssetID == id);
var assetVM = MapToViewModel(asset);
if(Request.IsAjaxRequest())
return PartialView("_detailsPartial", assetVM);
return View(assetVM);
}
</pre>
<br />
<h2 style="text-align: left;">
Implementing Delete Operation:</h2>
We will add the GET action method for delete which will get the particular asset from the repository and will display the details in popup, where user would be able to delete it or cancel it. Here is the code for the action method:<br />
<pre class="brush: csharp"> public ActionResult Delete(Guid id)
{
var asset = DbContext.Assets.FirstOrDefault(x => x.AssetID == id);
AssetViewModel assetViewModel = MapToViewModel(asset);
if (Request.IsAjaxRequest())
return PartialView("_DeletePartial", assetViewModel);
return View(assetViewModel);
}
</pre>
<br />
<h2 style="text-align: left;">
Delete Partial View Addition</h2>
We will now add another partial view in the solution for delete part, so navigate to the <i><b>Views >> Asset</b></i> folder in the <i><b>Solution Explorer</b></i> and from the context menu which appears by right clicking the <i><b>Asset </b></i>folder, add a new View using the Option <i><b>Add >> MVC 5 Partial Page (Razor)</b></i> and name the partial view to <i><b>_DeletePartial</b></i> and add the following code to it:<br />
<pre class="brush: html">@model GridAdvancedSearchMVC.Models.AssetViewModel
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Delete Asset</h4>
<h3>Are you sure you want to delete this?</h3>
</div>
<div class="modal-body">
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Barcode)
</dt>
<dd>
@Html.DisplayFor(model => model.Barcode)
</dd>
<dt>
@Html.DisplayNameFor(model => model.SerialNumber)
</dt>
<dd>
@Html.DisplayFor(model => model.SerialNumber)
</dd>
<dt>
@Html.DisplayNameFor(model => model.FacilitySite)
</dt>
<dd>
@Html.DisplayFor(model => model.FacilitySite)
</dd>
<dt>
@Html.DisplayNameFor(model => model.PMGuide)
</dt>
<dd>
@Html.DisplayFor(model => model.PMGuide)
</dd>
<dt>
@Html.DisplayNameFor(model => model.AstID)
</dt>
<dd>
@Html.DisplayFor(model => model.AstID)
</dd>
<dt>
@Html.DisplayNameFor(model => model.ChildAsset)
</dt>
<dd>
@Html.DisplayFor(model => model.ChildAsset)
</dd>
<dt>
@Html.DisplayNameFor(model => model.GeneralAssetDescription)
</dt>
<dd>
@Html.DisplayFor(model => model.GeneralAssetDescription)
</dd>
<dt>
@Html.DisplayNameFor(model => model.SecondaryAssetDescription)
</dt>
<dd>
@Html.DisplayFor(model => model.SecondaryAssetDescription)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Quantity)
</dt>
<dd>
@Html.DisplayFor(model => model.Quantity)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Manufacturer)
</dt>
<dd>
@Html.DisplayFor(model => model.Manufacturer)
</dd>
<dt>
@Html.DisplayNameFor(model => model.ModelNumber)
</dt>
<dd>
@Html.DisplayFor(model => model.ModelNumber)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Building)
</dt>
<dd>
@Html.DisplayFor(model => model.Building)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Floor)
</dt>
<dd>
@Html.DisplayFor(model => model.Floor)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Corridor)
</dt>
<dd>
@Html.DisplayFor(model => model.Corridor)
</dd>
<dt>
@Html.DisplayNameFor(model => model.RoomNo)
</dt>
<dd>
@Html.DisplayFor(model => model.RoomNo)
</dd>
<dt>
@Html.DisplayNameFor(model => model.MERNo)
</dt>
<dd>
@Html.DisplayFor(model => model.MERNo)
</dd>
<dt>
@Html.DisplayNameFor(model => model.EquipSystem)
</dt>
<dd>
@Html.DisplayFor(model => model.EquipSystem)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Comments)
</dt>
<dd>
@Html.DisplayFor(model => model.Comments)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Issued)
</dt>
<dd>
@Html.DisplayFor(model => model.Issued)
</dd>
</dl>
@using (Ajax.BeginForm("Delete", "Asset", null, new AjaxOptions { HttpMethod = "Post", OnSuccess = "DeleteAssetSuccess" }, new { @class = "form-horizontal", role = "form" }))
{
<div class="form-actions no-color">
@Html.HiddenFor(x => x.AssetID)
<input type="submit" value="Delete" class="btn btn-default" /> |
@Html.ActionLink("Back to List", "Index",null,new { data_dismiss = "modal" })
</div>
}
</div>
</div>
</div>
</pre>
<br />
Now we need to again a container div for delete popup as well which will be holding the html returned by the partial view <i><b>_DeletePartial</b></i> as we did for other three operations, so add the following html in the <i><b>Index.cshtml</b></i> view of <i><b>Asset </b></i>:<br />
<br />
<pre class="brush: html"><div class="modal fade" id="deleteAssetModal" tabindex="-1" role="dialog" aria-labelledby="DeleteAssetModal" aria-hidden="true" data-backdrop="static">
<div id="deleteAssetContainer">
</div>
</div>
</pre>
<br />
<h2 style="text-align: left;">
Handling Delete Link Event with JQuery:</h2>
We also need to implement the delete button click event which will be responsible for calling the action method asynchronously and will add the response html to the popup container and the popup container will be displayed to user, the code for which would be:<br />
<pre class="brush: js">$('#assets-data-table').on("click", ".deleteAsset", function (event) {
event.preventDefault();
var url = $(this).attr("href");
$.get(url, function (data) {
$('#deleteAssetContainer').html(data);
$('#deleteAssetModal').modal('show');
});
});
</pre>
<br />
<h2 style="text-align: left;">
Handling DELETE Ajax POST Success Callback:</h2>
If you notice here as well we are using <i><b>Ajax.BeginForm</b></i> helper method to post the <b>GUID </b>of Asset row that needs to be deleted, and we have specified a JavaScript success callback, but we haven’t yet defined the function in the <i><b>Index </b></i>view, so let’s do that as well, here is the function definition:<br />
<pre class="brush: js">function DeleteAssetSuccess(data) {
if (data != "success") {
$('#deleteAssetContainer').html(data);
return;
}
$('#deleteAssetModal').modal('hide');
$('#deleteAssetContainer').html("");
assetListVM.refresh();
}
</pre>
<br />
This is also quite same as we did for other actions, we are making sure that if deletion was successful or not, we update the UI accordingly, that’s what the above code is doing, it closes the popup, clears the html of the container div and refreshes the datatable ViewModel to reflect the latest changes in the grid.<br />
<br />
<h2 style="text-align: left;">
Implementing Delete POST Action:</h2>
Lastly, we need to define the POST action for delete which will be responsible for deleting the row from the database table and will return the status of the action back to view in either case i.e. success or failure, let’s do that, here is the code for <b>Delete </b>post action:<br />
<br />
<pre class="brush: csharp"> [HttpPost, ActionName("Delete")]
public async Task<ActionResult> DeleteAsset(Guid AssetID)
{
var asset = new Asset { AssetID = AssetID };
DbContext.Assets.Attach(asset);
DbContext.Assets.Remove(asset);
var task = DbContext.SaveChangesAsync();
await task;
if (task.Exception != null)
{
ModelState.AddModelError("", "Unable to Delete the Asset");
Response.StatusCode = (int)HttpStatusCode.BadRequest;
AssetViewModel assetVM = MapToViewModel(asset);
return View(Request.IsAjaxRequest() ? "_DeletePartial" : "Delete", assetVM);
}
if (Request.IsAjaxRequest())
{
return Content("success");
}
return RedirectToAction("Index");
}
</pre>
<br />
Now run the application and you should be able to add update and delete rows via Ajax without navigating between the pages.</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-66752315079644184122017-04-28T12:10:00.000-07:002017-05-04T04:54:07.440-07:00Equality Operator (==) Problem with Inheritance and Generics in C#<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<div dir="ltr" style="text-align: left;" trbidi="on">
<h2 style="text-align: left;">
Background</h2>
<div style="text-align: left;">
In the previous post, we learned that <b>== operator</b> does not works for non-primitive value types unless we overload the operator for that value type, and we saw how we can overload the equality operator to enable == operator comparison for non-primitive value types. We also compare the <b>== operator</b> and <b>Object.Equals</b> method to see how their behavior differs for primitive types, value types and reference types.</div>
<h2 style="text-align: left;">
Comparison of == operator and Object.Equals</h2>
<div style="text-align: left;">
Here is the comparison of both:</div>
<ul style="text-align: left;">
<li>For Primitive Types e.g. <b>int, float, long, bool</b> etc both the<i> <b>== operator</b></i> and <i><b>Object.Equals</b></i> method will compare the values i.e. 1 is equal to but 1, but 1 is not equal to 0 </li>
<li>For most of the Reference Types both the == operator and Object.Equals method will by default compare the references, you can modify this behavior by overloading the == operator or overriding the Object.Equals method but if you want the behavior of both to be consistent and don’t want to surprise other developers and yourself you must do the both (overload == operator and override the Equals method).</li>
<li>For Non-primitive Value Types the <i><b>Object.Equals</b></i> method will do the value equality using Refection which is slow and this is overridden behavior of course, but the equality operator is by default not available for value types unless you overload the == operator for that type which we saw in the example above.</li>
<li>There is also another minor difference that for reference types the virtual Equals method cannot work if the first parameter is null but that is trivial, as a workaround the static Equals method can be used which takes both the objects to be compared as parameter.</li>
</ul>
<h2 style="text-align: left;">
Previous Posts in the Series</h2>
<div style="text-align: left;">
You might want to read the previous posts in this series, if yes following are the links to the previous content related to it: </div>
<ul style="text-align: left;">
<li><b><a href="http://developmentpassion.blogspot.com/2016/06/story-of-complex-equality-in-net.html">Story of Equality in .Net – Part 1</a></b></li>
<li><b><a href="http://developmentpassion.blogspot.com/2016/06/story-of-equality-in-net-part-2.html">Equality and Object class in C# </a></b></li>
<li><b><a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-3.html">Equality and IEquatable<T> interface in C#</a></b></li>
<li><b><a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-4.html">== Operator and Primitive Types in C#</a> </b></li>
<li><b><a href="http://developmentpassion.blogspot.com/2016/08/story-of-equality-in-net-part-5.html">== Operator and Reference Types in C# </a></b></li>
<li><b><a href="http://developmentpassion.blogspot.com/2016/10/story-of-equality-in-net-part-6.html">== Operator and String class in C#</a></b></li>
<li><b><a href="http://developmentpassion.blogspot.nl/2017/01/equality-operator-and-value-types-in-c.html">== Operator and Value Types in C#</a></b></li>
</ul>
You might want to read the previous posts in this series, if yes following are the links to the previous content related to it:<br />
<h2 style="text-align: left;">
Introduction</h2>
<div style="text-align: left;">
In this post we will be seeing that why it is not always a good option to use == operator for doing equality, we will be seeing that how <i><b>== operator</b></i> does not work well with inheritance and generics and will see that the better options is to rely on <i><b>virtual Equals</b></i> method.</div>
<h2 style="text-align: left;">
Equality Operator and Inheritance Problem</h2>
<div style="text-align: left;">
Let’s create some example code that will illustrate how == operator behaves when inheritance is in play in our code, so let’s declare two string type variables and we will check the result once again by doing equality check in 4 different ways that are available in C#:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">public class Program
{
public static void Main(string[] args)
{
string str = "Ehsan Sajjad";
string str1 = string.Copy(str);
Console.WriteLine(ReferenceEquals(str, str1));
Console.WriteLine(str.Equals(str1));
Console.WriteLine(str == str1);
Console.WriteLine(object.Equals(str, str1));
}
}
</pre>
</div>
<h4 style="text-align: left;">
Output:</h4>
<div style="text-align: left;">
The following is the output of the above executed code:</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGVdTDNW3aFeaWkiQvlJVPS6jjsDPtJy9Hah8Tt5_yjU3z6f1h6hoD7FTs7nyCPBZLtnX02snucn6dq6SMQUYm7AdpFUGCGTNhyGwg533Sm5_WvVAL0ZQmSbbsB8-KSmUHxJjq3hvchmBL/s1600/%253D%253D+operator+1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGVdTDNW3aFeaWkiQvlJVPS6jjsDPtJy9Hah8Tt5_yjU3z6f1h6hoD7FTs7nyCPBZLtnX02snucn6dq6SMQUYm7AdpFUGCGTNhyGwg533Sm5_WvVAL0ZQmSbbsB8-KSmUHxJjq3hvchmBL/s1600/%253D%253D+operator+1.PNG" /> </a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div style="text-align: left;">
First we are checking that if both string variables have reference to same string object using <i><b>ReferenceEquals </b></i>method, next we check using the instance method <i><b>Equals </b></i>of <i><b>String</b></i> type, on third line we are again checking for equality but this time using the <i><b>== operator</b></i> and lastly we are checking using the static <i><b>Equals </b></i>method of <i><b>Object</b></i> so that we can compare the result of all these 4 techniques. We should be able to tell what would be the result from the previous posts which we have done so far:</div>
<ul style="text-align: left;">
<li><i><b>ReferenceEquals </b></i>will for sure return false as both are reference to different object not the same object. </li>
<li>The <i><b>Equals </b></i>method of <i><b>String</b></i> type will also return true as both strings are identical (i.e. same sequence or characters).</li>
<li><i><b>== Operator</b></i> will also return true as both string values are equal.</li>
<li><i><b>virtual Object.Equals</b></i> call will also return true as the overridden implementation of <i><b>String</b></i> would be called and it checks the equality of values of string.</li>
</ul>
All the above until now makes sense, now we will modify the above example a little, the only change we will do is instead of using variables of type <i><b>String</b></i>, we will use variables of type <i><b>Object </b></i>and we will see how the output differs from the above code, here is the code after converting it to use <i><b>Object</b></i> type instead of <i><b>String</b></i>:<br />
<br />
<div style="text-align: left;">
<pre class="brush: csharp">static void Main(string[] args)
{
Object str = "Ehsan Sajjad";
Object str1 = string.Copy((string)str);
Console.WriteLine(ReferenceEquals(str, str1));
Console.WriteLine(str.Equals(str1));
Console.WriteLine(str == str1);
Console.WriteLine(object.Equals(str, str1));
}
</pre>
</div>
<br />
<h4 style="text-align: left;">
Output:</h4>
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgncMqi5qC_p0OEruXWj1oE51JoPm05BGWsW0eV4BPHAHq7b3yeCz_KSubnACghlGxJQ3ekDaEV_whLQZmCLbHrp2U0k5yXQ3wafAXUpN129ARqD1aoTyXy7Ohb94LBJ0gGko6gsAKi67Vb/s1600/%253D%253D+operator+2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgncMqi5qC_p0OEruXWj1oE51JoPm05BGWsW0eV4BPHAHq7b3yeCz_KSubnACghlGxJQ3ekDaEV_whLQZmCLbHrp2U0k5yXQ3wafAXUpN129ARqD1aoTyXy7Ohb94LBJ0gGko6gsAKi67Vb/s1600/%253D%253D+operator+2.PNG" /> </a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So we can see the result is different than what we had before when we were using variables of type <i><b>String</b></i>. The other three ways methods are still returning the same result but the <i><b>== operator</b></i> equality check is now returning <i><b>false </b></i>instead of <i><b>true</b></i> stating that the two strings are not equal contradicting with the fact that they are equal actually and it’s also conflicting with the result of other two methods. </div>
<h2 class="separator" style="clear: both; text-align: left;">
Why is That?</h2>
<div class="separator" style="clear: both; text-align: left;">
The reason behind this is that the <i><b>== operator</b></i> is equivalent to a static method, and a static method cannot be a virtual method, what is actually happening when comparing using <i><b>== operator</b></i> here is that we are trying to compare two variables of type <i><b>Object</b></i>, we know that they are of type <i><b>String </b></i>in actual, but the compiler is not aware of that, and we know that for <b>non-virtual methods</b>, it is decided at compile-time that which implementation needs to be invoked and as the variables have been declared of type <i><b>Object </b></i>the compiler will emit code for comparing instances of type Object and if you navigate the source code for <i><b>Object </b></i>you will see that there is no overload for <i><b>== operator</b></i> for it, so what will happen here is that == operator will do what it always do for comparing two reference types when there is no overload found for that type (i.e. it will check for <b>reference equality</b>) and as these two string objects are separate instances, the reference equality will be evaluated to false saying that the two objects are not equal.</div>
<h2 class="separator" style="clear: both; text-align: left;">
Object Equals Method Should be Preferred</h2>
<div class="separator" style="clear: both; text-align: left;">
The above problem will never come with the other two <b>Equals </b>methods as they are <i><b>virtual </b></i>and the specific type will provide the <i><b>override </b></i>for it and calling them will always call the overridden implementation to correctly evaluate the equality of them, so in the above case overridden methods of <i><b>String </b></i>type will be called.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
For <i><b>static Equals</b></i> method we already discussed in one of the previous posts that it internally calls the same <i><b>virtual Equals</b></i> method, it is just there where we want to avoid <b>NRE (Null Reference Exception) </b>and there is chance that the object on which we will be calling Equals method could be null.<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So in case of inheritance <i><b>Equals</b></i> method overrides should be preferred when checking for equality instead of using <i><b>== operator</b></i>.</div>
<h2 class="separator" style="clear: both; text-align: left;">
== Operator and Reference Equals</h2>
<div class="separator" style="clear: both; text-align: left;">
Another thing to note is that casting the operands of equality operator to object before comparing will always give the same result as calling the <i><b>ReferenceEquals </b></i>method. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Some developers write that way to check for reference equality. We should be careful when doing reference equality that way because someone else reading that code in future might not understand or not aware that casting to object causes the comparison to be based of reference.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
But if we explicitly call the <i><b>ReferenceEquals </b></i>method that would clarify the intent that we want to do reference equality and it would clear all the doubts that what the code needs to do.</div>
<h2 class="separator" style="clear: both; text-align: left;">
== Operator and Generics Problem</h2>
<div class="separator" style="clear: both; text-align: left;">
Another reason to avoid the <i><b>== operator</b></i> is if we are using generics in our code. To illustrate that let’s create a simple method which takes two generic parameters of type <b>T </b>and compares to check if both the objects are equal and print the result on the <b>Console</b>, the code for which would be:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<pre class="brush: csharp">static void Equals<T%gt;(T a, T b)
{
Console.WriteLine(a == b);
}
</pre>
<br />
The above example is obviously pretty simple and one can easily tell what it is actually doing. We are using equality operator to compare the two objects of type <b>T</b>, but if you try to build the above example in Visual Studio, it wouldn’t build and a compile time error would come saying:<br />
<h3 style="text-align: center;">
<span style="color: red;">Error CS0019 : Operator '==' cannot be applied to operands of type 'T' and 'T'</span></h3>
<div style="text-align: left;">
The above error we are seeing because the <b>T </b>could be any type, it can be a reference type or a value type or a primitive type and there is no guarantee that the type parameter which is being passed provided implementation of <i><b>== operator</b></i> for itself.<br />
<br />
In<b> C# generics</b> there is no way to apply a constraint on the generic type or method which could force the past type parameter to provide the overload implementation of the<i><b> == operator</b></i>, we can make the above code build successfully by putting the class constraint on type <b>T</b> like:</div>
<br />
<pre class="brush: csharp">static void Equals<t>(T a, T b) where T : class
{
Console.WriteLine(a == b);
}
</pre>
</div>
<br />
So we have put a constraint on generic type <b>T </b>to be a reference type due to which we are now able to compile the code successfully, as <i><b>== operator</b></i> can always be used on reference types with no problems and it will check for reference equality of two objects of reference type.<br />
<h2 style="text-align: left;">
Temporary Solution</h2>
<div style="text-align: left;">
We are able to build the code now, but there is problem because what if we need to pass value type parameters on primitive types to the generic <i><b>Equals </b></i>method, that we will not be able to do as we had put the restriction to this method to only be called for reference types.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Let’s write some code in the main method which would create two identical strings as we did couple of times in previous posts as well:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">class Program
{
static void Main(string[] args)
{
Object str = "Ehsan Sajjad";
Object str1 = string.Copy((string)str);
Equals(str, str1);
}
static void Equals<T>(T a, T b) where T : class
{
Console.WriteLine(a == b);
}
}
</pre>
</div>
<br />
So guess what would be the output of the above code when we run it, it will evaluate the two strings to be equal or not? If we recall what we saw before was that for <i><b>String </b></i>type the<i><b> == operator</b></i> overload defined by String compares the values of the objects, so the above should print true on the <b>Console</b>, but it we run the code we will see the opposite result that it printed false:<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTeqWHb1fzF46WmmRPTD-PLOxSjiBUsNYpPzCW7JFGBWYYNgymEaR2kMdvZh0aMnL7rwS9Mat3ADj-K3R6avw_zF78Yv1QtO-72JY3P30BFbwVUaMjNp3p9H146c6Al5692lyigGsEpBD4/s1600/%253D%253D+operator+3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTeqWHb1fzF46WmmRPTD-PLOxSjiBUsNYpPzCW7JFGBWYYNgymEaR2kMdvZh0aMnL7rwS9Mat3ADj-K3R6avw_zF78Yv1QtO-72JY3P30BFbwVUaMjNp3p9H146c6Al5692lyigGsEpBD4/s1600/%253D%253D+operator+3.PNG" /> </a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So, the above code has given us unexpected result, we were expecting True to be printed on <b>Console</b>. The question which comes in mind instantly is because why it is evaluating to false, it looks like the <i><b>== operator </b></i>is checking the two objects for <b>Reference Equality</b> instead of <b>Value Equality</b>, but the question is why it is doing reference equality.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
This is happening because even though the compiler knows that it can apply <i><b>== operator</b></i> to whatever the type <i><b>T </b></i>being passed, In the above case <i><b>String </b></i>and it has <i><b>== operator</b></i> overload, but compiler does not know that whether the generic type which is being used when using the method overloads the <i><b>== operator</b></i> or not, so it assumes that <b>T </b>wouldn't overload it and it compiles the code considering that the <i><b>== operator</b></i> is called on instances of type <i><b>Object </b></i>which clearly happened that it checked for <b>Reference Equality</b>.<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<div class="separator" style="clear: both; text-align: left;">
This is very important to keep in mind when using <i><b>== operator</b></i> with generics. The <i><b>== operator</b></i> will not use the equality operator overload defined by the type <b>T </b>and it will consider it as <i><b>Object</b></i>.</div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<h2 style="text-align: left;">
Again Object.Equals to Rescue</h2>
<div style="text-align: left;">
Now let’s change our generic method to use Equals method instead of equality operator which would be:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">static void Equals<t>(T a, T b)
{
Console.WriteLine(object.Equals(a,b));
}
</pre>
</div>
<br />
We have removed the <b>class </b>constraint as <i><b>Object.Equals</b></i> can be called on any type and we are using the static method for the same reason that if one of the parameter is passed null our code wouldn’t fail and will work as expected, and now this method will work for both value types and reference types.<br />
<br />
Now if we run the code again we will see that it printed the result as expected because the <i><b>object.Equals</b></i> will call the appropriate overridden implementation of <i><b>Equals </b></i>method at run-time as static method will call the <i><b>virtual Equals</b></i> method and we see the expected result <b>True </b>as both string values are equal.<br />
<h2 style="text-align: left;">
Summary</h2>
<ul style="text-align: left;">
<li><i><b>== Operator</b></i> doesn’t work well with Inheritance and might give you unexpected result when used with inheritance because the<i><b> == operator</b></i> is not <i><b>virtual</b></i>, so wherever possible <i><b>virtual Equals</b></i> or <i><b>static Equals</b></i> methods should be preferred.</li>
<li><i><b>== Operator</b></i> also doesn’t work as expected when used in Generic class or methods and <b>Equals</b> method should be used with generic to avoid unexpected behavior in the program.</li>
</ul>
<div style="text-align: left;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div style="text-align: right;">
<br /></div>
<br /></div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-88099541456744855712017-02-08T13:11:00.000-08:002017-03-22T00:45:53.313-07:00GridView with Server Side Advanced Search Implementation using JQuery DataTables in ASP.NET MVC 5<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<br />
<div dir="ltr" style="text-align: left;" trbidi="on">
<h4 style="text-align: left;">
<a href="https://code.msdn.microsoft.com/How-to-implement-Advanced-84ce58e8">Download Source Code</a></h4>
<h2 style="text-align: left;">
Background:</h2>
<div style="text-align: left;">
In the last two posts about implementing GridView in asp.net mvc, we talked how we can create a grid like we had in asp.net webforms using JQuery DataTables plugin, then in the second post we saw that how we can enhance the performance of our gird by implementing the sorting, searching and paging, as in the first post we implemented a gird but the problem was all rows were getting rendered on the page as html when page is first time loaded and filtering, paging and sorting was being done on the client side and handled by the datables plugin.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
If you are interested to read those, you can find both of those post here:</div>
<div style="text-align: left;">
<br /></div>
<ul style="text-align: left;">
<li><a href="http://developmentpassion.blogspot.nl/2016/07/beginners-guide-for-creating-gridview.html">Beginners Guide for Creating GridView in ASP.NET MVC 5</a> </li>
<li><a href="http://developmentpassion.blogspot.nl/2016/08/grid-view-with-server-side-filtering.html">Grid View with Server Side Filtering, Sorting and Paging in ASP.NET MVC 5 </a></li>
</ul>
I hope that after reading previous posts on grid in asp.net mvc you are now in better position to create a grid view in asp.net mvc which is for most of the beginners a difficult thing especially for those who come from the web forms development experience.<br />
<h2 style="text-align: left;">
Introduction </h2>
<div style="text-align: left;">
In this post we will see that how we can add Advanced Search on our GridView, so that user gets more user friendly search experience while searching for data in the grid.<br />
<br />
We won’t be repeating the steps from the previous which we have done already which includes database creation and inserting sample data, setting up a new web application project with the required nuget packages, if you are directly reading this, you might want to take a look on at least the last post about server side filtering to get familiar with what we are doing, so as being said, we will be reusing the same project and code and will continue adding the new portion to it. </div>
<div style="text-align: left;">
At the end of previous article we had a working grid with server side pagination, filtering and sorting and after implementing the Advanced Search feature in the grid our application will look like:</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtiH3iOD7ZGxe9lVAdFrYu48kY1qCstsQ5NLGkHYLpZQhOmILmSfMGr-VEWwyBph7pdUIXYPlLFtyxZJdbfhBaOQeiyjKa0xhxul47KMDlEcd2_BWnXy-nTer60ALLPOZyno37fHyXuv45/s1600/Image_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtiH3iOD7ZGxe9lVAdFrYu48kY1qCstsQ5NLGkHYLpZQhOmILmSfMGr-VEWwyBph7pdUIXYPlLFtyxZJdbfhBaOQeiyjKa0xhxul47KMDlEcd2_BWnXy-nTer60ALLPOZyno37fHyXuv45/s1600/Image_1.png" /></a></div>
<div style="text-align: left;">
<br /></div>
<h2 style="text-align: left;">
Step 1 - Database Creation</h2>
<div style="text-align: left;">
We saw in previous posts that we had just one Assets table that we were using to display records in the Gird and we had all the data in just one table in De-normalized form, so we have normalized one of the column of Assets table and created a Lookup table named <b>FacilitySites </b>to demonstrate how advanced search can be implemented using datatables on server side, normalization is also done mostly to avoid data duplication so that instead of repeating same value in multiple rows we store it as a row in another table and just reference the unique identifier in the other table.<br />
Following is the script which can be used to create database:</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<br />
<pre class="brush: sql">CREATE DATABASE [AdvancedSearchGridExampleMVC]
GO
CREATE TABLE [dbo].[FacilitySites] (
[FacilitySiteID] UNIQUEIDENTIFIER NOT NULL,
[FacilityName] NVARCHAR (MAX) NULL,
[IsActive] BIT NOT NULL,
[CreatedBy] UNIQUEIDENTIFIER NOT NULL,
[CreatedAt] DATETIME NOT NULL,
[ModifiedBy] UNIQUEIDENTIFIER NULL,
[ModifiedAt] DATETIME NULL,
[IsDeleted] BIT NOT NULL
);
GO
CREATE TABLE [dbo].[Assets] (
[AssetID] UNIQUEIDENTIFIER NOT NULL,
[Barcode] NVARCHAR (MAX) NULL,
[SerialNumber] NVARCHAR (MAX) NULL,
[PMGuide] NVARCHAR (MAX) NULL,
[AstID] NVARCHAR (MAX) NOT NULL,
[ChildAsset] NVARCHAR (MAX) NULL,
[GeneralAssetDescription] NVARCHAR (MAX) NULL,
[SecondaryAssetDescription] NVARCHAR (MAX) NULL,
[Quantity] INT NOT NULL,
[Manufacturer] NVARCHAR (MAX) NULL,
[ModelNumber] NVARCHAR (MAX) NULL,
[Building] NVARCHAR (MAX) NULL,
[Floor] NVARCHAR (MAX) NULL,
[Corridor] NVARCHAR (MAX) NULL,
[RoomNo] NVARCHAR (MAX) NULL,
[MERNo] NVARCHAR (MAX) NULL,
[EquipSystem] NVARCHAR (MAX) NULL,
[Comments] NVARCHAR (MAX) NULL,
[Issued] BIT NOT NULL,
[FacilitySiteID] UNIQUEIDENTIFIER NOT NULL
);
GO
CREATE NONCLUSTERED INDEX [IX_FacilitySiteID]
ON [dbo].[Assets]([FacilitySiteID] ASC);
GO
ALTER TABLE [dbo].[Assets]
ADD CONSTRAINT [PK_dbo.Assets] PRIMARY KEY CLUSTERED ([AssetID] ASC);
GO
ALTER TABLE [dbo].[Assets]
ADD CONSTRAINT [FK_dbo.Assets_dbo.FacilitySites_FacilitySiteID] FOREIGN KEY ([FacilitySiteID]) REFERENCES [dbo].[FacilitySites] ([FacilitySiteID]) ON DELETE CASCADE;
GO
</pre>
</div>
<br />
<div style="text-align: left;">
If database gets created successfully which will of course after that we need to dump some records in the table so that when we query from the application we could have something displaying on the page to see if the things are working correctly. So following is the script for that:<br />
<br />
<pre class="brush: sql">INSERT INTO [dbo].[FacilitySites] ([FacilitySiteID], [FacilityName], [IsActive], [CreatedBy], [CreatedAt], [ModifiedBy], [ModifiedAt], [IsDeleted]) VALUES (N'526fa0d5-1872-e611-b10e-005056c00008', N'FOR', 1, N'8de72a70-6a35-4658-ae0d-ca3cc55da752', N'2016-09-04 01:56:08', NULL, NULL, 0)
INSERT INTO [dbo].[FacilitySites] ([FacilitySiteID], [FacilityName], [IsActive], [CreatedBy], [CreatedAt], [ModifiedBy], [ModifiedAt], [IsDeleted]) VALUES (N'536fa0d5-1872-e611-b10e-005056c00008', N'Pryco', 1, N'8de72a70-6a35-4658-ae0d-ca3cc55da752', N'2016-09-04 01:56:08', NULL, NULL, 0)
INSERT INTO [dbo].[FacilitySites] ([FacilitySiteID], [FacilityName], [IsActive], [CreatedBy], [CreatedAt], [ModifiedBy], [ModifiedAt], [IsDeleted]) VALUES (N'546fa0d5-1872-e611-b10e-005056c00008', N'6rt', 1, N'8de72a70-6a35-4658-ae0d-ca3cc55da752', N'2016-09-04 01:56:08', NULL, NULL, 0)
GO
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'd37cc16b-3d13-4eba-8c98-0008b409a77b', N'D04-056', N'N/A', N'D-04', N'D04-056', N'N/A', N'DOOR, HYDR/ELEC/PNEUM OPERATED', N'N/A', 1, N'KM', N'N/A', N'South', N'7', N'E', N'019', N'', N'', N'Swing', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'7be68b37-5ec3-4a8b-be48-00490049f66b', N'C06-114', N'N/A', N'C-06', N'C06-114', N'A11-13,C08-16', N'CONTROLS, CENTRAL SYSTEM, HVAC', N'N/A', 1, N'N/A', N'N/A', N'South', N'9', N'F', N'004', N'MER5 ', N'AC-SE-2', N'rtn damper', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'e8a8af59-a863-4757-93bd-00561f36122b', N'C03-069', N'N/A', N'C-03', N'C03-069', N'', N'COILS, REHEAT/PREHEAT (REMOTE)', N'N/A', 1, N'N/A', N'N/A', N'North', N'4', N'A', N'222', N'', N' RH-N-17', N'', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'69dcdb07-8f60-4bbf-ad05-0078f3902c48', N'D06-300', N'N/A', N'D-06', N'D06-300', N'', N'DRAIN, AREAWAY/DRIVEWAY/STORM', N'N/A', 1, N'N/A', N'N/A', N'South', N'Exterior', N'', N'1s0?', N'SB areaway 1st', N'', N'', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'5b229566-5226-4e48-a6c7-008d435f81ae', N'A05-46', N'N/A', N'A-05', N'A05-46', N'', N'Air Conditioning Machine, Split System Chilled Water Coils', N'10 Tons and Under', 1, N'Trane', N'N/A', N'South', N'1', N'G', N'022', N'Headquarter Protective Force', N'', N'Above Ceilg', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'108d1792-7aa1-4865-a3d3-00a0ea973aa3', N'C06-252', N'N/A', N'C-06', N'C06-252', N'F27-35,C08-33', N'CONTROLS, CENTRAL SYSTEM, HVAC', N'N/A', 1, N'N/A', N'N/A', N'South', N'9', N'F', N'004', N'MER5 ', N'E-SE-1', N'exh damper', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'80b9e4f9-71a4-4bd6-85c1-00a404cfee2b', N'D06-409', N'N/A', N'D-06', N'D06-409', N'', N'DRAIN, AREAWAY/DRIVEWAY/STORM', N'N/A', 1, N'N/A', N'N/A', N'North', N'Exterior', N'', N'eas0?', N'NB lawn east', N'', N'', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'bdad32e0-9c21-4451-8cc9-00b47b155eb9', N'D04-182', N'N/A', N'D-04', N'D04-182', N'N/A', N'DOOR, HYDR/ELEC/PNEUM OPERATED', N'N/A', 1, N'N/A', N'N/A', N'South', N'2', N'E', N'2E-115', N'Bathrooms', N'', N'HYDR/ELEC/PNEUM', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'4d859a1b-10e0-4cb0-96a4-00c164a7237e', N'C03-222', N'N/A', N'C-03', N'C03-222', N'', N'COILS, REHEAT/PREHEAT (REMOTE)', N'N/A', 1, N'N/A', N'N/A', N'West', N'G', N'GJ, GI', N'086,052', N'MER8 ', N'SW-26', N'', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'3df536d8-9f25-40dd-a83f-00c4434ad58e', N'D06-348', N'N/A', N'D-06', N'D06-348', N'', N'DRAIN, AREAWAY/DRIVEWAY/STORM', N'N/A', 1, N'N/A', N'N/A', N'West', N'Exterior', N'', N'2n4?', N'WB areaway 2nd', N'', N'', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'26c671bc-47f1-4d0e-acc6-00cdfb94b67d', N'C06-165', N'N/A', N'C-06', N'C06-165', N'A11-17,C08-22', N'CONTROLS, CENTRAL SYSTEM, HVAC', N'N/A', 1, N'N/A', N'N/A', N'South', N'9', N'F', N'004', N'MER5 ', N'AC-SE-6', N'min OA', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'be09535a-0fb6-4f7b-a74e-00dab4730211', N'D04-034', N'N/A', N'D-04', N'D04-034', N'N/A', N'DOOR, HYDR/ELEC/PNEUM OPERATED', N'N/A', 1, N'Dor-O-Matic, Jr', N'N/A', N'North', N'G', N'A', N'064', N'', N'', N'Swing', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'65a0abaa-75cf-489a-9367-0118486218b9', N'D05-049', N'N/A', N'D-05', N'D05-049', N'N/A', N'DOOR, ENTRANCE, MAIN', N'N/A', 1, N'N/A', N'N/A', N'South', N'G 1st', N'E', N'283', N'Ped Mall east', N'', N'', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
INSERT INTO [dbo].[Assets] ([AssetID], [Barcode], [SerialNumber], [PMGuide], [AstID], [ChildAsset], [GeneralAssetDescription], [SecondaryAssetDescription], [Quantity], [Manufacturer], [ModelNumber], [Building], [Floor], [Corridor], [RoomNo], [MERNo], [EquipSystem], [Comments], [Issued], [FacilitySiteID]) VALUES (N'c0101cf3-d1f1-4d32-a4b5-0135dc54645a', N'C03-046', N'N/A', N'C-03', N'C03-046', N'', N'COILS, REHEAT/PREHEAT (REMOTE)', N'N/A', 1, N'N/A', N'N/A', N'North', N'5', N'A', N'084', N'', N'RH-N-30', N'', 0, N'526fa0d5-1872-e611-b10e-005056c00008')
GO
</pre>
<br />
<h2 style="text-align: left;">
Step - 2 Advanced Search Form Creation</h2>
<div style="text-align: left;">
We will create a new view for our advanced search, which will contains a form with few input HTML controls that will be posted to controller action for filtering the records.<br />
In Solution Explorer, Expand the <b>Views </b>folder, then again expand the <b>Asset </b>folder and open the <b>Index.cshtml</b> file, we will add the html for the Advanced Search button that will appear above the grid. Add the following HTML in the view:</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<br />
<pre class="brush: html"><button type="button" class="btn btn-default btn-md" data-toggle="modal"
data-target="#advancedSearchModal" id="advancedsearch-button">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span> Advanced Search
</button>
</pre>
<br />
If you note we have some new attributes in the button code, you don’t need to worry about that those are for bootstrap modal, as clicking the button will open a Modal dialog, and user would be able to select the search criteria and search for results. The <b>data-toggle="modal"</b> attribute dictates that this button will toggle a Modal Dialog and <b>data-target="#advancedSearchModal"</b> specifies the html element of the page which would be displayed as Modal Dialog.<br />
After adding the above html code in the <b>Index.cshtml</b>, the view will have the following code in it:<br />
<br />
<br />
<pre class="brush: html"><div class="row">
<div class="col-md-12">
<div class="panel panel-primary list-panel" id="list-panel">
<div class="panel-heading list-panel-heading">
<h1 class="panel-title list-panel-title">Assets</h1>
<button type="button" class="btn btn-default btn-md" data-toggle="modal" data-target="#advancedSearchModal" id="advancedsearch-button">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span> Advanced Search
</button>
</div>
<div class="panel-body">
<table id="assets-data-table" class="table table-striped table-bordered" style="width:100%;">
</table>
</div>
</div>
</div>
</div>
@section Scripts
{
<script type="text/javascript">
var assetListVM;
$(function () {
assetListVM = {
dt: null,
init: function () {
dt = $('#assets-data-table').DataTable({
"serverSide": true,
"processing": true,
"ajax": {
"url": "@Url.Action("Get","Asset")"
},
"columns": [
{ "title": "Bar Code", "data": "BarCode", "searchable": true },
{ "title": "Manufacturer", "data": "Manufacturer", "searchable": true },
{ "title": "Model", "data": "ModelNumber", "searchable": true },
{ "title": "Building", "data": "Building", "searchable": true },
{ "title": "Room No", "data": "RoomNo" },
{ "title": "Quantity", "data": "Quantity" }
],
"lengthMenu": [[10, 25, 50, 100], [10, 25, 50, 100]],
});
}
}
// initialize the datatables
assetListVM.init();
});
</script>
}
</pre>
<br />
Our modal popup will finally look like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitGGzAsrsI2gjsnyw-RjIhmskj9vODZUmDPCrpq2aV_WsR60NgJMz-4RTbXRSKD1BSYlK9hNuKrctwwY7MaYCxvss1_cq92NXxylyDRqx99cwd8cMy9trXhk88lVstFb2OOl_vX-9H0LFW/s1600/Image_One.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="481" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitGGzAsrsI2gjsnyw-RjIhmskj9vODZUmDPCrpq2aV_WsR60NgJMz-4RTbXRSKD1BSYlK9hNuKrctwwY7MaYCxvss1_cq92NXxylyDRqx99cwd8cMy9trXhk88lVstFb2OOl_vX-9H0LFW/s640/Image_One.png" width="640" /></a></div>
<br />
<h2 style="text-align: left;">
Step 4 - Adding Models with Entity Framework</h2>
<div style="text-align: left;">
The next step is to create a new Model (<b>DTO</b>) class named <b>FacilitySite </b>which will be used for getting the data from <b>FacilitySites </b>Lookup table which we created above with the database script. So add a new class in the <b>Models </b>folder in Solution Explorer named <b>FacilitySite </b>and following is the code for that:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GridAdvancedSearchMVC.Models
{
public class FacilitySite
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public System.Guid FacilitySiteID { get; set; }
[Display(Name = "Facility-Site")]
public string FacilityName { get; set; }
public bool IsActive { get; set; }
public System.Guid CreatedBy { get; set; }
[Required, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatedAt { get; set; }
public System.Guid? ModifiedBy { get; set; }
public DateTime? ModifiedAt { get; set; }
public bool IsDeleted { get; set; }
}
}
</pre>
<br />
Right now we have just added the Model class which will hold data for <b>FacilitySites </b>table, but as we are using Entity Framework for Data Access purpose, we will have to let it know that there is new table added on which data operations can be performed. For that in <b>Models </b>folder open the <b>IdentityModel.cs file</b> and update the <b>ApplicationDbContext </b>code to include a new property of type <b>DbSet<FacilitySite></b> :<br />
<br />
<pre class="brush: csharp">public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public DbSet<Asset> Assets { get; set; }
public DbSet<FacilitySite> FacilitySites { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
</pre>
<br />
Update the Asset model as well by removing the FacilitySite column which was of type String before and instead add a new column named <b>FacilitySiteId </b>which will be foreign key in <b>Asset </b>table of <b>FacilitySite </b>table, updated Asset model should be:<br />
<br />
<pre class="brush: csharp">using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GridAdvancedSearchMVC.Models
{
public class Asset
{
public System.Guid AssetID { get; set; }
[Display(Name = "Barcode")]
public string Barcode { get; set; }
[Display(Name = "Serial-Number")]
public string SerialNumber { get; set; }
//[Display(Name = "Facility-Site")]
//public string FacilitySite { get; set; }
[ForeignKey("FacilitySite")]
public Guid FacilitySiteID { get; set; }
[Display(Name = "PM-Guide-ID")]
public string PMGuide { get; set; }
[Required]
[Display(Name = "Asset-ID")]
public string AstID { get; set; }
[Display(Name = "Child-Asset")]
public string ChildAsset { get; set; }
[Display(Name = "General-Asset-Description")]
public string GeneralAssetDescription { get; set; }
[Display(Name = "Secondary-Asset-Description")]
public string SecondaryAssetDescription { get; set; }
public int Quantity { get; set; }
[Display(Name = "Manufacturer")]
public string Manufacturer { get; set; }
[Display(Name = "Model-Number")]
public string ModelNumber { get; set; }
[Display(Name = "Main-Location (Building)")]
public string Building { get; set; }
[Display(Name = "Sub-Location 1 (Floor)")]
public string Floor { get; set; }
[Display(Name = "Sub-Location 2 (Corridor)")]
public string Corridor { get; set; }
[Display(Name = "Sub-Location 3 (Room No)")]
public string RoomNo { get; set; }
[Display(Name = "Sub-Location 4 (MER#)")]
public string MERNo { get; set; }
[Display(Name = "Sub-Location 5 (Equip/System)")]
public string EquipSystem { get; set; }
public string Comments { get; set; }
public bool Issued { get; set; }
public virtual FacilitySite FacilitySite { get; set; }
}
}
</pre>
</div>
</div>
</div>
</div>
<br />
<h2 style="text-align: left;">
Step 4 - Creating ViewModel class</h2>
<div style="text-align: left;">
We will also need to create a ViewModel class which will be used for posting the search criteria to server side which will be controller action for performing the search. Let’s add the ViewModel then. Following is the code for the <b>AdvancedSearchViewModel </b>class:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">using System;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace GridExampleMVC.Models
{
public class AdvancedSearchViewModel
{
[Display(Name = "Facility-Site")]
public Guid FacilitySite { get; set; }
[Display(Name = "Main-Location (Building)")]
public string Building { get; set; }
public string Manufacturer { get; set; }
public string Status { get; set; }
public SelectList FacilitySiteList { get; set; }
public SelectList BuildingList { get; set; }
public SelectList ManufacturerList { get; set; }
public SelectList StatusList { get; set; }
}
}
</pre>
</div>
<br />
<div style="text-align: left;">
<h2 style="text-align: left;">
Step 5 - Implement Advanced Search Get Action</h2>
<div style="text-align: left;">
Navigate to <b>Controllers </b>folder and expand it, and open the <b>AssetController.cs </b>file, we will add a new get action that will be used to populate the <b>AdvancedSeachViewModel </b>and we will be setting the <b>SelectList </b>properties with data from their respective data sources for populating the Dropdown List controls on the advanced search modal popup:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">[HttpGet]
public ActionResult AdvancedSearch()
{
var advancedSearchViewModel = new AdvancedSearchViewModel();
advancedSearchViewModel.FacilitySiteList = new SelectList(DbContext.FacilitySites
.Where(facilitySite => facilitySite.IsActive && !facilitySite.IsDeleted)
.Select(x => new { x.FacilitySiteID, x.FacilityName }),
"FacilitySiteID",
"FacilityName");
advancedSearchViewModel.BuildingList = new SelectList(DbContext.Assets
.GroupBy(x => x.Building)
.Where(x => x.Key != null && !x.Key.Equals(string.Empty))
.Select(x => new { Building = x.Key }),
"Building",
"Building");
advancedSearchViewModel.ManufacturerList = new SelectList(DbContext.Assets
.GroupBy(x => x.Manufacturer)
.Where(x => x.Key != null && !x.Key.Equals(string.Empty))
.Select(x => new { Manufacturer = x.Key }),
"Manufacturer",
"Manufacturer");
advancedSearchViewModel.StatusList = new SelectList(new List<SelectListItem>
{
new SelectListItem { Text="Issued",Value=bool.TrueString},
new SelectListItem { Text="Not Issued",Value = bool.FalseString}
},
"Value",
"Text"
);
return View("_AdvancedSearchPartial", advancedSearchViewModel);
}
</pre>
</div>
<br />
<div style="text-align: left;">
<h2 style="text-align: left;">
Step 6 - Advanced Search Post Action Implementation</h2>
<div style="text-align: left;">
Our AdvancedSearch post action will be almost same implementation wise as was the implementation of Search action for Server Side Sort, Filter and Paging one, but there will be small change in action signatures for AdvancedSearch, it will now take 2 parameter which is quite obvious, one for maintain the DataTables state which was already there before as well and the new one will be the instance of <b>AdvancedSearchViewModel </b>class which will have the state of controls of Advanced Search Modal popup.</div>
<div style="text-align: left;">
<br />
We need to update the <b>SearchAssets </b>private method which we created in the previous post about Grid View Server Side Processing, add the advanced searching database logic in this method, so this method will not take another parameter which is we know instance of <b>AdvancedSearchViewModel</b>:</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<br />
<pre class="brush: csharp">private IQueryable<Asset> SearchAssets(IDataTablesRequest requestModel, AdvancedSearchViewModel searchViewModel, IQueryable<Asset> query)
{
// Apply filters
if (requestModel.Search.Value != string.Empty)
{
var value = requestModel.Search.Value.Trim();
query = query.Where(p => p.Barcode.Contains(value) ||
p.Manufacturer.Contains(value) ||
p.ModelNumber.Contains(value) ||
p.Building.Contains(value)
);
}
/***** Advanced Search Starts ******/
if (searchViewModel.FacilitySite != Guid.Empty)
query = query.Where(x => x.FacilitySiteID == searchViewModel.FacilitySite);
if (searchViewModel.Building != null)
query = query.Where(x => x.Building == searchViewModel.Building);
if (searchViewModel.Manufacturer != null)
query = query.Where(x => x.Manufacturer == searchViewModel.Manufacturer);
if (searchViewModel.Status != null)
{
bool Issued = bool.Parse(searchViewModel.Status);
query = query.Where(x => x.Issued == Issued);
}
/***** Advanced Search Ends ******/
var filteredCount = query.Count();
// Sort
var sortedColumns = requestModel.Columns.GetSortedColumns();
var orderByString = String.Empty;
foreach (var column in sortedColumns)
{
orderByString += orderByString != String.Empty ? "," : "";
orderByString += (column.Data) + (column.SortDirection == Column.OrderDirection.Ascendant ? " asc" : " desc");
}
query = query.OrderBy(orderByString == string.Empty ? "BarCode asc" : orderByString);
return query;
}
</pre>
</div>
<br />
<div style="text-align: left;">
<h2 style="text-align: left;">
Step 7 - Updating DataTables Post Call Action</h2>
<div style="text-align: left;">
Now update the action as well which is called for handles the grid server side processing to accept the advanced search parameter as well and pass them to the SearchAssets method for more granular filtering, here is the updated code of the action:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">public ActionResult Get([ModelBinder(typeof(DataTablesBinder))] IDataTablesRequest requestModel, AdvancedSearchViewModel searchViewModel)
{
IQueryable<Asset> query = DbContext.Assets;
var totalCount = query.Count();
// searching and sorting
query = SearchAssets(requestModel, searchViewModel,query);
var filteredCount = query.Count();
// Paging
query = query.Skip(requestModel.Start).Take(requestModel.Length);
var data = query.Select(asset => new
{
AssetID = asset.AssetID,
BarCode = asset.Barcode,
Manufacturer = asset.Manufacturer,
ModelNumber = asset.ModelNumber,
Building = asset.Building,
RoomNo = asset.RoomNo,
Quantity = asset.Quantity
}).ToList();
return Json(new DataTablesResponse(requestModel.Draw, data, filteredCount, totalCount), JsonRequestBehavior.AllowGet);
}
</pre>
</div>
<br />
<div style="text-align: left;">
<h2 style="text-align: left;">
Step 7 - Implement Modal Popup View for Advanced Search</h2>
<div style="text-align: left;">
Now we will move towards the view part, as you can see we have last four properties of type SelectList which are there because we will have few dropdown list controls in the advanced form which user will be selecting from pre-populated values for searching the records. <br />
<br />
The <b><span style="color: red;">data-target</span>=<span style="color: blue;">"#advancedSearchModal"</span></b> which we added in the html of <b>Index.cshtml</b> view will be referenced in this partial view, so create a new partial view under <b>Views >> Asset</b> named _AdvancedSearchPartial, for that right click the Asset folder under View and navigate to <b>Add </b>Item, then from next Menu select <b>MVC 5 Partial Page (Razor)</b> :</div>
<div style="text-align: left;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLVIW3aIFfN9BYpEa9RIaerRj7s3pynONqZJpjJZ6NQ71cTgU4EESBpqBJUP-1QqA1jamf325GWfFZCmUPNV7mw4PCbWdbgWJMI_73GFjJoHs4YXE4fVVbN8TI1fjaTi-lJj5LMlUFUDqO/s1600/Image_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLVIW3aIFfN9BYpEa9RIaerRj7s3pynONqZJpjJZ6NQ71cTgU4EESBpqBJUP-1QqA1jamf325GWfFZCmUPNV7mw4PCbWdbgWJMI_73GFjJoHs4YXE4fVVbN8TI1fjaTi-lJj5LMlUFUDqO/s1600/Image_3.png" /></a></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Type the partial view name which would be <b>_AdvancedSearchPartial</b> in this case and Click the <b>OK</b> button:</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi67LDkIVeADr2Y1GJkRzjcjcOLiCUy_z95DggM6cDDUyVz8jqCqWpX7CpcAKGGb9DF5ieGsZtbxvtNkdlLrmfNEYd4_5uB_R404nYZRxT6jQo-RoB_MeLvOEhpqYsGqcyYurYxF_PLB1p7/s1600/Image_4.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="171" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi67LDkIVeADr2Y1GJkRzjcjcOLiCUy_z95DggM6cDDUyVz8jqCqWpX7CpcAKGGb9DF5ieGsZtbxvtNkdlLrmfNEYd4_5uB_R404nYZRxT6jQo-RoB_MeLvOEhpqYsGqcyYurYxF_PLB1p7/s640/Image_4.PNG" width="640" /></a></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
And then open the file <b>_AdvancedSearchPartial.cshtml</b> and add the html in the partial view that will be displayed as modal popup when the user will click the Advanced Search button that we created in the <b>Index.cshtml</b> view, following the code of the advanced search partial view:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: html">@model TA_UM.ViewModels.AdvancedSearchViewModel
@{
Layout = null;
}
<div class="modal fade" id="advancedSearchModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Advanced Search</h4>
</div>
@using (Html.BeginForm("Get", "Asset", FormMethod.Get, new { id = "frmAdvancedSearch", @class = "form-horizontal", role = "form" }))
{
<div class="modal-body">
<div class="form-horizontal">
<hr />
<div class="form-group">
@Html.LabelFor(model => model.FacilitySite, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-8">
<div class="dropdown">
@Html.DropDownListFor(model => model.FacilitySite, Model.FacilitySiteList, "Any", new { @class = "form-control" })
</div>
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Building, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-8">
<div class="dropdown">
@Html.DropDownListFor(model => model.Building, Model.BuildingList, "Any", new { @class = "form-control" })
</div>
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Manufacturer, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-8">
<div class="dropdown">
@Html.DropDownListFor(model => model.Manufacturer, Model.ManufacturerList, "Any", new { @class = "form-control" })
</div>
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Status, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-8">
<div class="dropdown">
@Html.DropDownListFor(model => model.Status, Model.StatusList, "Both", new { @class = "form-control" })
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button id="btnPerformAdvancedSearch" type="button" class="btn btn-default btn-success" data-dismiss="modal">Search</button>
<button id="btnCancel" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
</div>
</pre>
</div>
<br />
<div style="text-align: left;">
<h2 style="text-align: left;">
Final Step - Pass Advanced Search Parameters from View in POST</h2>
<div style="text-align: left;">
Finally open the <b>Index.cshtml</b> located in <b>Views >> Asset</b> and call the AdvancedSearch get action before the <b><span style="background-color: yellow;">@section Scripts</span></b> start for adding the Advanced Search Modal popup html in the browser which will be displayed when button is triggered, another thing to note is we have not specified anywhere about how the dropdown selected values will be posted with DataTables server side processing in the same action, though we have added the parameter in action but we haven't changed anything specific to that in View, we will have to update the jquery datatables initialization code for that, and specify the values for posting to the <b>AdvancedSearchViewModel </b>using data property for which we would have to define the property, so add the following code just after the line where we are specifying url for datatable which is <b><span style="color: #990000;">"url"</span>: <span style="color: #990000;">"</span><span style="background-color: yellow;">@</span>Url.Action(<span style="color: #990000;">"Get","Asset"</span>)<span style="color: #990000;">"</span></b>, and after adding that final Index view code should be :</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: js">"data": function (data) {
data.FacilitySite = $("#FacilitySite").val();
data.Building = $("#Building").val();
data.Manufacturer = $("#Manufacturer").val();
data.Status = $("#Status").val();
}
</pre>
</div>
<br />
<div style="text-align: left;">
Our Index View would contain following code:
</div>
<br />
<div style="text-align: left;">
<pre class="brush: html"><div class="row">
<div class="col-md-12">
<div class="panel panel-primary list-panel" id="list-panel">
<div class="panel-heading list-panel-heading">
<h1 class="panel-title list-panel-title">Assets</h1>
<button type="button" class="btn btn-default btn-md" data-toggle="modal" data-target="#advancedSearchModal" id="advancedsearch-button">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span> Advanced Search
</button>
</div>
<div class="panel-body">
<table id="assets-data-table" class="table table-striped table-bordered" style="width:100%;">
</table>
</div>
</div>
</div>
</div>
@Html.Action("AdvancedSearch")
@section Scripts
{
<script type="text/javascript">
var assetListVM;
$(function () {
assetListVM = {
dt: null,
init: function () {
dt = $('#assets-data-table').DataTable({
"serverSide": true,
"processing": true,
"ajax": {
"url": "@Url.Action("Get","Asset")",
"data": function (data) {
data.FacilitySite = $("#FacilitySite").val();
data.Building = $("#Building").val();
data.Manufacturer = $("#Manufacturer").val();
data.Status = $("#Status").val();
}
},
"columns": [
{ "title": "Bar Code", "data": "BarCode", "searchable": true },
{ "title": "Manufacturer", "data": "Manufacturer", "searchable": true },
{ "title": "Model", "data": "ModelNumber", "searchable": true },
{ "title": "Building", "data": "Building", "searchable": true },
{ "title": "Room No", "data": "RoomNo" },
{ "title": "Quantity", "data": "Quantity" }
],
"lengthMenu": [[10, 25, 50, 100], [10, 25, 50, 100]],
});
},
refresh: function () {
dt.ajax.reload();
}
}
// Advanced Search Modal Search button click handler
$('#btnPerformAdvancedSearch').on("click", assetListVM.refresh);
}
// initialize the datatables
assetListVM.init();
});
</script>
}
</pre>
</div>
<br />
<div style="text-align: left;">
You can see above we have add a new function in our datatable view model named refresh, whose purpose is to reload the datatable from server side using the model of DataTables, we have wrote the event handler for Advanced Search Popup button that when it is pressed it causes the datatable to be reloaded and in the ajax call of it we are passing the user selected search criteria from advanced search view as well using that data property of jQuery datatables.<br />
<br />
Now build the project, and run it in browse to see the working server side Advanced Search using JQuery datatables and with server side filtering, paging, and sorting as well in action. <br />
<br />
<h2 style="text-align: left;">
Source Code</h2>
<div>
You can download the source code from <a href="https://code.msdn.microsoft.com/How-to-implement-Advanced-84ce58e8">MSDN code samples gallery here</a></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-15454075857709889142017-01-15T13:21:00.001-08:002017-01-22T07:18:05.315-08:00Equality Operator (==) and Value Types in C#<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<h2 style="text-align: left;">
Background</h2>
<div style="text-align: left;">
This article is in the continuation of series of articles regarding how Equality works in .Net, the purpose is to have the developers more clear understanding on how .Net handles equality for different types. We have already seen equality for primitive types, reference types works, we also discussed separately how equality works differently for <b>String </b>type. Following are some points which we were able to understand until now.</div>
<h2 style="text-align: left;">
Key Points Learned So Far</h2>
<ul style="text-align: left;">
<li>By default the <b><i>virtual</i> Object.Equals</b> method does reference equality for reference types and value equality for value types, but for value types it uses reflection which is a performance overhead for value types and any type can <i><b>override</b></i> <b>Object.Equals</b> method to change the logic of how it checks for equality <b>e.g. String, Delegate</b> and <b>Tuple </b>do this for providing value equality, even though these are reference types.</li>
<li><b>Object </b>class also provides a <i><b>static </b></i><b>Equals</b> method which can be used when there is chance that one or both of the parameters can be <i><b>null</b></i>, other than that it behaves identical to the <i><b>virtual</b></i> <b>Object.Equals</b> method.</li>
<li>There is also a <b><i>static</i> ReferenceEquals</b> method which provides a guaranteed way to check for reference equality.</li>
<li><b>IEquatable<T></b> interface can be implemented on a type to provide a strongly typed <b>Equals</b> method which also avoids boxing for value types. It is implemented for primitive numeric types but unfortunately Microsoft has not been very proactive implementing for other value types in the <b>FCL( Framework Class Library )</b>.</li>
<li>For <b>Value Types</b> using <b>== operator</b> gives us the same result as calling <b>Object.Equals</b> but underlying mechanism of <b>== operator </b>is different in<b> IL( Intermediate Language )</b> as compared to <b>Object.Equals</b>, so the <b>Object.Equals</b> implementation provided for that primitive type is not called, instead an <b>IL </b>instruction <a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ceq(v=vs.110).aspx"><b>ceq </b></a>gets called which says that compare the two values that are being loaded on the stack right now and perform equality comparison using CPU registers.</li>
<li>For <b>Reference Types</b>, <b>== operator</b> and <b>Object.Equals</b> method call both work differently behind the scenes which can be verified by inspecting the IL code generated. It also uses <b>ceq</b> instruction which do the comparison of memory addresses.</li>
</ul>
If the above points does not makes sense to you, it would be better to read it from the start, following are the links to the previous content related to it:<br />
<br />
<ul style="text-align: left;">
<li><a href="http://developmentpassion.blogspot.com/2016/06/story-of-complex-equality-in-net.html">Story of Equality in .Net – Part 1</a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/06/story-of-equality-in-net-part-2.html">Story of Equality in .Net – Part 2</a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-3.html">Story of Equality in .Net – Part 3</a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-4.html">Story of Equality in .Net – Part 4</a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/08/story-of-equality-in-net-part-5.html">Story of Equality in .Net – Part 5</a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/10/story-of-equality-in-net-part-6.html">Story of Equality in .Net – Part 6</a> </li>
</ul>
<h2 style="text-align: left;">
Equality Operator for Value Types </h2>
<div style="text-align: left;">
We have already learned that what the Equality operator does for both the primitive types and reference types. One case that we haven’t tested yet is that what happens for the non-primitive value types. This time we will be focusing on the value types.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
We will be using the same example that we used before, so we will declare a <b>Person </b>type as <b>struct</b> and we will compare two instances to see if they are equal not using <b>Object.Equals</b> method which we did previously and we know that it does the value comparison which is very in-efficient as for value types it uses reflection to iterate through the fields and check for equality of each one, but instead we will compare two <b>Person </b>type<b> </b>objects using the <b>== operator</b>.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
The Person type definition looks like:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">public struct Person
{
private string _name;
public string Name
{
get
{
return _name;
}
}
public Person(string name)
{
_name = name;
}
public override string ToString()
{
return _name;
}
}
</pre>
</div>
<br />
If we write the following code in Main and build the project, what will we see:<br />
<br />
<pre class="brush: csharp">class Program
{
static void Main(String[] args)
{
Person p1 = new Person("Ehsan Sajjad");
Person p2 = new Person("Ehsan Sajjad");
Console.WriteLine(p1.Equals(p2));
Console.WriteLine(p1 == p2);
Console.ReadKey();
}
}
</pre>
<br />
When we try to build the above program, the first line where we are comparing p1 and p2 using Equals method will have no problem, but the build fails on line 2 where we are using == operator with the following error message:<br />
<br />
<blockquote class="tr_bq">
<span style="color: red;"><b>Operator ‘==’ cannot be applied to operands of type `Person` and `Person`</b></span></blockquote>
So the above makes one thing clear to us that the Equality operator does nothing for the non-primitive value types, for using the equality operator for non-primitive value types we need to provide an operator overload for the type.<br />
<br />
Let’s modify the above example to add the equality operator overload for the Person struct, we will be now specifying what the == operator should do for two Person objects being compared, following is the syntax to provide the overload for == operator if we want to provide the implementation so that what the operator should do when used for two objects of type Person:<br />
<br />
<pre class="brush: csharp">public static bool operator ==(Person p1, Person p2)
{
}
</pre>
<br />
After adding the above code in the Person struct we would be able to compile the code written in Main method of Program, but note that this would not compile still as the overload has return type bool as per signatures but we are returning nothing, this is just to give idea how to write == operator overloaded implementation for a user defined Value Type.<br />
<br />
We saw in one of the previous posts that <b>String </b>overloads the equality operator to make sure that it does the same thing as <b>Equals </b>method, so whenever you are defining a new type make sure that it does the same thing with both the method and the operator, if we provide either of them it is generally a good thing to do. Following is an example code that will help us understand why it is a good practice:<br />
<br />
<pre class="brush: csharp">class Program
{
static void Main(string[] args)
{
Tuple<int int=""> tuple1 = Tuple.Create(1, 2);
Tuple<int int=""> tuple2 = Tuple.Create(1, 2);
Console.WriteLine(ReferenceEquals(tuple1, tuple2));
Console.WriteLine(tuple1.Equals(tuple2));
Console.WriteLine(tuple1 == tuple2);
Console.Read();
}
</int></int></pre>
<br />
As you can see we are instantiating two tuples containing same values i.e. <b>1</b> and <b>2</b>, Tuple is a generic class which comes within Framework Class Libraries provided by Microsoft which simply provides a way to group couple of values together in a single object. The <b>Tuple.Create(1, 2);</b> is a nicer way to instantiate a new tuple saving developer to explicitly write the generic types in the code.<br />
<br />
Now we are comparing the tuples to see if they are equal or not, Tuple is a reference type, so we are checking equality using ReferenceEquals check to confirm that we are dealing with two separate instances, next we are comparing if they are equal using the Equals method, and lastly we are comparing using equality operator aka == operator, Let’s run this program and following is the output of the above program:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFak__-q15bgmFSSBMXXb5qeyVjqBasi1EbyhBNvQ4JreOAbj_o1a7MnDarIPft6mxy16A2LNbnzNk5eB80dtSEFiAa3PaYRsfWzv4zYo9fD5etdGggh0i8FoeI8p_sqLw1-pU7xa2iINp/s1600/pic1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFak__-q15bgmFSSBMXXb5qeyVjqBasi1EbyhBNvQ4JreOAbj_o1a7MnDarIPft6mxy16A2LNbnzNk5eB80dtSEFiAa3PaYRsfWzv4zYo9fD5etdGggh0i8FoeI8p_sqLw1-pU7xa2iINp/s1600/pic1.png" /></a></div>
<br />
For some of you the result might be a surprise, we can see that <b>ReferenceEquals </b>has returned <b>false</b> which means that both are different instances, but the <b>== operator </b>and <b>Equals </b>method have returned the opposite result, the <b>== operator</b> says that both are not equal while the <b>Equals </b>method is saying that they are equal.<br />
<br />
What’s actually happening above is that Tuple overrides the <b>Equals </b>method in a way that it checks for value equality for the objects. Microsoft figured that when you are dealing with a type whose purpose is just to encapsulate couple of fields that is probably what you want equality to mean, so as the two Tuple instances have the same value the <b>Equals </b>method says that they are equal, but <b>Microsoft </b>didn’t provided the overload for<b> == operator </b>and that means that <b>== operator</b> has just done what it is meant to be doing and will always do for reference type that does not provide an overload and checks reference equality and has returned <b>False </b>in this case as both are different instances.<br />
<br />
I am pretty sure that has confused you, of course the behavior is confusing and it did confuse me as well when I was digging in to it. Almost no one is going to expect this kind of behavior and it is strongly recommended to not add this kind of behavior is any type we define.<br />
<br />
If you <i><b>override </b></i>the Equality then it is much better to provide the<b> == operator</b> overload to make sure that method and the operator always gives the same result and if you implement the <b>IEquatable<T> </b>interface then you should do same for that as well.<br />
<h2 style="text-align: left;">
<br /></h2>
<h2 style="text-align: left;">
Comparison of == Operator and Object.Equals Method</h2>
<div style="text-align: left;">
<!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:RelyOnVML/>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]--></div>
<div style="text-align: left;">
<!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:TrackMoves/>
<w:TrackFormatting/>
<w:PunctuationKerning/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>EN-US</w:LidThemeOther>
<w:LidThemeAsian>X-NONE</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:EnableOpenTypeKerning/>
<w:DontFlipMirrorIndents/>
<w:OverrideTableStyleHps/>
</w:Compatibility>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="--"/>
<m:smallFrac m:val="off"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="false"
DefSemiHidden="false" DefQFormat="false" DefPriority="99"
LatentStyleCount="371">
<w:LsdException Locked="false" Priority="0" QFormat="true" Name="Normal"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 1"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 2"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 3"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 4"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 5"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 6"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 7"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 8"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 9"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 9"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 1"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 2"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 3"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 4"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 5"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 6"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 7"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 8"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 9"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Normal Indent"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="footnote text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="annotation text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="header"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="footer"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index heading"/>
<w:LsdException Locked="false" Priority="35" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="caption"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="table of figures"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="envelope address"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="envelope return"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="footnote reference"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="annotation reference"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="line number"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="page number"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="endnote reference"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="endnote text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="table of authorities"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="macro"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="toa heading"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Bullet"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Number"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Bullet 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Bullet 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Bullet 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Bullet 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Number 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Number 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Number 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Number 5"/>
<w:LsdException Locked="false" Priority="10" QFormat="true" Name="Title"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Closing"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Signature"/>
<w:LsdException Locked="false" Priority="1" SemiHidden="true"
UnhideWhenUsed="true" Name="Default Paragraph Font"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text Indent"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Continue"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Continue 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Continue 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Continue 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Continue 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Message Header"/>
<w:LsdException Locked="false" Priority="11" QFormat="true" Name="Subtitle"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Salutation"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Date"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text First Indent"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text First Indent 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Note Heading"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text Indent 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text Indent 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Block Text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Hyperlink"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="FollowedHyperlink"/>
<w:LsdException Locked="false" Priority="22" QFormat="true" Name="Strong"/>
<w:LsdException Locked="false" Priority="20" QFormat="true" Name="Emphasis"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Document Map"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Plain Text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="E-mail Signature"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Top of Form"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Bottom of Form"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Normal (Web)"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Acronym"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Address"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Cite"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Code"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Definition"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Keyboard"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Preformatted"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Sample"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Typewriter"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Variable"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Normal Table"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="annotation subject"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="No List"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Outline List 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Outline List 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Outline List 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Simple 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Simple 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Simple 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Classic 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Classic 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Classic 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Classic 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Colorful 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Colorful 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Colorful 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Columns 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Columns 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Columns 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Columns 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Columns 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table 3D effects 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table 3D effects 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table 3D effects 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Contemporary"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Elegant"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Professional"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Subtle 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Subtle 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Web 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Web 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Web 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Balloon Text"/>
<w:LsdException Locked="false" Priority="39" Name="Table Grid"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Theme"/>
<w:LsdException Locked="false" SemiHidden="true" Name="Placeholder Text"/>
<w:LsdException Locked="false" Priority="1" QFormat="true" Name="No Spacing"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading"/>
<w:LsdException Locked="false" Priority="61" Name="Light List"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 1"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 1"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 1"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 1"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 1"/>
<w:LsdException Locked="false" SemiHidden="true" Name="Revision"/>
<w:LsdException Locked="false" Priority="34" QFormat="true"
Name="List Paragraph"/>
<w:LsdException Locked="false" Priority="29" QFormat="true" Name="Quote"/>
<w:LsdException Locked="false" Priority="30" QFormat="true"
Name="Intense Quote"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 1"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 1"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 1"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 1"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 1"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 1"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 1"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 2"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 2"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 2"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 2"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 2"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 2"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 2"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 2"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 2"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 2"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 2"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 3"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 3"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 3"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 3"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 3"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 3"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 3"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 3"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 3"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 3"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 3"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 3"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 3"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 4"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 4"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 4"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 4"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 4"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 4"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 4"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 4"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 4"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 4"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 4"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 4"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 4"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 4"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 5"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 5"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 5"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 5"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 5"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 5"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 5"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 5"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 5"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 5"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 5"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 5"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 5"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 5"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 6"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 6"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 6"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 6"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 6"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 6"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 6"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 6"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 6"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 6"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 6"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 6"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 6"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 6"/>
<w:LsdException Locked="false" Priority="19" QFormat="true"
Name="Subtle Emphasis"/>
<w:LsdException Locked="false" Priority="21" QFormat="true"
Name="Intense Emphasis"/>
<w:LsdException Locked="false" Priority="31" QFormat="true"
Name="Subtle Reference"/>
<w:LsdException Locked="false" Priority="32" QFormat="true"
Name="Intense Reference"/>
<w:LsdException Locked="false" Priority="33" QFormat="true" Name="Book Title"/>
<w:LsdException Locked="false" Priority="37" SemiHidden="true"
UnhideWhenUsed="true" Name="Bibliography"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="TOC Heading"/>
<w:LsdException Locked="false" Priority="41" Name="Plain Table 1"/>
<w:LsdException Locked="false" Priority="42" Name="Plain Table 2"/>
<w:LsdException Locked="false" Priority="43" Name="Plain Table 3"/>
<w:LsdException Locked="false" Priority="44" Name="Plain Table 4"/>
<w:LsdException Locked="false" Priority="45" Name="Plain Table 5"/>
<w:LsdException Locked="false" Priority="40" Name="Grid Table Light"/>
<w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark"/>
<w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful"/>
<w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 1"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 1"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 1"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 1"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 1"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 2"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 2"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 2"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 2"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 2"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 3"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 3"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 3"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 3"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 3"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 4"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 4"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 4"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 4"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 4"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 5"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 5"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 5"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 5"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 5"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 6"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 6"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 6"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 6"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 6"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 6"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 6"/>
<w:LsdException Locked="false" Priority="46" Name="List Table 1 Light"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark"/>
<w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful"/>
<w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 1"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 1"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 1"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 1"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 1"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 2"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 2"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 2"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 2"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 2"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 3"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 3"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 3"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 3"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 3"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 4"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 4"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 4"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 4"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 4"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 5"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 5"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 5"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 5"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 5"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 6"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 6"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 6"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 6"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 6"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 6"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 6"/>
</w:LatentStyles>
</xml><![endif]--><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin-top:0in;
mso-para-margin-right:0in;
mso-para-margin-bottom:8.0pt;
mso-para-margin-left:0in;
line-height:107%;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family:"Calibri",sans-serif;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;}
</style>
<![endif]-->
</div>
<div class="MsoNormal">
Finally let’s quickly see how the == operator and Equals method
differ as far as their behavior is concerned:</div>
<br />
<ul style="text-align: left;">
<li>For Primitive Types <b>e.g.</b> <b>int</b>, <b>float</b>, <b>long</b>, <b>bool</b> etc both the <b>== operator</b> and <b>Object.Equals </b>method will compare the values i.e. 1 is equal to but 1, but 1 is not equal to 0 </li>
<li>For most of the <b>Reference Types</b> both the <b>== operator</b> and <b>Object.Equals</b> method will by default compare the references, you can modify this behavior by overloading the == operator or overriding the Object.Equals method but if you want the behavior of both to be consistent and don’t want to surprise other developers and yourself you must do the both (overload == operator and override the Equals method).</li>
<li>For Non-primitive Value Types the Object.Equals method will do the value equality using Refection which is slow and this is overridden behavior of course, but the equality operator is by default not available for value types unless you overload the == operator for that type which we saw in the example above.</li>
<li>There is also another minor difference that for reference types the virtual Equals method cannot work if the first parameter is null but that is trivial, as a workaround the static Equals method can be used which takes both the objects to be compared as parameter </li>
</ul>
<h2 style="text-align: left;">
Summary</h2>
<div style="text-align: left;">
So after all the above points and discussion we can conclude that a lot of the time the operator and the method gives the same result in practice, but since the syntax of the operator is so much convenient that developers most of the time prefer the operator. In the next post we will be discussing what are the situations where == operator might not be the preferable but instead Equals method would be preferable. </div>
<div style="text-align: left;">
</div>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com1tag:blogger.com,1999:blog-5386436084600983822.post-11406393509541940142016-10-02T04:31:00.000-07:002016-10-02T10:19:05.278-07:00Story of Equality in .Net - Part 6<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<h2 style="text-align: left;">
Background:</h2>
<div>
This article is in the continuation of series of articles regarding how Equality works in .Net, the purpose is to have the developers more clear understanding on how .Net handles equality for different types.</div>
<div>
<h2 style="text-align: left;">
What we learned so far:</h2>
</div>
<div>
<div>
Following are the key points that we learned from the previous parts until now:</div>
<div>
<ul style="text-align: left;">
<li>C# does not syntactically distinguish between value and reference equality which means it can sometimes be difficult to predict what the equality operator will do in particular situations.</li>
<li>There are often multiple different ways of legitimately comparing values. .Net addresses this by allowing types to specify their preferred natural way to compare for equality, also providing a mechanism to write equality comparers that allow you to place a default equality for each type </li>
<li>It is not recommended to test floating point values for equality because rounding errors can make this unreliable</li>
<li>There is an inherent conflict between implementing equality, type-safety and good Object Oriented practices.</li>
<li>Net provides the types equality implementation out of the box, few methods are defined by the .Net framework on the <b>Object </b>class which are available for all types.</li>
<li>By default the <b><i>virtual</i></b> <b>Object.Equals</b> method does reference equality for reference types and value equality for value types, but for value types it uses reflection which is a performance overhead for value types and any type can <b><i>override</i> Object.Equals</b> method to change the logic of how it checks for equality <b>e.g. String, Delegate</b> and <b>Tuple</b> do this for providing value equality, even though these are reference types.</li>
<li>Object class also provides a <b><i>static</i> Equals</b> method which can be used when there is chance that one or both of the parameters can be <b><i>null</i></b>, other than that it behaves identical to the <b><i>virtual</i> Object.Equals</b> method.</li>
<li>There is also a <b><i>static </i>ReferenceEquals</b> method which provides a guaranteed way to check for reference equality.</li>
<li><b>IEquatable<T></b> interface can be implemented on a type to provide a strongly typed <b>Equals </b>method which also avoids boxing for value types. It is implemented for primitive numeric types but unfortunately Microsoft has not been very proactive implementing for other value types in the <b>FCL( Framework Class Library )</b>.</li>
<li>For <b>Value Types</b> using <b>== operator</b> gives us the same result as calling <b>Object.Equals</b> but underlying mechanism of <b>== operator</b> is different in <b>IL( Intermediate Language )</b> as compared to Object.Equals, so the <b>Object.Equals</b> implementation provided for that primitive type is not called, instead an IL instruction <b><a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ceq(v=vs.110).aspx">ceq </a></b>gets called which says that compare the two values that are being loaded on the stack right now and perform equality comparison using CPU registers.</li>
<li>For <b>Reference Types</b>, <b>== operator</b> and <b>Object.Equals</b> method call both work differently behind the scenes which can be verified by inspecting the <b>IL </b>code generated. It also uses <b>ceq </b>instruction which do the comparison of memory addresses.</li>
</ul>
<div>
If you want to read the other parts published until now, you can read them here:</div>
</div>
</div>
<div>
<ul style="text-align: left;">
<li><a href="http://developmentpassion.blogspot.com/2016/06/story-of-complex-equality-in-net.html"><b>Story of Equality in .Net – Part 1</b></a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/06/story-of-equality-in-net-part-2.html"><b>Story of Equality in .Net – Part 2</b></a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-3.html"><b>Story of Equality in .Net – Part 3</b></a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-4.html"><b>Story of Equality in .Net – Part 4 </b></a></li>
<li><b><a href="http://developmentpassion.blogspot.com/2016/08/story-of-equality-in-net-part-5.html">Story of Equality in .Net – Part 5 </a></b></li>
</ul>
<h2 style="text-align: left;">
Introduction:</h2>
</div>
<div>
<div>
We will be looking at <b>String </b>type in this post that how Equality works for it. You might be aware that for strings the equality operator compares values not references which we had seen in the first post of this series. It is because <b>String </b>has overridden the implementation of <b>Equals </b>to behave in this manner.</div>
<div>
We will investigate how<b> == operator</b> and <b>Object.Equals</b> method behave for equality checking.</div>
</div>
<h2 style="text-align: left;">
Equality Operator and String:</h2>
<div>
Consider the following piece of code:</div>
<div>
<br /></div>
<div>
<pre class="brush: csharp">class Program
{
static void Main(String[] args)
{
string s1 = "Ehsan Sajjad";
string s2 = String.Copy(s1);
Console.WriteLine(ReferenceEquals(s1, s2));
Console.WriteLine(s1 == s2);
Console.WriteLine(s1.Equals(s2));
Console.ReadKey();
}
}
</pre>
</div>
<br />
The above code is very similar to what we have looked at before as well, but this time we have <b>String </b>type variables in place. We are creating a string and holding its reference in <b>s1 </b>variable and on next line we are creating copy of the string and holding its reference in another variable names <b>s2</b>.<br />
<br />
Then we are checking for reference equality for both the variables that are they both pointing to same memory location or not, then in next two lines we are checking the output of equality operator and <b>Object.Equals</b> method.<br />
<br />
Now we will build the project and run it to see what it outputs on the console. The following is the output printed on console:<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV94VMoAEYd_mYz4AAHHoSNK_a3RT9Jp07q9ZmR_rsHguHu2mYJqZRWOLKcT8usP0HQb8TLicmMMuFcjhNsTsDiDIACvYnjgnK8nb_sKAbuUErTrMkoHAAxckvygenulqgK9F4j4Dkz1WA/s1600/Console.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV94VMoAEYd_mYz4AAHHoSNK_a3RT9Jp07q9ZmR_rsHguHu2mYJqZRWOLKcT8usP0HQb8TLicmMMuFcjhNsTsDiDIACvYnjgnK8nb_sKAbuUErTrMkoHAAxckvygenulqgK9F4j4Dkz1WA/s1600/Console.png" /></a></div>
<div>
<br /></div>
<div>
You can see that <b>ReferenceEquals </b>has returned <b><i>false </i></b>which means that both the string are different instances, but the <b>== operator</b> and <b>Equals</b> method have returned <b><i>true</i></b>, so it is clear that for Strings the equality operator does indeed test the value for equality not the reference exactly as <b>Object.Equals</b> does.</div>
<h2 style="text-align: left;">
Behind the Scenes of Equality Operator for String</h2>
<div>
Let’s see how the equality operator is doing that. Now let’s examine the IL code generated for this example. For doing that, Open the <b>Visual studio Developer Command Prompt</b>, for opening it, go to <b>Start Menu >> All Programs >> Microsoft Visual Studio >> Visual Studio Tools>> Developer Command Prompt</b></div>
<div>
<b><br /></b></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifZ4ias-Pvd1namR11zLdFdL044EU3kYsR0WDcEamE75C3MHzLq0I-6QMCAnRCd3a3AvS0gjHFW1QJ-5JhdbAJ5JahtN4D3H7Y0tJlEyvZB3ikn9rrqeT4kHLMlbrXQbMtxEAoQ6ncXYcp/s1600/pic+1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifZ4ias-Pvd1namR11zLdFdL044EU3kYsR0WDcEamE75C3MHzLq0I-6QMCAnRCd3a3AvS0gjHFW1QJ-5JhdbAJ5JahtN4D3H7Y0tJlEyvZB3ikn9rrqeT4kHLMlbrXQbMtxEAoQ6ncXYcp/s1600/pic+1.png" /></a></div>
<div>
<b><br /></b></div>
<div>
Type <b>ildasm </b>on the command prompt, this will launch the IL disassembler which is used to look at the IL code contained in an assembly, it is installed automatically when you install <b>Visual Studio</b>, so you don’t need to do anything for installing it.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqe3Lec3t_3vww2LlXuYnIedLqGbYFRG_jYju2E_uwqr_sBls8ZkwmbaIsfLidFPTRCjNBvgI0IuOlGPsrje1U9KOXCd0SYFSrfPBuUcNl9jl6fgSw9Zpl9EXsKZXIpeKaMRFFVQlh27WU/s1600/pic+2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqe3Lec3t_3vww2LlXuYnIedLqGbYFRG_jYju2E_uwqr_sBls8ZkwmbaIsfLidFPTRCjNBvgI0IuOlGPsrje1U9KOXCd0SYFSrfPBuUcNl9jl6fgSw9Zpl9EXsKZXIpeKaMRFFVQlh27WU/s1600/pic+2.png" /></a></div>
<div>
<br /></div>
<div>
Click the <b>File </b>Menu to open the menu, and click the <b>Open </b>Menu Item which will bring up the window to browse the executable that we want to disassemble.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm7LgQsizHVs2-Qbgvhn45Spwief470veaerkrrSnRBV6d4B9gl8x1z1CrlVGFc6x40_NRN6sX7LWR2pPYwpBZq2NetRzKSiggqMgLLTsGyj7TLlzlRg9y0d3zhIQeXIaKc0pVHMUmFmWw/s1600/pic+3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm7LgQsizHVs2-Qbgvhn45Spwief470veaerkrrSnRBV6d4B9gl8x1z1CrlVGFc6x40_NRN6sX7LWR2pPYwpBZq2NetRzKSiggqMgLLTsGyj7TLlzlRg9y0d3zhIQeXIaKc0pVHMUmFmWw/s1600/pic+3.png" /></a></div>
<div>
<br /></div>
<div>
Now navigate to the location where your application executable file is located and open it.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyJ_oncDCb_9ixFvlYEY9_awwZ_lh_JYjwmMoHlBEXDM_9C8wIaETxErEgEg-5LLGLbBwk1qmaK-sTLLKssnVYCZ9OptymAH0-0XH_1iVngG42iBddSo4Q0Xrr_veOVJCahQS4ATebbmew/s1600/pic+4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyJ_oncDCb_9ixFvlYEY9_awwZ_lh_JYjwmMoHlBEXDM_9C8wIaETxErEgEg-5LLGLbBwk1qmaK-sTLLKssnVYCZ9OptymAH0-0XH_1iVngG42iBddSo4Q0Xrr_veOVJCahQS4ATebbmew/s1600/pic+4.png" /></a></div>
<div>
<br /></div>
<div>
<div>
This will bring up the code of the assembly in hierarchical form, as we have multiple classes written in the assembly, so it has listed down all the classes.</div>
<div>
<br /></div>
<div>
Now the code which we want to explore is in the <b>Main Method</b> of the <b>Program </b>class so navigate to the Main method and double click it to bring the IL code for it.</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZB4ikW3cnS5rxlTTU2Q7d-cJgxDUsk4YKUvRmPtlev4_O9drzq64T1Sm2M8FUZK2ef73jv5h6L8Fuy58oBNI-VNxI_fnOfmZBLjEHDtU-2xyMqHwuLmNK4bc3AQnEJIAzO06gE1s2Bqj8/s1600/pic+5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZB4ikW3cnS5rxlTTU2Q7d-cJgxDUsk4YKUvRmPtlev4_O9drzq64T1Sm2M8FUZK2ef73jv5h6L8Fuy58oBNI-VNxI_fnOfmZBLjEHDtU-2xyMqHwuLmNK4bc3AQnEJIAzO06gE1s2Bqj8/s1600/pic+5.png" /></a></div>
<div>
<br /></div>
<div>
<div class="MsoNormal">
The IL code for main looks like this:<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh06ZvA6h3-e7GXYkexIXDPp23H2LodpqOhYQslmFuCoBBlcoZX11nfsNon8GXFGbV1a_ZBc-Me548dgyRMo1ms_n4ZJx9WbR_T9Rigo70UlCMQpDOBk6YwO-MaamoBsW2cMf7Phu9kB2qO/s1600/pic+6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh06ZvA6h3-e7GXYkexIXDPp23H2LodpqOhYQslmFuCoBBlcoZX11nfsNon8GXFGbV1a_ZBc-Me548dgyRMo1ms_n4ZJx9WbR_T9Rigo70UlCMQpDOBk6YwO-MaamoBsW2cMf7Phu9kB2qO/s1600/pic+6.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<h2 style="text-align: left;">
IL for String override of Equals Method</h2>
</div>
<div>
First let;s look at the IL generated for <b>s1.Equals(s2)</b>, and there are no surprises as it is calling <b>Equals </b>method but this time it is calling the method implementation of<b> IEquatable<string></b> which takes a string as argument, not the <b>Object.Equals</b> override is being called, because the compiler found a better match for the string argument that was supplied. See the picture below:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvIhdGhPGCX6K6-rDcmlJZpQPdnoXTG0uLgD9dur3Kj3RCGyCY7aIYFj4kAJw-M1hNC8eiOzvku-GcSvQtNLa8E6osdvWuruQ-katZYTxYJzvXinnpzTmisi50tprns0Bq6CN3PfKGGHFb/s1600/pic+7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvIhdGhPGCX6K6-rDcmlJZpQPdnoXTG0uLgD9dur3Kj3RCGyCY7aIYFj4kAJw-M1hNC8eiOzvku-GcSvQtNLa8E6osdvWuruQ-katZYTxYJzvXinnpzTmisi50tprns0Bq6CN3PfKGGHFb/s1600/pic+7.png" /></a></div>
<div>
<br /></div>
<h2 style="text-align: left;">
IL for == operator for String</h2>
<div>
<div>
Now let’s examine what is the IL generated for the string equality checking done using equality operator, so we can see the now there is no <b>ceq </b>instruction being called which we saw in previous posts that for value types and reference types that instruction is executed when we check for equality using <b>== operator</b>, but for <b>String </b>we have call to a new method named <b>op_equality(string, string)</b> which takes two string arguments, we have not seen this kind of method before, so what it is actually? </div>
<div>
<br /></div>
<div>
The answer is it is the overload of C# equality operator (==) which is provided by <b>String </b>class. In C# when we define a type, we have the option to overload the equality operator for that type, for example , for <b>Person </b>class which we have been seeing in previous examples will look like following, if we overload the <b>== operator</b> for it:</div>
</div>
<div>
<br /></div>
<div>
<pre class="brush: csharp">public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public static bool operator == (Person p1, Person p2)
{
bool areEqual = false;
if (p1 == null || p2 == null)
areEqual = false;
if(p1 == null && p2 == null )
areEqual = true;
if (p1.Id == p2.Id)
areEqual = true;
else
areEqual = false;
return areEqual;
}
}
</pre>
</div>
<br />
So the above code is pretty simple, We have declared an operator overload which would be a static method, but the thing to notice here is that the name of the method is <b><i>operator</i> ==</b> The similarity of declaring operator overload with static method is not a con-incidence, actually it is compiled as a static method by the compiler, because we know and had been discussed before that <b>IL (Intermediate Language)</b> has no concept of operators, events etc , it only understands fields and methods, so operator overload can only exist as a method which we observed in IL code above, the overload operator code is turned by compiler in to a special static method called <b>op_Equality()</b>.<br />
<br />
First it is checking if any of the passed instances is null then they are not equal, then we see if both are null then obviously both references are equal so it will return true, and next it checks if Id property of both references is equal then they are equal, otherwise they are not equal.<br />
<br />
This way we can define our own implementation for our custom types according to the business requirements. As we discussed earlier that equality of two objects is totally dependent on the business flow of the application, so two objects might look equal to someone but not equal to some other according to their business logic.<br />
<br />
This makes one thing clear that <b>Microsoft </b>has provided <b>== operator overload</b> for <b>String </b>class, and we can even see that if we peek in to the source code of String class in Visual Studio by using <b>Go to Definition</b>, which would be like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimOpEb8IoPCIRvalkTbcSJClIpVgQkERZtaVyFozthNyGv8ROmkAvOvWCG18C6HNwtBLPIco5Kp326RAg0EQGpW7eMb-wgb-UOsncFOa5Fp6mM7Avk0kha7wrq-MWobH95-CfdzQ_ehlmF/s1600/pic+8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimOpEb8IoPCIRvalkTbcSJClIpVgQkERZtaVyFozthNyGv8ROmkAvOvWCG18C6HNwtBLPIco5Kp326RAg0EQGpW7eMb-wgb-UOsncFOa5Fp6mM7Avk0kha7wrq-MWobH95-CfdzQ_ehlmF/s1600/pic+8.png" /></a></div>
<br />
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 107%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;"><br /></span>
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 107%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;"><span style="font-family: Calibri, sans-serif; font-size: 14.6667px;">In the above snapshot, we can see that there are two operator overload one for equality and the other is inequality operator which works exactly the same way but the negation of equality operator output.</span></span><br />
<span style="font-family: Calibri, sans-serif;"><span style="font-size: 14.6667px;"><br /></span></span>
<h2 style="text-align: left;">
Summary</h2>
<br />
<ul style="text-align: left;">
<li>We have now enough understanding of what C# Equality operator does in the case of <b>Reference Types</b>. Following the thing that we need to keep in mind:</li>
<ul>
<li>If there is an overload for the equality operator for the type being compare, it uses that operator as a <b><i>static </i>method</b>.</li>
<li>If there is no overload of operator for reference type, the equality operator compares the memory addresses using <b>ceq </b>instruction.</li>
</ul>
<li>One thing to note is that <b>Microsoft </b>made sure that<b> == operator</b> overload and <b>Object.Equals <i>override</i></b><i> </i>always give the same result even though they are in fact different methods. So that is an important thing we need to keep in mind when we start implementing our own <b>Equals <i>override</i></b>, we should also take care of the equality operator as well, otherwise our type will end up giving different result using Equals override and equality operator which would be problematic for consumers of the type. We will be seeing in another post how we can override Equals method in a proper way.</li>
<li>If we are changing how Equality works for a type, we need to make sure we provide implementation for both Equals override and <b>== operator <i>overload</i></b><i> </i>so that they both give the same result, and that’s obvious otherwise it would be confusing for other developers who will be using our implemented type .</li>
</ul>
<br />
<span style="font-family: Calibri, sans-serif;"><span style="font-size: 14.6667px; line-height: 107%;"></span></span><br />
<div>
<br /></div>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-78462254504182991512016-08-29T13:55:00.000-07:002016-09-05T12:47:08.324-07:00Story of Equality in .Net - Part 5<div dir="ltr" style="text-align: left;" trbidi="on">
<h2 style="text-align: left;">
Background:</h2>
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<div style="text-align: left;">
This article is in the continuation of series of articles regarding how Equality works in .Net, the purpose is to have the developers more clear understanding on how .Net handles equality for different types. You may want to read the previous post as well:<br />
<br /></div>
<ul style="text-align: left;">
<li><a href="http://developmentpassion.blogspot.com/2016/06/story-of-complex-equality-in-net.html">Story of Equality in .Net – Part 1</a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/06/story-of-equality-in-net-part-2.html">Story of Equality in .Net – Part 2</a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-3.html">Story of Equality in .Net – Part 3</a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-4.html">Story of Equality in .Net – Part 4 </a></li>
</ul>
<br />
<ul style="text-align: left;">
</ul>
In the <a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-4.html">previous post (i.e. Part 4)</a> we compared the result of equality comparison of value type using <b>== operator</b> and <b>Object.Equals</b> method and the result was same but the mechanism for evaluating the equality is different as the IL generated for <b>Object.Equals</b> and <b>== operator </b>was different, which means that == operator does not call Object.Equals behind the scenes but it uses CPU’s registers to determine if the two value type variable are equal or not. <br />
<h2 style="text-align: left;">
Introduction:</h2>
<div style="text-align: left;">
I hope that after reading the previous posts, you have now better understanding how the c# equality operator works for primitive types like int, float, double etc. In this post we will be focusing on how the c# equality operator and Equals method behave for reference types either they are framework class library types or user defined custom types. If you haven’t read previous parts and interested in reading from start about this topic, you can navigate all parts published before here:</div>
<br />
<ul style="text-align: left;">
<li><a href="http://developmentpassion.blogspot.com/2016/06/story-of-complex-equality-in-net.html">Story of Equality in .Net – Part 1</a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/06/story-of-equality-in-net-part-2.html">Story of Equality in .Net – Part 2</a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-3.html">Story of Equality in .Net – Part 3</a></li>
<li><a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-4.html">Story of Equality in .Net – Part 4 </a></li>
</ul>
<br />
<h2 style="text-align: left;">
== Operator and Reference Types </h2>
<div style="text-align: left;">
If you recall from the previous post we saw an example using reference types for equality that it checks for reference equality, now we will modify the same example to see that equality operator compiles to what in case of reference types.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">class Program
{
static void Main(String[] args)
{
Person p1 = new Person();
p1.Name = "Ehsan Sajjad";
Person p2 = new Person();
p2.Name = "Ehsan Sajjad";
Console.WriteLine(p1.Equals(p2));
Console.WriteLine(p1 == p2);
Console.ReadKey();
}
}
</pre>
</div>
<div style="text-align: left;">
<br />
Now we will test using these both method of checking equality i.e. equality operator of c# and Equals method of Object type. If we runt his example we will see <b>false </b>printed on the console two times which was expected result as Person is a reference type and those are two different instances of person with difference memory reference.<br />
<br />
From the output we can easily deduce that both the equality operator and Equals method check for reference equality for reference types and that’s actually what’s happening. So, Equality operator also checks reference equality not value equality for reference types just same like Equals method.<br />
<br />
<h2 style="text-align: left;">
What Happens Behind the Scenes?</h2>
<div style="text-align: left;">
Now let’s examine the IL code generated for this example. For doing that, Open the Visual studio command prompt, for opening it, go to <b>Start Menu >> All Programs >> Microsoft Visual Studio >> Visual Studio Tools>> Developer Command Prompt</b></div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGl9LldBEDbhlKihsXKffCTqoEdop8HWzqfyha3cqW1ivOy-hycYP6hiOXkp9khPr5q4vsY7ChBVbpq7U4jcbmIN7yYznkwC3kd3FUT1Bktdp5O6Kdxl3LXG0xcsDuuC0o8KMpNOFrqEqE/s1600/part+5+-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGl9LldBEDbhlKihsXKffCTqoEdop8HWzqfyha3cqW1ivOy-hycYP6hiOXkp9khPr5q4vsY7ChBVbpq7U4jcbmIN7yYznkwC3kd3FUT1Bktdp5O6Kdxl3LXG0xcsDuuC0o8KMpNOFrqEqE/s1600/part+5+-1.png" /></a></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Type <b>ildasm </b>on the command prompt, this will launch the ildasm which is used to look at the IL code contained in an assembly, it is installed automatically when you install Visual Studio, so you don’t need to do anything for installing it. </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhccFFWXegeB8BG6tLWzgIIFv29wWcuV1qWAQBilYpAtxmaKqKCmUSpSiHIZT4oa88F3uw-5_vhJuikv-s74ZLxOCs-mRpz7-qt4aC7OmhpKeAD31_12I6ZWyzY28hRes4YSKFQ5BZ9PrVH/s1600/part+5+-+2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhccFFWXegeB8BG6tLWzgIIFv29wWcuV1qWAQBilYpAtxmaKqKCmUSpSiHIZT4oa88F3uw-5_vhJuikv-s74ZLxOCs-mRpz7-qt4aC7OmhpKeAD31_12I6ZWyzY28hRes4YSKFQ5BZ9PrVH/s1600/part+5+-+2.png" /></a></div>
<br />
<br />
Browse the folder where your executable is and open it using <b>File </b>Menu. This will bring up the IL code of your executable. <br />
<br />
The IL code for the above C# code looks like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTEdj06JxJBEuM3HIpgpe_kf7XnxtoTkGnCLkfeGLpJDh0nqb4iwVRNw7QASO_eefN4MAJdg6erJwkUDEhiwY-oPT3GTPVgmiNiLZClrcFDaGx8bfeDhpgYA3_R7_7QsYA4n5Sh1_L7mZD/s1600/Part+5+-+3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTEdj06JxJBEuM3HIpgpe_kf7XnxtoTkGnCLkfeGLpJDh0nqb4iwVRNw7QASO_eefN4MAJdg6erJwkUDEhiwY-oPT3GTPVgmiNiLZClrcFDaGx8bfeDhpgYA3_R7_7QsYA4n5Sh1_L7mZD/s1600/Part+5+-+3.png" /></a></div>
<br />
If we see the IL code for <b>p1.Equals(p2)</b>, there are no surprises, it is comparing the equality by calling the virtual <b>Equals </b>method of <b>Object</b>, and the method signatures are pretty clear, as they say it requires an object, so this is actually a virtual call to Object.Equals method, this is the best type’s method match that C# compiler picked.<br />
<br />
Now if we look at IL code generated for equality operator comparison of the objects. It is exactly the same instruction used which we saw for the integer example in the previous part. It is not calling any method to do the comparison, it is just loading both arguments to the evaluation stack and doing a <b>ceq</b>, which is a dedicated IL instruction to check for equality probably using the CPU’s hardware.<br />
<br />
You might be thinking how does that achieve the reference equality? We know that Person is a class which is a reference type which means whatever the variable of type Person contains is the address in memory of where the Person object is on managed heap.<br />
<br />
Both arguments <b>p1 </b>and <b>p2 </b>are holding the memory addresses and you know addresses in memory are just numbers which means that they can be compared using the <b>ceq </b>statement for equality just like the integers you declare in the code. In fact this <b>ceq </b>is comparing the addresses to see if they are equal, in other words whether the reference is pointing to the same memory address is reference equality.<br />
<h2 style="text-align: left;">
Summary </h2>
<ul style="text-align: left;">
<li>We saw that<b> == operator</b> and <b>Object.Equals</b> method call both work differently behind the scenes which we can verify by inspecting the IL code generated.</li>
<li>We saw that for Reference types as well using <b>== operator</b> gives us the same result as calling <b>Object.Equals</b> but underlying mechanism of <b>== operator</b> is different in IL as compare to <b>Object.Equals</b>, which is that it does not uses the <b>Object.Equals</b> instead it uses <b>ceq </b>instruction which do the comparison of memory addresses using hardware instructions .</li>
</ul>
<br /></div>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-78447319429950180562016-08-09T07:45:00.000-07:002017-03-22T00:47:22.261-07:00Grid View with Server Side Filtering, Sorting and Paging in asp.net mvc 5<div dir="ltr" style="text-align: left;" trbidi="on">
<h4 style="text-align: left;">
<b> </b></h4>
<h3 style="text-align: left;">
<b><a href="https://code.msdn.microsoft.com/Server-Side-Pagination-a91e7aaa">Download Source Code</a></b></h3>
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<br />
<h2 style="text-align: left;">
Background</h2>
<div style="text-align: left;">
In the <a href="http://developmentpassion.blogspot.nl/2016/07/beginners-guide-for-creating-gridview.html" target="_blank">previous post</a>, we talked about how we can achieve a gridview type functionality in asp.net mvc same like we have in asp.net webforms. We saw that how easy it is to implement a gird using jQuery datatables plugin which provides vital features such as searching, sorting and pagination.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUB78DQ2W5mOt1hTAp0C-XbNlGqucGKl_yyo8aGYpF0R5heymsBq8pupSpgBXvtBenk0_EefxYdK-vhKybtju70YeV16iPiMjo-je0a8KHEXxMYbnXDUGKWPlZyO9Q_OUErr5dWnXJqNB0/s1600/grid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUB78DQ2W5mOt1hTAp0C-XbNlGqucGKl_yyo8aGYpF0R5heymsBq8pupSpgBXvtBenk0_EefxYdK-vhKybtju70YeV16iPiMjo-je0a8KHEXxMYbnXDUGKWPlZyO9Q_OUErr5dWnXJqNB0/s1600/grid.png" /></a></div>
</div>
<div style="text-align: left;">
<br />
One thing to notice in the previous post is that all the features provided by the plugin are client side which means that all the data is loaded in the page first and then the plugin handles the data on client side for searching, pagination and sorting which is fine if the result sets coming are not very big, but it can cause problems if the table is too big or the data is not that much but grows gradually as applications is used, so if that is the case this way of creating the grid would fail in long run.</div>
<h2 style="text-align: left;">
Introduction</h2>
<div style="text-align: left;">
In this post, we will be seeing how we can implement the server side pagination, searching and sorting which is of course a better approach in the long run or for the applications where datasets are too big.</div>
<div style="text-align: left;">
We will be modifying the source code from the previous post for this, so let’s get started.</div>
<div style="text-align: left;">
<br />
First of all, we need to install <a href="https://www.nuget.org/packages/datatables.mvc5/">datatables.mvc5</a> from nuget package manager, it is a datatables model binder to controller implemented by <a href="https://www.nuget.org/profiles/snuxoll">Stefan Nuxoll</a>. You may be thinking why we need this package, it is because the binder will provide strongly typed model posted at controller, which will help us to avoid reading the request parameter and will also save us from type-casting the parameters from Request as all the parameters posted in Request object are not type safe so we have to convert them manually to their destination type, which will help the developers to focus on business logic instead of playing around with Http parameters, checking them and casting to the right type.</div>
<div style="text-align: left;">
The good thing about this binder is that you can add custom parameters sent in the request if your business requirements need that.</div>
<div style="text-align: left;">
You can add your own custom parameters if needed by providing your own implementation of <b>IDataTablesRequest</b>, and you will also need to override the <b>BindModel</b> and <b>MapAdditionalColumns</b> method of it.</div>
<div style="text-align: left;">
<br />
So now we will install <a href="https://www.nuget.org/packages/datatables.mvc5/">datatables.mvc5</a> , Go to <b>Tools >> NuGet Package Manager >> Manage Nuget Packages for Solution</b> and click it.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
The package manager will get opened and by default it will be displaying the installed nugget packages in your solution, click the <b>Browse</b> button and then search for <b>datatable.mvc5</b> package, then select it and check the projects of the solution in which you want to install this package, in our case we are installing in it <b>GridExampleMVC</b> web project only as per requirement and then press the install button.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLrRMmc1B2vqiLam99u13wGuDkZuBqEQqcQ1R2uwcWZofjWaTUypiAB3p7sxcgkslOc-ticSOAM1iPVuDyKJjZA0rtRtX7Ju08PXV-GuzPNBAq_O9OvgL48DHtYWvy5v6HuJtcfV6YPEIP/s1600/Step-4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLrRMmc1B2vqiLam99u13wGuDkZuBqEQqcQ1R2uwcWZofjWaTUypiAB3p7sxcgkslOc-ticSOAM1iPVuDyKJjZA0rtRtX7Ju08PXV-GuzPNBAq_O9OvgL48DHtYWvy5v6HuJtcfV6YPEIP/s1600/Step-4.png" /></a></div>
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Select the correct package which is in the above screenshot the top one returned in the search results and install it.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr60u4NGMwd5daFSqDHLHkYSqkQXUzv31lR_0QvAZSbD_N4EGlI5p0TRPxIFLIeBEFJay1g0Cqfxq85iWhyphenhyphenlA8GYbaiKb1zO1ihQOmGEf2sgEfHQJzb-f7C90SZu0lfQ9YyTc30y6pvjDs/s1600/datatables.mvc5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr60u4NGMwd5daFSqDHLHkYSqkQXUzv31lR_0QvAZSbD_N4EGlI5p0TRPxIFLIeBEFJay1g0Cqfxq85iWhyphenhyphenlA8GYbaiKb1zO1ihQOmGEf2sgEfHQJzb-f7C90SZu0lfQ9YyTc30y6pvjDs/s1600/datatables.mvc5.png" /></a></div>
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
If the installation of package goes successful, you will be able to see in the <b>References </b>of the project: </div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggGYf1QhaCZjQ13ZAVI8l05U0bP0J0tIfEj4LG5jwbJesg7_hdk6axEQ4c_gHo-hpbfhCuyjRU810V2NCNyzM72iC7tIxOQOly0hVHk1ufay-YYe5R2jBvsFZMIwx9g2A3y6cM9sp3hWZz/s1600/datatables.mvc5.reference.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggGYf1QhaCZjQ13ZAVI8l05U0bP0J0tIfEj4LG5jwbJesg7_hdk6axEQ4c_gHo-hpbfhCuyjRU810V2NCNyzM72iC7tIxOQOly0hVHk1ufay-YYe5R2jBvsFZMIwx9g2A3y6cM9sp3hWZz/s1600/datatables.mvc5.reference.png" /></a></div>
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Go to the Index.cshtml file and update the html of the view by removing the <b>thead </b>and <b>tbody </b>elements<b> </b>of the table. Your updated html would be:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: html"><div class="row">
<div class="col-md-12">
<div class="panel panel-primary list-panel" id="list-panel">
<div class="panel-heading list-panel-heading">
<h1 class="panel-title list-panel-title">Assets</h1>
</div>
<div class="panel-body">
<table id="assets-data-table" class="table table-striped table-bordered" style="width:100%;">
</table>
</div>
</div>
</div>
</div>
</pre>
</div>
<br />
We removed the head and body of table because it would get generated by the datatables plugin itself. Now we will have to update the jQuery datatables initialization so that it loads data from server side via ajaxing.<br />
<br />
For that add the following code in the Index.cshtml view:<br />
<br />
<pre class="brush: javascript">@section Scripts
{
<script type="text/javascript">
var assetListVM;
$(function () {
assetListVM = {
dt: null,
init: function () {
dt = $('#assets-data-table').DataTable({
"serverSide": true,
"processing": true,
"ajax": {
"url": "@Url.Action("Get","Asset")"
},
"columns": [
{ "title": "Bar Code", "data": "BarCode", "searchable": true },
{ "title": "Manufacturer", "data": "Manufacturer", "searchable": true },
{ "title": "Model", "data": "ModelNumber", "searchable": true },
{ "title": "Building", "data": "Building", "searchable": true },
{ "title": "Room No", "data": "RoomNo" },
{ "title": "Quantity", "data": "Quantity" }
],
"lengthMenu": [[10, 25, 50, 100], [10, 25, 50, 100]],
});
}
}
// initialize the datatables
assetListVM.init();
});
</script>
}
</pre>
<br />
After this, we will write the Get action code in the <b>AssetController</b>, for that first we need to reference the <b>System.Linq.Dynamic</b> namespace as we will be using the methods provided for dynamic linq in our action, for that go to Nuget Package Manager once again and search for <b>System.Linq.Dynamic</b> package and install it in your project.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzX0aLvHjXIg6XWOZoKxb-YodSt6Tpxx2gRNNVHRlg4eyDlF3d8sNsI_xUEhAoB2bhIXHgu3gwJKW9281izeNg2AIea7nc5634f1BIYAFkxnK3JuBLcpau4PBKM3UzOk3SMPju2ZVhmvHB/s1600/linq.dynamic+nuget.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzX0aLvHjXIg6XWOZoKxb-YodSt6Tpxx2gRNNVHRlg4eyDlF3d8sNsI_xUEhAoB2bhIXHgu3gwJKW9281izeNg2AIea7nc5634f1BIYAFkxnK3JuBLcpau4PBKM3UzOk3SMPju2ZVhmvHB/s1600/linq.dynamic+nuget.png" /></a></div>
<br />
<br />
After installing the package, go to <b>AssetController</b> and write the Get action implementation which will be :<br />
<br />
<pre class="brush: csharp">public ActionResult Get([ModelBinder(typeof(DataTablesBinder))] IDataTablesRequest requestModel)
{
IQueryable<asset> query = DbContext.Assets;
var totalCount = query.Count();
#region Filtering
// Apply filters for searching
if (requestModel.Search.Value != string.Empty)
{
var value = requestModel.Search.Value.Trim();
query = query.Where(p => p.Barcode.Contains(value) ||
p.Manufacturer.Contains(value) ||
p.ModelNumber.Contains(value) ||
p.Building.Contains(value)
);
}
var filteredCount = query.Count();
#endregion Filtering
#region Sorting
// Sorting
var sortedColumns = requestModel.Columns.GetSortedColumns();
var orderByString = String.Empty;
foreach (var column in sortedColumns)
{
orderByString += orderByString != String.Empty ? "," : "";
orderByString += (column.Data) + (column.SortDirection == Column.OrderDirection.Ascendant ? " asc" : " desc");
}
query = query.OrderBy(orderByString == string.Empty ? "BarCode asc" : orderByString);
#endregion Sorting
// Paging
query = query.Skip(requestModel.Start).Take(requestModel.Length);
var data = query.Select(asset => new
{
AssetID = asset.AssetID,
BarCode = asset.Barcode,
Manufacturer = asset.Manufacturer,
ModelNumber = asset.ModelNumber,
Building = asset.Building,
RoomNo = asset.RoomNo,
Quantity = asset.Quantity
}).ToList();
return Json(new DataTablesResponse(requestModel.Draw, data, filteredCount, totalCount), JsonRequestBehavior.AllowGet);
}
</pre>
<br />
<br />
<div class="MsoNormal">
Now build the project, and run it in browse to see the
working grid view with server side filtering, paging and sorting in action.<br />
<br />
<h2 style="text-align: left;">
Source Code</h2>
<div>
The source code is available for download from <a href="https://code.msdn.microsoft.com/Server-Side-Pagination-a91e7aaa">MSDN code samples gallery here</a></div>
</div>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-9863137030811158672016-07-23T12:43:00.000-07:002017-03-22T00:49:00.476-07:00Beginners Guide for Creating GridView in asp.net mvc 5<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<h4 style="text-align: left;">
<b><span style="font-weight: normal;"><a href="https://code.msdn.microsoft.com/Create-Grid-using-JQuery-711d6a1c">Download Source Code</a></span></b></h4>
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<br />
<h1>
Introduction</h1>
<div class="MsoNormal">
In this post, we will be seeing how we can create a grid
view in asp.net mvc, same like we have in asp.net web form. There are many
their party both server side and also client side plugins written in jQuery are
available which provide all the essential functionalities that we have in web
forms which include searching, sorting and paging etc. It totally depends on
the requirements of specific application if the search is needed client side or
server side, same for the other functions.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
You can download the <a href="https://drive.google.com/open?id=0Bzzb_9_aasccXy12d3FYTUdMcnM">source
code</a> from this <a href="https://drive.google.com/open?id=0Bzzb_9_aasccXy12d3FYTUdMcnM">link</a>.<br />
<br />
<h1>
Libraries Available</h1>
</div>
<div class="MsoNormal">
Some of the libraries and plugins available are:</div>
<div class="MsoListParagraphCxSpFirst" style="mso-list: l1 level1 lfo1; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span><a href="https://gridmvc.codeplex.com/">Grid.Mvc</a></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l1 level1 lfo1; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span><a href="http://mvcgrid.net/">MVCGrid.NET</a></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l1 level1 lfo1; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span><a href="https://www.nuget.org/packages/PagedList.Mvc/">PagedList.MVC</a></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l1 level1 lfo1; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span><a href="https://www.nuget.org/packages/jQuery.Grid/">JQuery.Grid</a></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l1 level1 lfo1; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span><a href="https://jqmvcgrid.codeplex.com/">JQuery
Grid for ASP.NET MVC</a></div>
<div class="MsoListParagraphCxSpLast" style="mso-list: l1 level1 lfo1; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span><a href="https://datatables.net/">JQuery DataTables</a></div>
<div class="MsoNormal">
<h1>
Using Jquery DataTables</h1>
All have their pros and cons, but personally I have found jQuery
datatables to be a good choice. It is highly flexible. It supports pagination,
instant-search, multi-column ordering. It also supports almost all the data
sources to which it can be binded, some of which are:</div>
<div class="MsoListParagraphCxSpFirst" style="mso-list: l0 level1 lfo2; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span><a href="https://datatables.net/examples/data_sources/dom.html">DOM</a></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo2; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span><a href="https://datatables.net/examples/data_sources/js_array.html">JavaScript</a></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo2; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span><a href="https://datatables.net/examples/data_sources/ajax.html">Ajax</a></div>
<div class="MsoListParagraphCxSpLast" style="mso-list: l0 level1 lfo2; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span><a href="https://datatables.net/examples/data_sources/server_side.html">Server-side
processing</a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
One of the best option which I like in it is that it
supports both client side searching, pagination, sorting etc, but it also
provides option to have server side processing of it, as there can be case
where we have too much data in database and in that case client side paging
wouldn’t be a good option, just think millions of rows in a table and if they
are binded to it using client side pagination, it will make or page
unresponsive due to high amount of rows processing and html rendering.<br />
<br />
We will first see an example of how we can implement it using client side processing. So, let’s get started. We will have a working grid with searching, sorting and paging at the end of the post which will look like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYhXC5ZOGPrAcAPeHdiKmvtSXn49hBh1ZlsT-RG5RcfHgvAVyc4HnTItyBAPi4TWsHop91GhV7L-VKuH5QaLTcw69hWIQ3vHTzTl1x78BmZVJWlWpZNvpr-Aq709j0ZYerd4FAatSK7fWs/s1600/grid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYhXC5ZOGPrAcAPeHdiKmvtSXn49hBh1ZlsT-RG5RcfHgvAVyc4HnTItyBAPi4TWsHop91GhV7L-VKuH5QaLTcw69hWIQ3vHTzTl1x78BmZVJWlWpZNvpr-Aq709j0ZYerd4FAatSK7fWs/s1600/grid.png" /></a></div>
<br />
First of all create database and table that we will be using in this post, Open <b>SQL Management Studio</b> and run the following script:<br />
<br /></div>
<pre class="brush: sql">CREATE DATABASE [GridExampleMVC]
GO
CREATE TABLE [dbo].[Assets] (
[AssetID] UNIQUEIDENTIFIER NOT NULL,
[Barcode] NVARCHAR (MAX) NULL,
[SerialNumber] NVARCHAR (MAX) NULL,
[FacilitySite] NVARCHAR (MAX) NULL,
[PMGuide] NVARCHAR (MAX) NULL,
[AstID] NVARCHAR (MAX) NOT NULL,
[ChildAsset] NVARCHAR (MAX) NULL,
[GeneralAssetDescription] NVARCHAR (MAX) NULL,
[SecondaryAssetDescription] NVARCHAR (MAX) NULL,
[Quantity] INT NOT NULL,
[Manufacturer] NVARCHAR (MAX) NULL,
[ModelNumber] NVARCHAR (MAX) NULL,
[Building] NVARCHAR (MAX) NULL,
[Floor] NVARCHAR (MAX) NULL,
[Corridor] NVARCHAR (MAX) NULL,
[RoomNo] NVARCHAR (MAX) NULL,
[MERNo] NVARCHAR (MAX) NULL,
[EquipSystem] NVARCHAR (MAX) NULL,
[Comments] NVARCHAR (MAX) NULL,
[Issued] BIT NOT NULL,
CONSTRAINT [PK_dbo.Assets] PRIMARY KEY CLUSTERED ([AssetID] ASC)
)
GO
</pre>
<br />
There is complete sql script file attached in the source code, so you can use it to create the database and table with sample data.<br />
<br />
Now, create a new asp.net mvc 5 web application. Open Visual Studio 2015. Go to <b>File >> New >> Project</b><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLbQ1vd0zJ4ZpFei6WUdZTXVAmGmBAlICOKT2lIZlwSguyw-_h-dNZONB0NLvO_wv2Srr-Jmc5viMt59qtrH7FKS8NjBOIHx-pDnhZ84bHMi0FqK60gmYFcfUf9MTm_R1lbayMaY-y9Yxo/s1600/Step-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLbQ1vd0zJ4ZpFei6WUdZTXVAmGmBAlICOKT2lIZlwSguyw-_h-dNZONB0NLvO_wv2Srr-Jmc5viMt59qtrH7FKS8NjBOIHx-pDnhZ84bHMi0FqK60gmYFcfUf9MTm_R1lbayMaY-y9Yxo/s1600/Step-1.png" /></a></div>
<br />
From the dialog navigate to Web and select ASP.Net Web Application project and click OK.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjM408CuIz1sPM8UfunThk9GJ_-b7WjlgmnVhAZgpFISQNw2wnSfT_mD-rRMfxprfThlyEXCQLJnquo0lTEAUpMUlT6HOoT8Nqd0ILXYDSkt7gLOsEqZ_IwxeonTRpLDjywmASqpiIYssA4/s1600/Step-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjM408CuIz1sPM8UfunThk9GJ_-b7WjlgmnVhAZgpFISQNw2wnSfT_mD-rRMfxprfThlyEXCQLJnquo0lTEAUpMUlT6HOoT8Nqd0ILXYDSkt7gLOsEqZ_IwxeonTRpLDjywmASqpiIYssA4/s1600/Step-2.png" /></a></div>
<br />
From Templates, Select <b>MVC</b>, check the unit tests if you will write unit tests as well for your implementations and click <b>OK</b>.<br />
Our project is created with basic things in place for us. Now we will start by creating the database context class as we will be using Entity Framework for the Data Access.<br />
<br />
First of all we need to create model for the Asset table which we will be using for retrieving data using ORM.<br />
In Model folder, create a new class named <b>Asset</b>:<br />
<br />
<pre class="brush: csharp">using System.ComponentModel.DataAnnotations;
namespace GridExampleMVC.Models
{
public class Asset
{
public System.Guid AssetID { get; set; }
[Display(Name = "Barcode")]
public string Barcode { get; set; }
[Display(Name = "Serial-Number")]
public string SerialNumber { get; set; }
[Display(Name = "Facility-Site")]
public string FacilitySite { get; set; }
[Display(Name = "PM-Guide-ID")]
public string PMGuide { get; set; }
[Required]
[Display(Name = "Asset-ID")]
public string AstID { get; set; }
[Display(Name = "Child-Asset")]
public string ChildAsset { get; set; }
[Display(Name = "General-Asset-Description")]
public string GeneralAssetDescription { get; set; }
[Display(Name = "Secondary-Asset-Description")]
public string SecondaryAssetDescription { get; set; }
public int Quantity { get; set; }
[Display(Name = "Manufacturer")]
public string Manufacturer { get; set; }
[Display(Name = "Model-Number")]
public string ModelNumber { get; set; }
[Display(Name = "Main-Location (Building)")]
public string Building { get; set; }
[Display(Name = "Sub-Location 1 (Floor)")]
public string Floor { get; set; }
[Display(Name = "Sub-Location 2 (Corridor)")]
public string Corridor { get; set; }
[Display(Name = "Sub-Location 3 (Room No)")]
public string RoomNo { get; set; }
[Display(Name = "Sub-Location 4 (MER#)")]
public string MERNo { get; set; }
[Display(Name = "Sub-Location 5 (Equip/System)")]
public string EquipSystem { get; set; }
public string Comments { get; set; }
public bool Issued { get; set; }
}
}
</pre>
<br />
Now Navigate to <b>Models </b>folder from <b>Solution Explorer</b> and open <b>IdenityModels.cs</b> file , we will add a property for the Asset table in the database context, which will be the Entity Framework representation of Asset table which we created using the script. Add new property in the <b>ApplicationDbContext </b>class:<br />
<br />
<pre class="brush: csharp">public class ApplicationDbContext : IdentityDbContext<applicationuser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public DbSet<asset> Assets { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
</asset></applicationuser></pre>
<br />
The above is the default entity framework settings for asp.net identity 2.0, we are extending it with our own tables for which we have added new <b>DbSet </b>for Asset table.<br />
<br />
Now add an empty controller in <b>Controllers </b>folder named <b>AssetController</b>, which we will be using for all the Asset related work. Here is how it should look like:<br />
<br />
<br />
<pre class="brush: csharp">public class AssetController : Controller
{
// GET: Asset
public ActionResult Index()
{
return View();
}
}
</pre>
<br />
Now we will install <b>jQuery datatables</b> that we will be using to build the gird, Go to <b>Tools >> NuGet Package Manager >> Manage Nuget Packages for Solution </b>and click it.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlK2XiIq8c-ksfEpEurWRQj_WpnnG5gpLNg27rnhwzE_RiVwzuCVajYrOq8B_L7tZCAaH1yBsFK2rBNv4hM8lFX6jOlAkEPic1witX51fsiDOKd4IodGvASSe05IWlC8tIS7fsJC0aMrM0/s1600/Step-4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlK2XiIq8c-ksfEpEurWRQj_WpnnG5gpLNg27rnhwzE_RiVwzuCVajYrOq8B_L7tZCAaH1yBsFK2rBNv4hM8lFX6jOlAkEPic1witX51fsiDOKd4IodGvASSe05IWlC8tIS7fsJC0aMrM0/s1600/Step-4.png" /></a></div>
<br />
The package manager will get opened and by default it will be displaying the installed nugget packages in your solution, click the browser button and then search for <b>jQuery datatables</b> package, then select it and check the projects of the solution in which you want to install this package, in our case we are installing in it <b>GridExampleMVC </b>web project only as per requirement and then press the <b>Install </b>button.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW-v6WfHLkyjKqHVKPobOyLgPkmM7kA2YxI1LuNza4Hv5BEcU9FCyD4RZKShBvzxW-YAo4VybykR5QTj4I9lgJeM8NKrF44DRCXLWpBWwutoHq47bUBLg_xqiivoS8PEV24FfpbMWJm-OL/s1600/Step-5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW-v6WfHLkyjKqHVKPobOyLgPkmM7kA2YxI1LuNza4Hv5BEcU9FCyD4RZKShBvzxW-YAo4VybykR5QTj4I9lgJeM8NKrF44DRCXLWpBWwutoHq47bUBLg_xqiivoS8PEV24FfpbMWJm-OL/s1600/Step-5.png" /></a></div>
<br />
<br />
<br />
<br />
<br />
Visual Studio will prompt to tell that it is going to modify the solution, you will have to press ok to continue the installation of the package.<br />
<br />
After the nugget package is installed successfully, we need to include the necessary <b>js </b>and <b>css </b>of <b>jquery datatables</b> in the view where we will use it, for that we have to register the jquery datatables, for that open the <b>BundleConfig.cs </b>file locate in <b>App_Start</b> folder and add the following code for <b>css </b>and <b>js </b>files at the end:<br />
<br />
<pre class="brush:csharp">bundles.Add(new ScriptBundle("~/bundles/datatables").Include(
"~/Scripts/DataTables/jquery.dataTables.min.js",
"~/Scripts/DataTables/dataTables.bootstrap.js"));
bundles.Add(new StyleBundle("~/Content/datatables").Include(
"~/Content/DataTables/css/dataTables.bootstrap.css"));
</pre>
<br />
After registering the scripts and css for datatables, we need to add them in our master layout which is by default <b>_Layout.cshtml</b> located in <b>Views >> Shared</b> which is defined in the<b> _ViewStart.cshtml </b>located in the same location.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinK5E9spzvggmriXMOqit1CeBhg4nkYqZCNZmOxME4-af5ljQ-JN-nKrq488uoIqY2x_UTlFkZhNRDm0YvyNm4LkynKFy8BD_S1_k5yMBR9GLxm66KC2TgYLjcStyVESPKmT_-I_-M9ux5/s1600/Step-6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinK5E9spzvggmriXMOqit1CeBhg4nkYqZCNZmOxME4-af5ljQ-JN-nKrq488uoIqY2x_UTlFkZhNRDm0YvyNm4LkynKFy8BD_S1_k5yMBR9GLxm66KC2TgYLjcStyVESPKmT_-I_-M9ux5/s1600/Step-6.png" /></a></div>
<br />
<br />
<br />
<br />
<br />
Before writing the controller code, we need to configure the connection string for entity framework that will be used to connect database when it will be doing database operations i.e. running queries. So our connection string should be pointing to a valid data source so that our application won’t break when we run it.<br />
<br />
<br />
For that open <b>web.config</b> and provide the connection string for the database. In config file you will find the under <b>configuaration </b>node<b> connectionStrings</b>, you will need to modify the connection string in that node according to your system. In my case it looks like:<br />
<br />
<pre class="brush: xml"><connectionstrings>
<add connectionstring="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=GridExampleMVC;Integrated Security=True;MultipleActiveResultSets=true" name="DefaultConnection" providername="System.Data.SqlClient"/>
</connectionstrings>
</pre>
<br />
Now in controller add a property for database context that we will be using for querying the database.<br />
<br />
<pre class="brush: csharp">private ApplicationDbContext _dbContext;
public ApplicationDbContext DbContext
{
get
{
return _dbContext ?? HttpContext.GetOwinContext().Get<applicationdbcontext>();
}
private set
{
_dbContext = value;
}
}
</applicationdbcontext></pre>
<br />
This property we will be using to query the database with entity framework in all actions of the controller wherever needed.<br />
<br />
Now in the index action, we will simply fetch all the rows of the table and pass it to view:<br />
<br />
<pre class="brush: csharp">public ActionResult Index()
{
return View(DbContext.Assets.ToList());
}
</pre>
<br />
Our complete controller class code now looks like:<br />
<br />
<pre class="brush: csharp">using GridExampleMVC.Models;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity.Owin;
namespace GridExampleMVC.Controllers
{
public class AssetController : Controller
{
private ApplicationDbContext _dbContext;
public ApplicationDbContext DbContext
{
get
{
return _dbContext ?? HttpContext.GetOwinContext().Get<applicationdbcontext>();
}
private set
{
_dbContext = value;
}
}
public AssetController()
{
}
public AssetController(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
// GET: Asset
public ActionResult Index()
{
return View(DbContext.Assets.ToList());
}
}
}
</applicationdbcontext></pre>
<br />
Here comes the view part now, where we will write code about how it should render as html. So create a view with Template Empty (Without Model) for the Index action and add the following code in it:<br />
<br />
<pre class="brush: html">@model IEnumerable< GridExampleMVC.Models.Asset>
<div class="row">
<div class="col-md-12">
<div class="panel panel-primary list-panel" id="list-panel">
<div class="panel-heading list-panel-heading">
<h1 class="panel-title list-panel-title">Assets</h1>
</div>
<div class="panel-body">
<table id="assets-data-table" class="table table-striped table-bordered" style="width:100%">
<thead>
<tr>
<th>Bar Code</th>
<th>Manufacturer</th>
<th>Model Number</th>
<th>Building</th>
<th>Room No</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
@foreach (var asset in Model)
{
<tr>
<td>@asset.Barcode</td>
<td>@asset.Manufacturer</td>
<td>@asset.ModelNumber</td>
<td>@asset.Building</td>
<td>@asset.RoomNo</td>
<td>@asset.Quantity</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
@section Scripts
{
<script type="text/javascript">
$(document).ready(function () {
$('#assets-data-table').DataTable();
});
</script>
}
</pre>
<br />
Now run the application and you will see a grid with sorting, searching and filtering available in it, but there is one problem in it, which is it is processed on client side, all the data is rendered by view when action is called which may make page performance slow or increases page load time if there are a large number of rows coming.<br />
<br />
We will be seeing in another post how we can make it more better by using server side paging, sorting and filtering which is surely a better approach where we have huge data set.<br />
<br />
<h2 style="text-align: left;">
Source Code</h2>
<div>
The code is available at <a href="https://code.msdn.microsoft.com/Create-Grid-using-JQuery-711d6a1c">MSDN samples gallery</a> for download. Please <a href="https://code.msdn.microsoft.com/Create-Grid-using-JQuery-711d6a1c">click here</a> to download.</div>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-3927043042311209972016-07-08T07:51:00.000-07:002016-07-08T09:24:56.014-07:00Story of Equality in .Net - Part 4<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<h1>
Background:</h1>
<div class="MsoNormal">
This article is in the continuation of the previous three articles
regarding how Equality works in .Net, the purpose is to have the developers
more clear understanding on how .Net handles equality for types. You may want
to read the previous post as well:</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoListParagraphCxSpFirst" style="mso-list: l0 level1 lfo2; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";"> <b>
</b></span></span></span><b><a href="http://developmentpassion.blogspot.com/2016/06/story-of-complex-equality-in-net.html" target="_blank">Story of Equality in .Net – Part 1</a></b></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo2; text-indent: -.25in;">
<b><span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";"> <a href="http://developmentpassion.blogspot.com/2016/06/story-of-equality-in-net-part-2.html" target="_blank">
</a></span></span></span><a href="http://developmentpassion.blogspot.com/2016/06/story-of-equality-in-net-part-2.html" target="_blank">Story of Equality in .Net – Part 2</a></b></div>
<div class="MsoListParagraphCxSpLast" style="mso-list: l0 level1 lfo2; text-indent: -.25in;">
<b><span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span><a href="http://developmentpassion.blogspot.com/2016/07/story-of-equality-in-net-part-3.html" target="_blank">Story of Equality in .Net – Part 3</a></b></div>
<br />
<h1>
Introduction</h1>
<div class="MsoNormal">
I hope that after reading the previous three posts, you have
now understanding how the .Net framework deals with the Equality using the virtual
<b style="mso-bidi-font-weight: normal;">Object.Equals</b> method and for most of
the value types and for few of Reference types using <b style="mso-bidi-font-weight: normal;">IEquatable<T></b>. In this post we will be discussing the c#
equality operator provided by Microsoft. We will explore what the C# Equality
operator does and how it works. After reading this post I hope you will have a
better understanding what it means when you check for equality of two variable
using == operator.</div>
<br />
<div class="MsoNormal">
We will cover the following things:</div>
<ul style="text-align: left;">
<li>We will be writing some code for comparing the
== operator and Object.Equals behavior for same parameters to see what happens,
and we will see that the result is same, but the mechanism used for both is
different</li>
<li>We will see how C# equality operator works for
primitive types.</li>
</ul>
<div class="MsoNormal">
C# also provides inequality operator as well, the syntax for
which is <b style="mso-bidi-font-weight: normal;">!=</b>. We will not be
discussing this operator in detail because it is the negation of what equality
operator does, so they are not that much different. For example, if a==b
evaluates to true then a!=b should evaluate to false and vice versa. Apart from
this difference both the operators work exactly the same way. So, keep in mind
that everything that we will discuss in this post about equality operator also
applies to the inequality operator as well, it will just inverse the return
value.</div>
<br />
<div class="MsoNormal">
The equality operator is used when we want to evaluate that
if two of the variables are equal or not. A lot of developers have
misconception that this operator is basically the same as Object.Equals method,
and it is just a syntactical convenience provide by C# language.</div>
<br />
<div class="MsoNormal">
This is not true actually. It is being designed in a way
that it often gives the same result which by calling Object.Equals will give
but that’s not always the case as the underlying mechanism is completely
different.</div>
<br />
<h1>
== Operator and Primitive Types</h1>
We will see with example code that how the
equality operator uses different mechanism in reference to Object.Equals
method.<br />
<br />
<pre class="brush: csharp"> class Program
{
static void Main(String[] args)
{
int num1 = 5;
int num2 = 5;
Console.WriteLine(num1.Equals(num2));
Console.WriteLine(num1 == num2);
Console.ReadKey();
}
}
</pre>
<br />
<br />
<div class="MsoNormal">
We are comparing two integers for equality using both way ,
first using Object.Equals overload for integer and second one using c# equality
operator and we will examine the generated IL code which will help us
understand how they are different in mechanism.</div>
<div class="MsoNormal" style="background: white; line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;">
Of course when we will run this program it will evaluate to <b style="mso-bidi-font-weight: normal;">true</b> for both the statements, and you
can test it on your machine as well. As the result of both the statements is
same this makes us believe that both are using Object.Equals and checking two
integers for equality.</div>
<br />
<div class="MsoNormal" style="background: white; line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;">
<br /></div>
<br />
<h1>
<span style="mso-fareast-font-family: "Times New Roman";">What Happens Behind
the Scene</span></h1>
<div class="MsoNormal">
As we talked earlier that the == operator and Object.Equals
work differently and we are going to see that how it is which will be a proof
to what we talked earlier. We will examine the IL generated for both the
statements after compilation.</div>
<br />
<div class="MsoNormal">
One thing to note here is that before doing this you will
need to build your project using Release build not debug, as debug code will
generate a lot of unnecessary instructions that are helpful when we need to debug
and also in debug build it will use <b style="mso-bidi-font-weight: normal;">Object.Equals</b>
implementation for both, so that will not help you to see what we will discuss
next.</div>
<br />
<div class="MsoNormal">
For doing that, Open the Visual studio command prompt, for
opening it, go to <b style="mso-bidi-font-weight: normal;">Start Menu >> All
Programs >> Microsoft Visual Studio >> Visual Studio Tools>> Developer
Command Prompt</b></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<b style="mso-bidi-font-weight: normal;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQgtipI4FHpwaRvF3tNI2QUFlQDgAPzKrdA4iYFnHMAT6l05YbC5Ex-uYyCQZSk0GDH50fy2l3ec32iV7K5TPDlXKX6atwKt-kbck1kPn606O8d0fUA78z8n8PyWe3K4kV3LjzwORr2EzA/s1600/Visual+Studio+Command+Prompt.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQgtipI4FHpwaRvF3tNI2QUFlQDgAPzKrdA4iYFnHMAT6l05YbC5Ex-uYyCQZSk0GDH50fy2l3ec32iV7K5TPDlXKX6atwKt-kbck1kPn606O8d0fUA78z8n8PyWe3K4kV3LjzwORr2EzA/s1600/Visual+Studio+Command+Prompt.png" /></a></b></div>
<br />
<br />
Type <b style="mso-bidi-font-weight: normal;">ildasm</b> on
the command prompt, this will launch the ildasm which is used<span style="mso-spacerun: yes;"> </span>to look at the IL code contained in an assembly,
it is installed automatically when you install Visual Studio, so you don’t need
to do anything for installing it.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkaJlkmOOAuqlmrR4nLjhMpCu3rBeqjI-3VeFqgEu84jr_mhLf7CBrBqOfa1ZtUOw597LAmZ9wTedW7nLfAfmZGs9GWvjNArS26C8SciyV-4KcrWCbrfJfX_45z95N_3ACEnN0fcHws-fp/s1600/IL+DASM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkaJlkmOOAuqlmrR4nLjhMpCu3rBeqjI-3VeFqgEu84jr_mhLf7CBrBqOfa1ZtUOw597LAmZ9wTedW7nLfAfmZGs9GWvjNArS26C8SciyV-4KcrWCbrfJfX_45z95N_3ACEnN0fcHws-fp/s1600/IL+DASM.PNG" /></a></div>
<br />
<br />
Browse the folder where your executable is and open it using File Menu. This will bring up the IL code of your executable.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEGA6c-eTyhJQnmzogwQZSx6fNHMc_n7wASxwXPtxpFenC9d3dMEL965XKNcpTgU9bCTZiK_5QQVDkXlvvL9oNfuj4D1QRAwYfI3iyTs21ra-Do2DCQBWDqmmFL6N9nlS3zJ1czKfp47Js/s1600/il.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEGA6c-eTyhJQnmzogwQZSx6fNHMc_n7wASxwXPtxpFenC9d3dMEL965XKNcpTgU9bCTZiK_5QQVDkXlvvL9oNfuj4D1QRAwYfI3iyTs21ra-Do2DCQBWDqmmFL6N9nlS3zJ1czKfp47Js/s1600/il.PNG" /></a></div>
<br />
<br />
Expand the Program class and double click the Main method, it will open up the intermediate language for Main method:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUiNqiKu_dLh7yUnSOfVHukDjz7w-T8lYvqWYcao_5ZejeswvfrFHQdwxgLqTuTQygz2odxKeXuCSAAQ8SDW2SOeWU3Tl0cak7WY7atzmmlRk5sBQAKf1xAQy723Ohwjdk1kb17tcRwLDj/s1600/IL+Main.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUiNqiKu_dLh7yUnSOfVHukDjz7w-T8lYvqWYcao_5ZejeswvfrFHQdwxgLqTuTQygz2odxKeXuCSAAQ8SDW2SOeWU3Tl0cak7WY7atzmmlRk5sBQAKf1xAQy723Ohwjdk1kb17tcRwLDj/s1600/IL+Main.PNG" /></a></div>
<br />
<br />
<div class="MsoNormal">
You don’t need to understand all the code written in it, if
you have not seen IL seen before that may look complex to you, but you don’t
need to understand all the instructions.</div>
<div class="MsoNormal">
We will just look at the lines where the comparison is done
for both ways to show you the difference, you can see the following line:</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: 0in;">
<span style="font-size: small;"><b style="mso-bidi-font-weight: normal;"><span style="font-family: "fixedsys"; font-size: 10.0pt;">IL_0007:<span style="mso-spacerun: yes;"> </span>call<span style="mso-spacerun: yes;"> </span>instance bool
[mscorlib]System.Int32::Equals(int32)</span></b></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Here it is calling the Object.Equals implementation provided
via <b style="mso-bidi-font-weight: normal;">IEquatable<int></b> for
integer type, in IL we need to specify the method call using Fully Qualified
name, so the above statements say to call Equals method which takes as <b style="mso-bidi-font-weight: normal;">int32</b> as parameter and method exists in
<b style="mso-bidi-font-weight: normal;">System.Int32</b> type and this type
exists in mscorlib assembly.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Now look at IL generated for second comparison which was
done via equality operator, which is:</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: 0in;">
<span style="font-size: small;"><b style="mso-bidi-font-weight: normal;"><span style="font-family: "fixedsys"; font-size: 10.0pt;">IL_0013:<span style="mso-spacerun: yes;"> </span>ceq</span></b></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
You can see that call to Equals method in Int class is not
called in this case, instead we have an IL instruction written <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ceq(v=vs.110).aspx">ceq</a>
</b>which says that compare the two values that are being loaded on the stack
right now and perform equality comparison using CPU registers. So, C# equality
operator uses <b style="mso-bidi-font-weight: normal;">ceq </b>statement to do
equality check for primitive types and it does not calls the Object.Equals
implementation provided by that primitive type.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWPkSuYu0s5D5cunhKwWjPPKfPnm_UBux4PHDn-0lSULeWBIZwjJSa49naP3Lzjn2R9gm7g2pEQrxiV_umq5ez88BOlLlkDBQlJ8VzfSSoO_VWdOnkRU8QIJT8cFdhtFvnjm-IxjyJrc77/s1600/tools.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWPkSuYu0s5D5cunhKwWjPPKfPnm_UBux4PHDn-0lSULeWBIZwjJSa49naP3Lzjn2R9gm7g2pEQrxiV_umq5ez88BOlLlkDBQlJ8VzfSSoO_VWdOnkRU8QIJT8cFdhtFvnjm-IxjyJrc77/s1600/tools.png" /></a></div>
<br />
<br />
<br />
<h1>
Summary</h1>
<ul style="text-align: left;">
<li>We compared the == operator with Object.Equals
method in this post.</li>
<li>We saw that using == operator gives us the same result
as calling Object.Equals but underlying mechanism of == operator is different
in IL as compare to Object.Equals, which is that it does not uses the Object.Equals
instead it uses probably cpu registers to do the comparison.</li>
</ul>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-91528772015916937012016-07-04T17:10:00.000-07:002016-12-18T09:15:52.281-08:00Story of Equality in .Net - Part 3<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<br />
<h1>
Introduction</h1>
<div class="MsoNormal">
After reading,<br />
<br />
<b> <a href="http://developmentpassion.blogspot.com/2016/06/story-of-complex-equality-in-net.html" target="_blank">Story of Equality in .Net - Part 1</a> </b><br />
<b><a href="http://developmentpassion.blogspot.com/2016/06/story-of-equality-in-net-part-2.html" target="_blank"> Story of Equality in .Net - Part 2</a></b> <br />
<br />
you can see that
Object.Equals method has two problems. One thing is that it lacks strong typing
and for value types boxing needs to be done. In this post we will look at the
IEquatable<T> interface which provides solution to these problems.</div>
<h1>
IEquatable<T> Interface</h1>
<div class="MsoNormal">
The generic IEquatable <T> exists for solving a
slightly different problem with Equals method. The Equals method on Object type
takes parameter of type Object. We know that this is the only type of parameter
which is possible if we want Object.Equals to work for all types.</div>
<div class="MsoNormal">
But Object is a reference type which means that if you want
to pace a value type as an argument, the value type would be boxed which will
be a performance hit which is bad. Typically when we define value type instead
of reference type is because we are concerned of performance, so we always want
to avoid this performance overhead of boxing and unboxing.</div>
<div class="MsoNormal">
There is also another problem, having an object as parameter
means that there is no type safety. For Example, the following code will
compile without any problem:<br />
<br /></div>
<pre class="brush: csharp"> class Program
{
static void Main(String[] args)
{
Person p1 = new Person("Ehsan Sajjad");
Program p = new Program();
Console.WriteLine(p1.Equals(p));
Console.ReadKey();
}
}
</pre>
<br />
<br />
<div class="MsoNormal">
There is nothing to stop me for calling Equals method on two
difference type of instances. We are comparing instance of Person class with
instance of Program and compiler didn’t stopped me doing that, which is clearly
an issue as both are totally different types and there is no way they can
meaningfully equal each other.<br />
<br />
<br />
<div class="MsoNormal">
This was just an example, you should not be doing this kind
of comparisons in your code, and obviously it would be nice if compiler could
pick up this kind of situation, right now it cannot because Object.Equals
method does not have strong type safety.</div>
<div class="MsoNormal">
We can solve this boxing and type safety issue by having an
Equals method that takes the type being compare as parameter, so for example we
can have an Equals method on String which takes a string as parameter and<span style="mso-spacerun: yes;"> </span>we can have an Equals method on Person class
which takes a Person variable as parameter. This will solve both boxing and
type safety problem nicely.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
As we talked in the previous post about the problem of
inheritance with the above approach. But there is no way to usefully define
these strongly typed methods on <b style="mso-bidi-font-weight: normal;">System.Object,</b>
because <b style="mso-bidi-font-weight: normal;">System.Object</b> does not know
what types will be deriving from it.</div>
<div class="MsoNormal">
So how can we make a strongly typed Equals method generally
available to consume. Microsoft solved this problem by providing the interface <b style="mso-bidi-font-weight: normal;">IEquatable<T> </b>which can be
exposed by any type that wants to provide strongly typed Equals method. If we
look at the documentation we can see that IEquatable<T> exposes just one
method called Equals which returns a bool.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5ilwMoWTyx-ACZMgccNR3uARQk6KHtLBIifH27qOnfs_y9HSdNbs5yXQULXUdnlSeI-kv17nRfDiWjHzQYLX-DQEmx4kANcQPaLCWrGoIJqsHIfztp7kQPdxymnwsQsRxMxpfIyDpJXeU/s1600/Iequatable.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5ilwMoWTyx-ACZMgccNR3uARQk6KHtLBIifH27qOnfs_y9HSdNbs5yXQULXUdnlSeI-kv17nRfDiWjHzQYLX-DQEmx4kANcQPaLCWrGoIJqsHIfztp7kQPdxymnwsQsRxMxpfIyDpJXeU/s1600/Iequatable.png" /></a></div>
<br />
<div class="MsoNormal">
This serves<span style="mso-spacerun: yes;"> </span>exactly
the same purpose<span style="mso-spacerun: yes;"> </span>as Object.Equals, but
it takes the generic type T instance as a parameter and therefore it is
strongly typed which means for value types there will be no boxing to be<span style="mso-spacerun: yes;"> </span>done.</div>
<h1>
IEquatable<T> and Value Types</h1>
<div class="MsoNormal">
We can illustrate the IEquatable<T> interface with one
of the simplest type integer.<br />
<br /></div>
<pre class="brush: csharp"> static void Main(String[] args)
{
int num1 = 5;
int num2 = 6;
int num3 = 5;
Console.WriteLine(num1.Equals(num2));
Console.WriteLine(num1.Equals(num3));
}
</pre>
<br />
We have three integer variables which we are comparing using Equals and printing the result on the console. If we look at the intellisense, we can see that there are two Equals method for int, one of them takes object as parameter and that’s the overridden Object.Equals method, other one takes an integer as parameter, this Equals method is implementation of IEquatable<int> by integer type, and this is the overload which will be used for comparison of the above example code, because in both Equals call we are passing integer as parameter not object, so the compiler will pick the overload defined for IEquatable<int> as it is the best signature match.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfAkLcpCL8tz2_swes3UgrQcsHhdse3fHjPiAO0cv_30lkyE2iP1wgh4rsrE7ITMhwG3lgUUW7Esiz5LJeD-pACCzZLFdtmddyqlivQa3he-46XEb7wD9fB2EQMY9Hez5Cay-AgBXCsMnp/s1600/intellisense.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfAkLcpCL8tz2_swes3UgrQcsHhdse3fHjPiAO0cv_30lkyE2iP1wgh4rsrE7ITMhwG3lgUUW7Esiz5LJeD-pACCzZLFdtmddyqlivQa3he-46XEb7wD9fB2EQMY9Hez5Cay-AgBXCsMnp/s1600/intellisense.png" /></a></div>
<br />
This is obviously very unnatural way to compare integers, normally we just write like:<br />
<br />
<pre class="brush: csharp"> Console.WriteLine(num1 == num2);
</pre>
<br />
We have written the code via Equals method so that you can see that there are two Equals method out there. All primitive supports provide the implementation for IEquatable<T> interface. Just take the above example, int implements the IEquatable<int>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw7GHeAFi3u8Xpif4wuZAyL-xcGy___fO7ea6am9kMQIblNV_15MrgjOYTdC-RcPN3QFe6Ahe8jS3XBo5XjOXDjo7FJ6C-4onhyzkoXsn6sChrKb47Ha7iMLmDXQhb_GzrZ2KbMjmzTZbZ/s1600/Int32.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw7GHeAFi3u8Xpif4wuZAyL-xcGy___fO7ea6am9kMQIblNV_15MrgjOYTdC-RcPN3QFe6Ahe8jS3XBo5XjOXDjo7FJ6C-4onhyzkoXsn6sChrKb47Ha7iMLmDXQhb_GzrZ2KbMjmzTZbZ/s1600/Int32.png" /></a></div>
<br />
<div class="MsoNormal">
Likewise other primitive types also implement
IEquatable<T>. Generally IEquatable<T> is very useful for value
types. Unfortunately Microsoft had not been very consistent about implementing
it for non-primitive value types in the Framework Class Library, so you can’t
always rely on this interface to be available</div>
<h1>
IEquatable<T> and Reference Types</h1>
<div class="MsoNormal">
.IEquatable<T> is not that much useful for reference
types as it is for value types. Because for reference types there is not really
any performance issues like we had for value types (boxing) which needs fixing
and also for the reason that IEquatable<T> does not play nicely with
inheritance.</div>
<div class="MsoNormal">
<br /></div>
But it is worth noting here that String which is
a reference type does implements IEquatable<T>.<span style="mso-spacerun: yes;"> </span>If you recall from the Part – 2, when we were
demonstrating the Equals method for string we were explicitly casting the
string variable to object.<br />
<br />
<pre class="brush: csharp"> static void Main(String[] args)
{
string s1 = "Ehsan Sajjad";
string s2 = string.Copy(s1);
Console.WriteLine(s1.Equals((object)s2));
}
</pre>
<br />
<div class="MsoNormal">
That was to make sure that it call the Object.Equals
override which takes object as parameter, if we don’t do that then compiler
will pick the strongly typed Equals method and that method is actually the
implementation of IEquatable<string> implemented by String . String is a
sealed class so you cannot inherit from it, so the issue of conflict between
Equality and Inheritance does not arise.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Obviously you would expect that when both Equals method are
available on a type, the virtual Object.Equals method and the
IEquatable<T> Equals method, they should always give the same result.
That’s’ true for all the Microsoft implementations and it’s one of the things
that is expected of you when you implement this interface yourself.</div>
<div class="MsoNormal">
If you want to implement IEquatable<T> interface, then
you should make sure that you override the Object.Equals method to do exactly
the same thing as your interface method does and that makes sense, because it
should be clear that if a type implements two versions of Equals that behave
differently, then developers who will consume your type will get very confused.
</div>
<h1>
Summary</h1>
<div class="MsoListParagraph" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font: 7.0pt "Times New Roman";">
</span></span></span>We saw that we can implement IEquatable<T>
on our types to provide a strongly typed Equals method which also avoids boxing
for value types.</div>
IEquatable<T> is implemented for<span style="mso-spacerun: yes;"> </span>primitive numeric types but unfortunately
Microsoft has not been very proactive<span style="mso-spacerun: yes;">
</span>implementing for other value types in the Framework Class Library</div>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com1tag:blogger.com,1999:blog-5386436084600983822.post-2380224050216092602016-06-26T17:29:00.000-07:002016-06-30T11:58:17.939-07:00Story of Equality in .Net - Part 2<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<h1>
Introduction</h1>
<div class="MsoNormal">
In this post, we will see how smartly .Net handles equality and
comparison out of the box. This means that you will be able to understand how
.Net handles some of the issues that we discussed in the <b><a href="http://developmentpassion.blogspot.com/2016/06/story-of-complex-equality-in-net.html">previous post</a></b>.<br />
<br /></div>
<div class="MsoNormal">
If you remember from previous post,there are 4 methods in Object class which are provide by .Net framework for the purpose of equality checking but each one is designed for different scenarios but their purpose is same which is to check equality of two objects. In this post we will be focusing on the following three methods out of the four which are:<br />
<ol style="text-align: left;">
<li><b><a href="https://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx">virtual Object.Equals</a></b></li>
<li><b><a href="https://msdn.microsoft.com/en-us/library/w4hkze5k(v=vs.110).aspx">static Object.Equals</a></b></li>
<li><b><a href="https://msdn.microsoft.com/en-us/library/system.object.referenceequals(v=vs.110).aspx">static Object.ReferenceEquals </a></b></li>
</ol>
<br />
We will start by looking in detail at the virtual <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx">Object.Equals</a></b>
method. This provides the most important mechanism for equality checking in
.Net, since it is the means by which any type can tell what equality means for
itself. We will see how out of the box this method gives you reference equality
for most reference types but value equality for all value types.</div>
<div class="MsoNormal">
We will also compare it with the static method <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/w4hkze5k(v=vs.110).aspx">Object.Equals()</a></b>
which is of same name which is more robust when the scenario is that instances
to be checked for equality can be null.</div>
<div class="MsoNormal">
<br />
We will also see how we can guarantee that the equality
check is done on the reference of instances not the values of the instances
using the static <a href="https://msdn.microsoft.com/en-us/library/system.object.referenceequals(v=vs.110).aspx" target=""><b style="mso-bidi-font-weight: normal;">Object.ReferenceEquals</b></a>
method.</div>
<div class="MsoNormal">
</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
After reading this post, I hope that you will have a good
understanding what equality means in .Net.<br />
<br />
<h1>
Virtual Object.Equals() Method</h1>
<div class="MsoNormal">
As we discussed in the previous post as well, in .Net there
are number of ways to compare equality, but the most fundamental way .Net
provides for this purpose is the <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx">virtual
Object.Equals()</a></b> method defined in the <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.object(v=vs.110).aspx">System.Object</a></b>
type.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
To see this method in action, we will create a class which
represents a kind of person. The only thing our class contains is a string
field containing the name of the person and a constructor that enforces to set
the value of the name field.<br />
<br />
<pre class="brush: csharp"> public class Person
{
private string _name;
public string Name
{
get
{
return _name;
}
}
public Person(string name)
{
_name = name;
}
public override string ToString()
{
return _name;
}
}
</pre>
Now we will write the Main method to use this type.<br />
<br />
<pre class="brush: csharp"> static void Main(String[] args)
{
Person p1 = new Person("Ehsan Sajjad");
Person p2 = new Person("Ahsan Sajjad");
Console.WriteLine(p1.Equals(p2));
}
</pre>
<br />
<br />
<div class="MsoNormal">
As you can see in Main we are creating two instances of
Person class passing different value as parameter to the constructor, and then
on the next line we are checking for equality using the <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx">Object.Equals</a></b>
method. The equal method returns a Boolean, it returns true if both items are
equals and false if they are not equal, we are writing the result of the
equality comparison on the console to see what it outputs.</div>
<div class="MsoNormal">
You would hope from the code that the two instances are not
equal as <b style="mso-bidi-font-weight: normal;">“Ehsan Sajjad” </b><span style="mso-spacerun: yes;"> </span>and <b style="mso-bidi-font-weight: normal;">“Ahsan
Sajjad”</b> are not equal they have different sequence of characters, and of
course if we run the code we will see false as output on the console. So <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx">Equals()</a></b>
appears to be working right here and if you notice we didn’t have to do anything
in our <b style="mso-bidi-font-weight: normal;">Person </b>class definition to
achieve this. The <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx">Equals</a></b>
method is provided by <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.object(v=vs.110).aspx">System.Object<span style="font-weight: normal;"> </span></a></b><span style="mso-spacerun: yes;"> </span>so it is automatically available on all types,
because all types ultimately derive from <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.object(v=vs.110).aspx">System.Object</a></b>
</div>
<div class="MsoNormal">
By the way I suspect some of you may be looking at this code
and thinking that the line <b style="mso-bidi-font-weight: normal;">p1.Equals(p2)</b>
is not what we write normally for checking equality, if we want to check for
equality, we just write this <b style="mso-bidi-font-weight: normal;">p1 == p2</b>,
but the point here is we need to understand how equality works in .Net and the
starting point for that is the Equals method.</div>
<h1>
== Operator and Equals Method</h1>
<div class="MsoNormal">
If you write <b style="mso-bidi-font-weight: normal;">== </b>in
your code, you are using the C# equality operator and that is a very nice
syntactical convenience C# language provides to make the code more readable but
it is not really part of the .Net Framework. .Net has no concept of operators,
it works with methods. If you want to understand how equality works in .Net
then we need to start with the things that .Net Framework understands. So we
will only be using .Net methods in this post for most of the code, so you can
see how it works , that means some of the code<span style="mso-spacerun: yes;">
</span>you will see may look un-natural<span style="mso-spacerun: yes;">
</span>but we will discuss<span style="mso-spacerun: yes;"> </span>the <b style="mso-bidi-font-weight: normal;">==</b> (c# equality operator) in another
post.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Now let’s get back to the fun part i.e. code, we will
declare another instance of Person in the Main program </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
This new instance p3 also passes same value in the
constructor as p1 which is <b style="mso-bidi-font-weight: normal;">“Ehsan Sajjad”</b>,
so what do you think what will happen if we try to compare p1 with p3 using the
Equals method, let’s try and see what happens:</div>
<br />
<pre class="brush: csharp"> static void Main(String[] args)
{
Person p1 = new Person("Ehsan Sajjad");
Person p2 = new Person("Ahsan Sajjad");
Person p3 = new Person("Ehsan Sajjad");
Console.WriteLine(p1.Equals(p3));
}
</pre>
<br />
<br />
<div class="MsoNormal">
This also returns false, these two instances p1 and p3 are
not equal and the reason is the base Object.Equals method evaluates reference
equality, its implementation tests <span style="mso-spacerun: yes;"> </span>whether two variables refers to the same
instance, in this case it is obvious to us and that p1 and p3 have exactly the
same value, both instances contains the same data but Equals method does not
care about that, it care only about that they are same or different instances,
so it returns false telling us that they are not equal.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
As we discussed earlier in this post and in previous post as
well that Equals is a virtual method in Object type which means that we can
override it, if we want the Equals method to compare the values of the Person
instances, we can override the Equals method<span style="mso-spacerun: yes;">
</span>and can define our own implementation for how to compare two Person
instances for equality, there is nothing unusual in this, Equals is a normal
virtual method, we are not going to override it yet though, if you want to
stick to good coding practices you need to do few other things when you
override Object.Equals method, we will see later how to do that, for this post
we will just stick to what Microsoft has given us<span style="mso-spacerun: yes;"> </span>out of the box.</div>
<div class="MsoNormal">
<br /></div>
<h1>
Equals Method Implementation for String</h1>
There are
couple of reference types for which Microsoft has overridden the Object.Equals
method in order to compare values instead of references, probably the well know
of these and certainly the one that’s most important to be aware of is <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.string(v=vs.110).aspx">String</a></b>,
we will examine with a small program the demonstration of that:</div>
<br />
<pre class="brush: csharp"> static void Main(String[] args)
{
string s1 = "Ehsan Sajjad";
string s2 = string.Copy(s1);
Console.WriteLine(s1.Equals((object)s2));
}
</pre>
<br />
<br />
<div class="MsoNormal">
In this program we initialize a string and store it’s
reference in s1, then we create another variable s2 which contains the same
value but we initializer s2 by creating a copy of the value s1 has, string.Copy
method’s name is pretty descriptive, it creates and returns the copy of the
string and then we are using Equals method to compare them.</div>
<div class="MsoNormal" style="text-align: justify;">
You can see that we are casting
argument of Equals method explicitly to <b style="mso-bidi-font-weight: normal;">object
</b>type that obviously you would not want to do in the production code, the
reason we have done that here is to make sure that implementation of <a href="https://msdn.microsoft.com/en-us/library/fkfd9eh8(v=vs.110).aspx">override
of <b style="mso-bidi-font-weight: normal;">Object.Equals()</b></a><b style="mso-bidi-font-weight: normal;"> </b>is called, as string define <a href="https://msdn.microsoft.com/en-us/library/system.string.equals(v=vs.110).aspx">multiple
Equals method</a> and <a href="https://msdn.microsoft.com/en-us/library/858x0yyx(v=vs.110).aspx">one of
them</a> is strongly type to string i.e. it<span style="mso-spacerun: yes;">
</span>takes string as parameter, if we didn’t cast it to object then the
compiler would have considered the strongly typed method a better parameter
when resolving overloads and would have called that one, that is obviously<span style="mso-spacerun: yes;"> </span>better when we are normally programming and
both method will actually do the same thing<span style="mso-spacerun: yes;">
</span>but we explicitly wanted to show how the <b style="mso-bidi-font-weight: normal;">object.Equals</b> override behaves, so we needed to cast parameter to
object to tell the compiler to avoid strongly typed overload and use the object
type override.</div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
If we run the above code will see
that it returns true. The override provided by Microsoft for string type
compares the contents of the two string instances to check whether they
contains exactly the same characters in the same sequence and returns true if
they are otherwise returns false, even if they are not the same instance.</div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
There are not many Microsoft
defined reference types for which Microsoft has overridden Equals method to
compare values, apart from String type, two others types that you must be aware
of are<b style="mso-bidi-font-weight: normal;"> <a href="https://msdn.microsoft.com/en-us/library/900fyy8e.aspx">Delegate</a></b>
and <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx">Tuple</a></b>,
calling Equals on these two will also compare the values, these are the
exceptional ones all other reference types Equals will always do Reference
equality check.</div>
<h1>
Equals Method and Value Types</h1>
<span style="font-family: "calibri" , "sans-serif"; font-size: 11.0pt; line-height: 107%;">Now we will see how Equals method works for
value types, we will be using the same example that we used at start of the
post (Person class ) but we will change it to <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/ah19swz4.aspx">struct</a></b>
instead of class for seeing the behavior in case of value type</span></div>
<br />
<pre class="brush: csharp"> public struct Person
{
private string _name;
public string Name
{
get
{
return _name;
}
}
public Person(string name)
{
_name = name;
}
public override string ToString()
{
return _name;
}
}
</pre>
<br />
What you think what will happen now if we run the same program again, as we know struct is stored on the stack, they don’t have references normally unless we box them, that’s why they are called value type not reference type</div>
<pre class="brush: csharp"> static void Main(String[] args)
{
Person p1 = new Person("Ehsan Sajjad");
Person p2 = new Person("Ahsan Sajjad");
Person p3 = new Person("Ehsan Sajjad");
Console.WriteLine(p1.Equals(p2));
Console.WriteLine(p1.Equals(p3));
}
</pre>
<br />
So as we know that the implementation of Object.Equals do the reference comparison in case of reference types but in this case you might think that comparing references does not makes sense as struct is a value type.<br />
<br />
So let’s run the program and see what it prints on the console.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhcSSQf-Sw8pGFPHayAXUs2QJoMj20MtfDEtnAahlLx60ImHEkhfe5A9EaU9EN0koaUCg_UveVW1bfqGq8I0w5NnR1chzl8tPqqXcizU-q3hyQodz9qcls9OvudVqQpxtADkW5Zvdv6o9n/s1600/equals+value+types.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhcSSQf-Sw8pGFPHayAXUs2QJoMj20MtfDEtnAahlLx60ImHEkhfe5A9EaU9EN0koaUCg_UveVW1bfqGq8I0w5NnR1chzl8tPqqXcizU-q3hyQodz9qcls9OvudVqQpxtADkW5Zvdv6o9n/s1600/equals+value+types.PNG" /></a></div>
<br />
You can see that this time the result is different, for the second case it is saying that both instances are equal, it is exactly the result you would expect if you were to compare the values of both p1 and p3 instances of Person to see if they were equal and that is actually happening in this case, but if we look at the Person type definition we have not added any code for overriding the Equals method of Object class, which means there is nothing written in this type to tell the framework that how to compare the values of instances of Person type to see if they are equal.<br />
<br />
<br />
<div class="MsoNormal">
.Net already knows all that, it knows how to do that, .Net
framework has figured out without any effort from us that how to tell p1 and p3
have equal values or not, how is that happening. What actually happening is
that as you may already know that all <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/ah19swz4.aspx">struct</a></b> types
inherits from <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.valuetype(v=vs.110).aspx">System.ValueType</a>
</b>which ultimately derives from <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.object(v=vs.110).aspx">System.Object</a></b>.</div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.valuetype(v=vs.110).aspx">System.ValueType</a></b>
itself overrides the System.Object Equals method, and what the override does is
that it traverses all the fields in the value type and call Equals against each
one until it either finds any field value that is different or all fields are
traversed, if all the fields turn out to be equal, then it figures out that
these two value type instances are equal. In other words, value types override the
Equals method implementation and says that both instances are equal if every
field in them has same value which is quite sensible. In the above example our
Person type has only one field in it which is the backing field for the Name
property which is of type string and we already know that calling Equals on
string compares values and the above results of our program proves what we are
stating here. That’s how .Net provides the behavior of Equals method for value
types very nicely.</div>
<h1>
Performance Overhead for Value Types</h1>
<div class="MsoNormal">
Unfortunately, this convenience provide by .Net framework
comes with a price. The way <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.valuetype(v=vs.110).aspx">System.ValueType</a></b>
Equals implementation works is by using Reflection. Of course it has to if we
think about it. As <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.valuetype(v=vs.110).aspx">System.ValueType</a></b>
is a base type and it does not know about how you will derive from it, so the
only way to find out what fields in out defined type (in this case Person) has
is to do it using Reflection which means that performance would be bad</div>
<h1>
Recommended Approach for Value Types</h1>
<div class="MsoNormal">
The recommend way is to override the Equals method for you
own value types which we will see later how to provide that in a way that it
runs faster, in fact you will see that Microsoft has done that for many of the
built-in value types that comes with the framework which we use every day in
our code.</div>
<div class="MsoNormal">
<br /></div>
<h1>
Static Equals Method</h1>
<div class="MsoNormal">
There is one problem when checking for equality using the
virtual Equals method. What will happen if one or both of the references you
want to compare is <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/edakx9da.aspx">null</a></b>. Let’s
see what happens when we call Equals method with null as argument. Let’s modify
the existing example for that:</div>
</div>
<br />
<pre class="brush: csharp"> static void Main(String[] args)
{
Person p1 = new Person("Ehsan Sajjad");
Console.WriteLine(p1.Equals(null));
}
</pre>
<br />
If we compile this and run, it returns false and it should and makes perfect sense because it is obvious that null is not equal to non-null instance and this is the principle of Equality in .Net that Null should never evaluate as equal to Non-Null value.<br />
<br />
Now let’s make it vice versa to see what will happen if the p1 variable is null, then we have a problem. Consider that we don’t have this hardcoded instance creation code instead of that this variable is passed as parameter from some client code which uses this assembly and we don’t know if either of the value is null.<br />
If p1 is passed as null, executing the Equals method call will throw a Null Reference Exception, because you cannot call instance methods against null instances.<br />
The Static Equals method was designed to address this problem, so we can use this method if we are not aware if one of the objects could be null or not, we can use it this way:</div>
<br />
<pre class="brush :csharp"> Console.WriteLine(object.Equals(p1,null));
</pre>
<br />
Now we are good to go without worrying about if either of the instance reference is null, you can test it by running with both scenarios and you will see it works fine, and of course it would return false if one of the reference variable is null.<br />
<br />
Some of you may be wondering that what would happened if both the arguments passed to Static Equals method are null, if you add the following line to test that:</div>
<br />
<pre class="brush: csharp"> Console.WriteLine(object.Equals(null,null));
</pre>
<br />
You will see that it returns true in this case, in .Net null is always equal to null, so testing whether null is equal to null should always evaluate to true.<br />
<br />
If we dig in to the implementation Static Equals method we will find that it is very simple implementation. Following is the logic of it if you look in to the source code of Object type:</div>
<br />
<pre class="brush: csharp">public static bool Equals(object x, object y)
{
if (x == y) // Reference equality only; overloaded operators are ignored
{
return true;
}
if (x == null || y == null) // Again, reference checks
{
return false;
}
return x.Equals(y); // Safe as we know x != null.
}
</pre>
<br />
<br />
<div class="MsoNormal">
If first checks if both parameters refer to the same instance
i.e. what == operator will do, this check will evaluate to true causing method
to return true if both the parameters are null, the next if block will return
false if one of the parameters is null and other one is not, finally if control
reaches the else block then we know that both parameter point to some instance,
so we will just call the virtual Equals method.</div>
<div class="MsoNormal">
This means that the static Equals method will always give
the same result as the virtual method<span style="mso-spacerun: yes;">
</span>except that it checks for null first, as static method call the virtual
method, if we override the virtual Equals method, our override will
automatically be<span style="mso-spacerun: yes;"> </span>picked by the static
method, that’s important as we want both static virtual methods to behave
consistently.</div>
<div class="MsoNormal">
<br /></div>
<h1>
ReferenceEquals Method</h1>
<div class="MsoNormal">
ReferenceEquals serves a slightly different purpose from the
two Equals method which we have discussed above. It exists for those situations
where we specifically want to determine whether the two variables refer to the
same instance. You may have question in mind that Equals method also checks reference
equality then why a separate method.</div>
<div class="MsoNormal">
Those two methods do check reference equality, but they are
not guaranteed to do so, because the virtual Equals method can be overridden to
compare values of the instance not the reference. </div>
<div class="MsoNormal">
So, ReferenceEquals will give the same result as Equals for
types that don’t have overridden the Equals method. For example, take the
Person class example which we used above. But it’s possible to have different
results for types that have overridden the Equals method. For Example, the
String class.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Let’s modify the string class example that we used earlier
in this post to demonstrate this:</div>
</div>
<br />
<pre class="brush: csharp"> static void Main(String[] args)
{
string s1 = "Ehsan Sajjad";
string s2 = string.Copy(s1);
Console.WriteLine(s1.Equals((object)s2));
Console.WriteLine(ReferenceEquals(s1,s2));
}
</pre>
<br />
If we run this example, we will see that the first Equals call returns true just as before, but the ReferenceEquals method call returns false, and why is that?<br />
<br />
It is telling that both string variables are different instances even though they contain the same data and if you recall what we discussed in previous post that String type overrides Equals method to compare the value of two instance not the reference.<br />
<br />
You know that in C# static methods cannot be overridden which means you can never change the behavior of ReferenceEquals method which makes sense because it always needs to do the reference comparison.<br />
<br />
<h1>
Summary </h1>
</div>
</div>
<ul style="text-align: left;">
<li>We learned how .Net provides the types equality implementation out of the box</li>
<li>We saw that few methods are defined by the .Net framework on the Object class which are available for all types .</li>
<li>By default the virtual Object.Equals method does reference equality for reference types and value equality for value types by using reflection which is a performance overhead for value types. </li>
<li>Any type can override Object.Equals method to change the logic of how it checks for equality e.g. String, Delegate and Tuple do this for providing value equality, even though these are reference types.</li>
<li>Object are provides a static Equals method which can be used when there is chance that one or both of the parameters can be null, other than that it behaves identical to the virtual Object.Equals method.</li>
<li>There is also a static ReferenceEquals method which provides a guaranteed way to check for reference equality.</li>
</ul>
<br /></div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-79339416219000576652016-06-19T16:14:00.003-07:002016-08-05T15:07:44.257-07:00Story of Equality in .Net - Part 1<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<br />
<h2 style="text-align: left;">
Background</h2>
<h2 style="text-align: left;">
<span style="-webkit-text-stroke-width: 0px; background-color: white; color: #111111; display: inline !important; float: none; font-family: "Segoe UI", Arial, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">Few months back i followed a very interesting course on <a href="https://www.pluralsight.com/" target="_blank">Pluralsight </a>by </span><a href="http://app.pluralsight.com/author/simon-robinson" style="-webkit-text-stroke-width: 0px; background-color: white; border: 0px; color: purple; font-family: "Segoe UI", Arial, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin: 0px; orphans: auto; padding: 0px; text-align: start; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">Simon Robinson</a><span style="-webkit-text-stroke-width: 0px; background-color: white; color: #111111; display: inline !important; float: none; font-family: "Segoe UI", Arial, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;"> about </span><a href="https://app.pluralsight.com/library/courses/csharp-equality-comparisons/table-of-contents" style="-webkit-text-stroke-width: 0px; background-color: white; border: 0px; color: purple; font-family: "Segoe UI", Arial, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin: 0px; orphans: auto; padding: 0px; text-align: start; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">Equality and Comprison in .Net</a><span style="-webkit-text-stroke-width: 0px; background-color: white; color: #111111; display: inline !important; float: none; font-family: "Segoe UI", Arial, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;"> which is a great course indeed that would help developers to understand that how equlity and comparisons work in .Net, So i thought to shared the insights of it what i have learned from the course, hope this will help others to understand the equality behaviour and in depth understnading of how .Net handles it.</span> </h2>
<h2 style="text-align: left;">
Introduction</h2>
The purpose of this post is to outline and explore some of the issues that makes performing the equality much more complex than you might expect. Among other things, we will examine the difference between the value and reference equality and why equality and inheritance don’t work well together. So let’s get started.<br />
<br />
<a href="https://www.blogger.com/blogger.g?blogID=5386436084600983822" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=5386436084600983822" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a>We will start from a simple example that will compare two numbers. For instance let’s say that 3 is less than 4, conceptually it is trivial and the code for that is also very easy and simple:<br />
<br />
<pre class="brush: csharp"> if(3 < 4)
{
}
</pre>
<br />
<br />
<div class="MsoNormal">
If you look at the <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.object(v=vs.110).aspx">System.Object</a></b>
class from which all other types inherit, you will find the following 4 methods
which are for equality checking:<br />
<br />
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/w4hkze5k(v=vs.110).aspx">static
Equals()</a></span></b></div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx">virtual
Equals()</a></span></b></div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/system.object.referenceequals(v=vs.110).aspx">static
ReferenceEquals()</a></span></b></div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/system.object.gethashcode(v=vs.110).aspx">virtual
GetHashCode()</a></span></b></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<a href="https://www.blogger.com/blogger.g?blogID=5386436084600983822" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a>In addition to that Microsoft has provided 9 different
interfaces for performing equality or comparison of types:</div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx">IEquatable<T></a></span></b></div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/system.icomparable(v=vs.110).aspx">IComparable</a></span></b></div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/4d7sx9hd(v=vs.110).aspx">IComparable<T></a></span></b></div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/system.collections.icomparer(v=vs.110).aspx">IComparer</a></span></b></div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/system.collections.icomparer(v=vs.110).aspx">IComparer<T></a></span></b></div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/ms132151(v=vs.110).aspx">IEqualityComparer</a></span></b></div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/ms132151(v=vs.110).aspx">IEqualityComparer<T></a></span></b></div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/system.collections.istructuralequatable(v=vs.110).aspx">IStructuralEquatable</a></span></b></div>
<div class="MsoNormal">
<b style="mso-bidi-font-weight: normal;"><span style="font-size: 16.0pt; line-height: 107%;"><a href="https://msdn.microsoft.com/en-us/library/system.collections.istructuralcomparable(v=vs.110).aspx">IStructuralComparable</a></span></b></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Most of these method and interfaces come with a risk that if
you override their implementation incorrectly, it will cause bugs in your code
and can will also break the existing collections provided by the framework
which depend on them</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<a href="https://www.blogger.com/blogger.g?blogID=5386436084600983822" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a>We will see what’s the purpose of these method and
interfaces is and how to use these them correctly. We will also focus on How to
provide custom implementation for equality and comparisons in the right way,
which will perform efficiently and follows best practices and most importantly
does not break other types implementation.<br />
<h2 style="text-align: left;">
Equality is Difficult</h2>
</div>
<div class="MsoNormal">
There are 4 reasons that make equality complex than you
might expect:</div>
<div class="MsoListParagraphCxSpFirst" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<span style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">1.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>Reference v/s Value Equality</div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<span style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">2.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>Multiple ways to Compare Values</div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<span style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">3.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>Accuracy</div>
<div class="MsoListParagraphCxSpLast" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
<span style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">4.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>Conflict with OOP</div>
<div class="MsoNormal">
<br />
<h2 style="text-align: left;">
Reference V/S Value Equality</h2>
</div>
<div class="MsoNormal">
There is an issue of reference versus value equality, it’s
possible to treat equality either way and unfortunately c# is not being
designed in a way so that it can distinguish between two of these and that can
cause unexpected behavior sometimes, if you don’t understand how these various
operators and method work.</div>
<div class="MsoNormal">
As you know, in C# reference types do not contain actual
value, they contains a pointer to a location in memory that actually holds
those values, which means that for reference types there are two possible ways
to measure the equality.</div>
<div class="MsoNormal">
You can say that do both variables refer to same location in
memory which is called reference equality and known as Identity or you can say
that do the location to which both variables are pointing contains the same
value, even if they are different locations which is called Value Equality.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
We can illustrate the above points using the following
example:</div>
<br />
<pre class="brush: csharp">class Program
{
static void Main(String[] args)
{
Person p1 = new Person();
p1.Name = "Ehsan Sajjad";
Person p2 = new Person();
p2.Name = "Ehsan Sajjad";
Console.WriteLine(p1 == p2);
Console.ReadKey();
}
}
</pre>
<br />
<br />
<div class="MsoNormal">
As you can see in the above example, we have instantiated
two objects of Person class and both contains the same value for Name property,
clearly the above two instances of Person class are identical as they contain
the same values, are they really equal? When we check their equality of both
instances using c# equality operator and runt the example code, it prints out
on the console <b style="mso-bidi-font-weight: normal;">False </b>as output,
which means that they are not equal.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://www.blogger.com/blogger.g?blogID=5386436084600983822" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihrrSa1m-RkFEcD0S8eIRESI674aVsWO-kmC2lCa5RTY4qyHI6uuRxfqiIcVPovtWJVk2AjQh5RFakJwJ8Hu4zu3LXGSDSmVQZ8vz4v-Dp3SleXNaWnmsq28ZhBCVL0U3mO7LyQrcuI6uV/s1600/false.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihrrSa1m-RkFEcD0S8eIRESI674aVsWO-kmC2lCa5RTY4qyHI6uuRxfqiIcVPovtWJVk2AjQh5RFakJwJ8Hu4zu3LXGSDSmVQZ8vz4v-Dp3SleXNaWnmsq28ZhBCVL0U3mO7LyQrcuI6uV/s1600/false.png" /></a></div>
<br />
<br />
<div class="MsoNormal">
It is because for Person class both C# and the .Net
framework considers the equality to be the Reference Equality. In other words,
the Equality operator checks whether these two variable refer to the same
location in memory, so in this example, they are not equal because though both
instances of Person class are identical but they are separate instances, the
variables <b style="mso-bidi-font-weight: normal;">p1 </b>and <b style="mso-bidi-font-weight: normal;">p2</b> both refer to different locations in
memory.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Reference Equality is very quick to perform, because you
only need to check for one thing whether the two variable holds the same memory
address, while comparing values can be a lot slower.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
For Example, if Person class holds a lot of fields and
properties instead of just one, and if you wanted to check if the two instances
of Person class have same values, you will have to check every field/property,
there is no operator in C# which would check the value equality of two Person
class instances which is reasonable though, because comparing two instances of
Person class containing exactly the same values is not the sort of thing you
would normally want to do, obviously if for some reason you would want to do
that you will need to write your own code to do that.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Now take this code as example:<br />
<br />
<pre class="brush: csharp">class Program
{
static void Main(String[] args)
{
string s1 = "Ehsan Sajjad";
string s2 = string.Copy(s1);
Console.WriteLine(s1 == s2);
Console.ReadKey();
}
}
</pre>
The above code is quite similar to previous example code, but in this case we are applying equality operator on to identical strings, we instantiated a string and stored it’s reference in a variable named s1, then we created copy of its value and hold that in another variable s2, now if we run this code, we will see that according to output we can say that both strings are equal.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN-ZS0DEl0BMcI1Llz3_9hThMJVwggQPMZrLWCQ09UjVuCulTZ6DHrvDtfeIWMbILpQlkCducw_WIW0BGiyWpCiiRoFdGkT_5S3dCYM1X0yWKlUOmbMBNep4um7lEJvIoVLDDgGVHjhfMZ/s1600/true.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN-ZS0DEl0BMcI1Llz3_9hThMJVwggQPMZrLWCQ09UjVuCulTZ6DHrvDtfeIWMbILpQlkCducw_WIW0BGiyWpCiiRoFdGkT_5S3dCYM1X0yWKlUOmbMBNep4um7lEJvIoVLDDgGVHjhfMZ/s1600/true.png" /></a></div>
<br />
<br />
<div class="MsoNormal">
If the equality operator had been checking for reference
equality, we would had seen <b style="mso-bidi-font-weight: normal;">false</b>
printed on the console for this program, but for strings == operator evaluates
equality of values of the operands.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Microsoft has implemented it like that, because checking
whether one string contains another string is something a programmer would very
often need to do.</div>
<div class="MsoNormal">
<h2 style="text-align: left;">
Reference and Value Types</h2>
The reference and value issue only exists for Reference
Types by the way. For unboxed value types for such as integer, float etc the
variable directly contains the value, there are no references which means that
equality only means to compare values.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The following code which compares two integers will evaluate
that both are equal, as the equality operator will compare the values that are
hold by the variables.</div>
<br />
<pre class="brush: csharp">class Program
{
static void Main(String[] args)
{
int num1 = 2;
int num2 = 2;
Console.WriteLine(num1 == num2);
Console.ReadKey();
}
}
</pre>
<br />
<br />
<div class="MsoNormal">
So in the above code the equality operator is comparing the
value stored in variable <b style="mso-bidi-font-weight: normal;">num1 </b>with
the value stored in <b style="mso-bidi-font-weight: normal;">num2</b>.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
However if we modify this code and cast both variables to
object, as we did in the following lines of code:</div>
<pre class="brush: csharp">int num1 = 2;
int num2 = 2;
Console.WriteLine((object)num1 == (object)num2);
</pre>
<br />
<br />
<div class="MsoNormal">
Now if we run the code, you will see that the result in
contradictory with the result we got from the first version of code, which is
the second version of code comparison returns <b style="mso-bidi-font-weight: normal;">false</b>, that happened because the object is a reference type, so
when we cast integer to object, it ends up boxed in to object as reference,
which means the second code is comparing references not values and it returns
false because both integers are boxed in to different reference instances.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
This is something that a lot of developers don’t expect,
normally we don’t cast value types to object, but there is another common
scenario that we often see is that if we need to cast value type in to an
interface.</div>
<br />
<pre class="c#" name="code">Console.WriteLine((IComparable<int>)num1 == (IComparable<int>)num2);
</int></int></pre>
<br />
<br />
<div class="MsoNormal">
For illustrating what we said above, let’s modify the
example code to cast the integer variables to <b style="mso-bidi-font-weight: normal;">ICompareable<int></b>. This is an interface provided by .Net
framework which integer type inherits or implements, we will talk about it in
some other post about it.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
In .Net interfaces are always reference types, so the above
line of code involves boxing too, and if we run this code, we will see that
this equality check also returns false, and it’s because this is again checking
reference equality.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
So, you need to be careful when casting values types to
interfaces, it will always result in reference equality if you do equality
check.</div>
<div class="MsoNormal">
<h2 style="text-align: left;">
== Operator</h2>
All this code would probably not had been a problem, if C#
had different operators for value-types and reference types equality, but it
does not, which some developers think is a problem. C# has just one equality
operator and there is no obvious way to tell upfront what the operator is
actually going to do for a given type.</div>
<div class="MsoNormal">
For instance consider this line of code:</div>
<br />
<pre class="brush: csharp">Console.WriteLine(var1 == var2)
</pre>
<br />
<br />
<div class="MsoNormal">
We cannot tell what the equality operator will do in the
above, because you just have to know what equality operator does for a type,
there is no way around, that’s how C# is designed.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
In this post we will go through, what the equality operator
does and how it works under the hood in detail, so after reading the complete
post, I hope you will have a much better understanding than other developers
that what actually happens when you write an equality check condition and you
will be better able to tell how equality between two objects is evaluated and
will be able to answer correctly whenever you came across the code where two
objects are being compared for equality.</div>
<div class="MsoNormal">
<h2 style="text-align: left;">
Different Ways to Compare Values </h2>
Another issue that exists in that complexity of equality is,
there are often more than one ways to compare values of a given type. String
type is the best example for this. Suppose we have two string variable the
contain the same value in them:</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<pre class="brush: csharp"> string s1 = "Equality";
string s2 = " Equality";
</pre>
<br />
<div class="MsoNormal">
Now if compare both s1 and s2, should we expect that the
result would be true for equality check? Means should we consider these two
variables to be equal?</div>
<div class="MsoNormal">
I am sure you are looking as both string variables contains
exactly same values, then it makes sense to consider them equal, and indeed
that is what c# does, but what if I change the case of one of them to make them
different<span style="mso-spacerun: yes;"> </span>like:</div>
<br />
<pre class="brush: csharp"> string s1 = "EQUALITY";
string s2 = "equality";
</pre>
<br />
Now should these two strings to be considered equal? In C# the equality operator will evaluate to false saying that the two strings are not equal, but if we are not asking about C# equality operator, but about in Principle we should consider those two strings as equal then we cannot really answer, as it completely depends on the context whether we should consider or ignore the case, Let’s say I have a database of food items, and we are querying a food item to be searched from database, then the changes are we want to ignore the case and treat the both string equal, but if the user is typing in password for logging in to an application, and you have to check if the password entered by user is correct, then you should not certainly consider the lower case and title case strings to be equal.<br />
<br />
The equality operator for strings in C# is always case sensitive, so you can’t use it for comparison and ignore the case. If you want to ignore the case, you can do but you will have to call the special methods which are defined in the String type. For Example:</div>
<br />
<pre class="brush: csharp">
string s1 = "EQUALITY";
string s2 = "equality";
if(s1.Equals(s2,StringComparison.OrdinalIgnoreCase))
</pre>
<br />
The above example will evaluate if statement to true as we are telling to ignore the case when doing comparison for equality between s1 and s2.<br />
<br />
Now I am sure that none of that will surprise you. Case sensitivity is an issue that almost everyone encounters very early on when they do programming. From the above example we can illustrate a wider point for equality in general that Equality is not absolute in programming, it is often context-sensitive (e.g. case-sensitivity of string)<br />
<br />
One example of this is that user is searching for an item on a shopping cart web application and user types an item name with extra whitespace in it, but when we are comparing that with items in our database, so should we consider the item in our database equal to the item entered by user with whitespace, normally we consider them equal and display that result to user as a result of searching, which again illustrates that equality is context sensitive.<br />
<br />
Let’s take one more example, consider the following two database records:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2vKoDuFvd8-ofRiTY7REGtkwoMZKLkvPPv65Z9EBoaxkD0QwQZJ0yXyc4vd4A_On45gpdsf8uSlyFoC2Hc0NawQyDmL2iPWG822HDUY4smcJOEqNcYPxr-gonGBrGHxBGHX55b8b-OdsY/s1600/Capture.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2vKoDuFvd8-ofRiTY7REGtkwoMZKLkvPPv65Z9EBoaxkD0QwQZJ0yXyc4vd4A_On45gpdsf8uSlyFoC2Hc0NawQyDmL2iPWG822HDUY4smcJOEqNcYPxr-gonGBrGHxBGHX55b8b-OdsY/s1600/Capture.PNG" /></a></div>
<br />
<br />
Are the equal? In one sense Yes. Obviously these are the same records, they refer to the same drink item and they have the same primary key, but couple of columns value are different, it is clear that the second records item is the data after the records was updated and the first one is before updating, so this illustrates another conceptual issue with equality which comes in to play when you are updating data. Do you care about the precise values of the record or do you care whether it is the same record and clearly there is no one right answer to that. So once again it depends on the context what you are trying to do!<br />
<div class="MsoNormal">
<h2 style="text-align: left;">
Equality and Comparison</h2>
The way .Net deals with multiple meanings of equality is
quite neat. .Net allows each type to specify its own single natural way of
measuring equality for that type. So, for example, String type defines it’s
natural equality to be if two strings contains exactly same sequence of
characters, that’s why comparing two strings with different case returns false
as they contains different character. This is because “<b style="mso-bidi-font-weight: normal;">eqaulity” </b>is not equal to <b style="mso-bidi-font-weight: normal;">“EQUALITY”</b>
as lower case and uppercase are different characters.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
It is very common that the types expose their natural way of
determining equality by means of a generic interface called <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx">IEquatable<T></a></b>.
String also implements this interface for equality. But separately .Net also
provides a mechanism for you to plug in a different implementation of equality
if you don’t like the Type’s own definition or if that does not fulfill your
needs.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
This mechanism is based on what is known as Equality
Comparers. An Equality Comparer is an object whose purpose is to test whether
instances of a type are equal using the definition provided by the comparer for
checking equality.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Equality Comparers implement an interface called <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/ms132151(v=vs.110).aspx">IEqualityComparer<T></a></b>.
So for example, if you want to compare string ignoring the extra whitespaces,
you could write an equity comparer that knows how to do that and then use that
equality comparer instead of the equality operator as required.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Things work basically the same way for doing ordering
comparisons. The main difference is that you would use different
interfaces.<span style="mso-spacerun: yes;"> </span>.Net also provides an
interface to provide mechanism for a type to do less than or greater then
comparison for a type which is known as<b style="mso-bidi-font-weight: normal;"> <a href="https://msdn.microsoft.com/en-us/library/4d7sx9hd(v=vs.110).aspx">ICompareable<T></a></b>,
and separately you can write what are known as comparers which is <b style="mso-bidi-font-weight: normal;"><a href="https://msdn.microsoft.com/en-us/library/system.collections.icomparer(v=vs.110).aspx">IComparer<T></a></b>,
this can be used to define an alternative implementation for comparison done
for ordering, we will see how to implement these interfaces in some other post.<br />
<div class="MsoNormal">
<h2 style="text-align: left;">
Equality for Floating Points</h2>
Some data types are inherently approximate. In .Net you will
encounter this problem with floating point types like <b style="mso-bidi-font-weight: normal;">float</b>,<b style="mso-bidi-font-weight: normal;"> double</b> or <b style="mso-bidi-font-weight: normal;">decimal</b> or any type that contains a
floating point type as a member field. Let’s have a look on an example.</div>
</div>
<br />
<pre class="brush: csharp">
float num1 = 2.000000f;
float num2 = 2.000001f;
Console.WriteLine(num1 == num2);
</pre>
<br />
We have two floating point numbers that are nearly equal. So are they equal? It looks pretty obvious that they are not equal as they differ in the final digit and we are printing the equality result on console, so when we run the code, the program displays true<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhKegkHrajv6-kHDESujqVYNmVXSQWs4hW-n8IpPRQtSAbD1BfOa79L-TOZdVMqTuImEZe2hhXDbwAdWBX7BS6aYm0oK8R2CAJqouOjvjAkmozNga8danT_BsyojVokUlht-VrwAKTDiuA/s1600/true.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhKegkHrajv6-kHDESujqVYNmVXSQWs4hW-n8IpPRQtSAbD1BfOa79L-TOZdVMqTuImEZe2hhXDbwAdWBX7BS6aYm0oK8R2CAJqouOjvjAkmozNga8danT_BsyojVokUlht-VrwAKTDiuA/s1600/true.png" /></a></div>
<br />
This program has come out saying that they both are equal which is completely contradictory to what we have evaluated by looking at the numbers and you can probably guess what the problem is. Computers can only the numbers to a certain level of accuracy and the float type just cannot store the enough significant digits to distinguish these two particular numbers and it can work other way around two, see this example:<br />
<br /></div>
<br />
<pre class="brush: csharp">
float num1 = 1.05f;
float num2 = 0.95f;
var sum = num1 + num2;
Console.WriteLine(sum);
Console.WriteLine(sum == 2.0f);
</pre>
<br />
This is a simple calculation where we are adding 1.05 to 0.95. It looks very obvious that when you add those two numbers you will get the answer 2.0, so we have written a small program for this which adds those two numbers and then we check that the sum of two numbers is equal to 2.0, if we run the program, the output contradicts what we had thought, which says the sum is not equal to 2.0, the reason is that rounding errors happened in the floating point arithmetic resulting in the answer storing a number that is very close to 2, so close that string representation on Console.WriteLine even displayed it as 2 but it’s still not quite equal to 2.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhifsaQVnsQw-v2CH89UMUSY2WTtwrUOczhTXDfuXnkjbppsVCQHrYuHtHySpsX-7eerlVzdSNpVzPIKVfxEumozXWk7b3K9Gmc9hqiFxVk0PQsuN_uM2aiACT8149AGJN-Utoas8aG149n/s1600/float.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhifsaQVnsQw-v2CH89UMUSY2WTtwrUOczhTXDfuXnkjbppsVCQHrYuHtHySpsX-7eerlVzdSNpVzPIKVfxEumozXWk7b3K9Gmc9hqiFxVk0PQsuN_uM2aiACT8149AGJN-Utoas8aG149n/s1600/float.png" /></a></div>
<br />
<br />
<div class="MsoNormal">
Those rounding errors in floating point arithmetic has
resulted in the program to give the opposite answer to what any common sense
reasoning would tell you. Now this is an inherent difficulty with the floating
point numbers. Rounding error means that testing for equality often give you
the wrong result and .Net has no solution for this. The recommendation is, you
don’t try to compare floating point numbers for equality because the results
might not be what you predict. This only applies to equality, this problem does
not normally affect the less than an greater than comparisons, in most cases
there are no problems with comparing the floating points number to see whether
one is greater than or less than another , it’s equality that gives the
problem.</div>
<div class="MsoNormal">
<h2 style="text-align: left;">
Equality Conflict with Object Oriented Principles</h2>
This one often comes to as a surprise to experienced
developers as well, there is in fact a fundamental conflict between equality
comparisons, type safety and good object oriented practices. These 3 things do
not sit well together, this often makes very hard to make equality right and
bug free even once you resolved the other issues.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
We will not talk much about this in details as it will be
easy for you to understand once we start seriously coding which I will
demonstrate in a separate post and you will be able to then how the problem
naturally arises in the code you right.</div>
<div class="MsoNormal">
<br /></div>
<div style="text-align: left;">
Now let’s just try and give you a rough idea of
the conflict for now. Let’s say we have base class <b style="mso-bidi-font-weight: normal;">Animal</b> which represents different animals and will have a derived
class for example <b style="mso-bidi-font-weight: normal;">Dog</b> which adds
information specific to the Dog.</div>
</div>
</div>
</div>
</div>
<br />
<pre class="brush: csharp"> public class Animal
{
}
public class Dog : Animal
{
}
</pre>
<br />
If we wanted the Animal class to declare that Animal instances know how to check whether they are equal to other Animal instances, you might attempt to have it implement IEquatable<Animal>. This requires it to implement an Equals() method which takes an Animal instance as a parameter .<br />
<br />
<pre class="brush: csharp">
public class Animal : IEquatable<animal>
{
public virtual bool Equals(Animal other)
{
throw new NotImplementedException();
}
}
</pre>
<br />
<br />
<div class="MsoNormal" style="tab-stops: 409.5pt;">
If we<span style="mso-spacerun: yes;"> </span>want Dog class<span style="mso-spacerun: yes;"> </span>to also declare that Dog instances know how
to check wether they are equal to other Dog instances, we probably have
implement <b style="mso-bidi-font-weight: normal;">IEquatable<Dog><span style="mso-spacerun: yes;"> </span></b>that means it will also implement
similar<span style="mso-spacerun: yes;"> </span>Equals() method<span style="mso-spacerun: yes;"> </span>which take Dog instance as parameter.</div>
<br />
<pre class="brush: csharp"> public class Dog : Animal, IEquatable<Dog>
{
public virtual bool Equals(Dog other)
{
throw new NotImplementedException();
}
}
</pre>
<br />
<br />
<div class="MsoNormal" style="tab-stops: 409.5pt;">
And this is where the problem
comes in. You can probably guess that in a well-designed OOP code, you would
expect the <b style="mso-bidi-font-weight: normal;">Dog</b> class to override the
<b style="mso-bidi-font-weight: normal;">Equals()</b> method of <b style="mso-bidi-font-weight: normal;">Animal</b> class, but the trouble is Dog
equals method<span style="mso-spacerun: yes;"> </span>has a different argument
parameter<span style="mso-spacerun: yes;"> </span>than Animal Equals method
which means it won’t override it and if you are not very careful<span style="mso-spacerun: yes;"> </span>that can cause sort of subtle bugs where you
end up calling the wrong equals method and so returning the wrong result.</div>
<div class="MsoNormal" style="tab-stops: 409.5pt;">
<br /></div>
Often the only work around to this lose
type-safety and that’s what you exactly see in the <b style="mso-bidi-font-weight: normal;">Object</b> type Equals method<span style="mso-spacerun: yes;">
</span>which is the most basic way most types implement equality.</div>
<br />
<br />
<pre class="brush: csharp"> class Object
{
public virtual bool Equals(object obj)
{
}
}
</pre>
<br />
<br />
<div class="MsoNormal" style="tab-stops: 409.5pt;">
This method takes an instance of <b style="mso-bidi-font-weight: normal;">object</b> type as parameter which means it
is not type-safe, but it will work correct with inheritance. This is a problem
that is not well-known, there were a few blogs around that gave incorrect
advice on how to implement equality because they don’t take account of this
issue, but it is a problem there. We should be very careful how we design our
code to avoid it.</div>
<div class="MsoNormal" style="tab-stops: 409.5pt;">
<br />
<h2 style="text-align: left;">
Summary</h2>
</div>
<ul style="text-align: left;">
<li><span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span>C# does not syntactically distinguish between
value and reference equality which means it can sometimes be difficult to
predict what the equality operator will do in particular situations.<span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"> </span></span></span></li>
<li><span style="font-family: "symbol"; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";">
</span></span></span>There are often multiple different ways of
legitimately comparing values. .Net addresses this by allowing types to specify
their preferred natural way to compare for equality, also providing a mechanism
to write equality comparers that allow you to place a default equality for each
type</li>
<li>It is not recommended to test floating point
values for equality because rounding errors can make this unreliable</li>
<li>There is an inherent conflict between
implementing equality, type-safety and good Object Oriented practices.</li>
</ul>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-18163440214863141632016-02-05T06:28:00.000-08:002016-06-26T10:43:47.182-07:00Introduction to IEnumerable and IEnumerator in C#<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: "times new roman";"></span><br />
IEnumerable and IEnumerator are standard interfaces defined in C# which are used to enumerate the both generic and non-generic collections and we can iterate over these collection in forward only manner. Both are very related with each other in working in the .Net Framework.<br />
<h2 style="text-align: left;">
IEnumerator:</h2>
IEnumerator defines the way in which to traverse the elements of the collection in forward-only manner. The definition of IEnumerator contains just one property named <b>Current</b> which returns the current item of collection being enumerated and two methods named <b>MoveNext()</b> and <b>Reset()</b>.<br />
<br />
<br />
<b>MoveNext()</b> moves the position to next element and returns bool indicating that is there any more elements next and will return false if no more elements are found in collection, MoveNext() needs to be called before accessing first element. <br />
<br />
<br />
<b>Reset()</b> method which is pretty explanatory that it resets the enumerator and moves position back to the first element of the sequence so that it can be enumerated again.<br />
<br />
<br />
Here is the definition of it:<br />
<br />
<pre class="brush: csharp">public interface IEnumerator
{
bool MoveNext();
object Current { get; }
void Reset();
}
</pre>
<h2 style="text-align: left;">
IEnumerable:</h2>
Normally Collection do not provide implementation of enumerators, instead they use IEnumerable interface for providing enumerators.<br />
<br />
Following is the definition of IEnumerable interface: <br />
<br />
<pre class="brush: csharp">public interface IEnumerable
{
IEnumerator GetEnumerator();
}
</pre>
<br />
Collection classes provide implementation for this interface and it just returns the specific IEnumerator instance for the collection.<br />
<h2 style="text-align: left;">
Example:</h2>
Following example will help you understand how these two interfaces work together, we will be using a String type as example as it is a framework provided type and it implements IEnumerable interface which means we can enumerate on string variables.<br />
<br />
<pre class="brush: csharp">string enumeration = "Enumeration";
</pre>
<div class="c#" name="code">
</div>
now as string provides implementation for IEnumerable, i can call GetEnumerator() on it to get the enumerator of string:
IEnumerator enumerator = enumeration.GetEnumerator();
As we have enumerator of string available now, we can enumerate on it and print each character on screen :
<br />
<br />
<pre class="brush: csharp">while (enumerator.MoveNext())
{
char c = (char) enumerator.Current;
Console.Write (c);
}
</pre>
<br />
this will output:<br />
<h3 style="text-align: left;">
Enumeration
</h3>
<br />
But normally when we are working we do not need to call these methods like we did above, because C# provide us foreach loop to do that more cleaner way:
The above code can be written as :
<br />
<br />
<pre class="brush: csharp">string enumeration = "Enumeration";
foreach (char character in enumeration)
Console.Write (character);
</pre>
<br />
<h2 style="text-align: left;">
IEnumerable<T> and IEnumerator<T>:
</h2>
These two interfaces are almost same in implementation as IEnumerable and IEnumerator except they have generic type parameter.
Here is the implementation:
<br />
<br />
<pre class="brush: csharp">public interface IEnumerator<T> : IEnumerator, IDisposable
{
T Current { get; }
}
public interface IEnumerable<T> : IEnumerable
{
IEnumerator GetEnumerator();
}
</pre>
<br />
The typed parameter with these interfaces provides type safety at compile time and also eliminates the overhead of boxing and unboxing of value types and they are also more convenient to the consumers of it.
Arrays in c# by default implement IEnumerable<T> where T is the member type of array.
Type safe implementations of IEnumerable and IEnumerator saves us from runtime errors by throwing errors at compile time if something illegal is written.
<br />
<br />
<div style="text-align: left;">
<b>For Example:</b></div>
<div style="text-align: left;">
</div>
<pre class="brush: csharp">void Foo (IEnumerable<int> numbers)
{
}
</pre>
<br />
If i call above method by passing parameter of IEnumerable<char> it will give compile time error.
<br />
<br />
The standard practice for Collections is to expose the IEnumerable<T> and hiding the nongeneric IEnumerable using explicit interface implementation. It is because if you call GetEnumerator() directly it will return generic IEnumerator<T> which is type safe, but sometimes this rule is broken for backward compatibility scenarios as Generics were introduced after c# 2.0.
<br />
<br />
Arrays are classical example for this, as they return non generic IEnumerator to avoid breaking of old code base which were written in c# 2.0 or older than 2.0
<br />
<br />
For getting generic IEnumerator<T> you have to explicitly cast to expose the interface.
<br />
<br />
<b>For Example:</b>
<br />
<br />
<pre class="brush: csharp">int[] numbers = { 1, 2, 3 };
var enumerator = ((IEnumerable<int> )numbers ).GetEnumerator();
</pre>
<br />
<br />
But typically we don’t need to do this ourselves as foreach statement do this for us.
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-72315687689203741112016-01-24T06:35:00.000-08:002016-12-18T08:38:43.938-08:00Write Code Refactoring Extensions in Visual Studio 2015<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<span style="font-family: "calibri";">Microsoft has launched Visual Studio 2015 with many
improvements and new features as well which includes simple access to online
resources like Team Explorer, Salesforce, Cross platform mobile apps in C#
using xamarin, cross platform html apps with Cordova, cross platform mobile
apps in c# with unity, universal windows apps for any Windows 10 device,
asp.net 5 in web, device preview menu bar to see UI for different screen sizes
look, diagnostic features, cross platform debugging support, live code analysis
and much more.<o:p></o:p></span></div>
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
</div>
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<span style="font-family: "calibri";">One of these great features also includes Extensibility
templates which provide the ability to write new code refactorings, code
analyzers, diagnostic and code fixations, etc. When we will add our own created
code refactorings they will start to appear in the Quick Actions menu when we
are working on the source code in IDE.<o:p></o:p></span></div>
<o:p><span style="font-family: "calibri";"></span></o:p><br />
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<span style="font-family: "calibri";">You will need to install Visual Studio Extensibility
templates, when we install all components of VS 2015 they are automatically
been installed on the machine with VS 2015.In case it was not installed you
have to install it yourself first.<o:p></o:p></span></div>
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
</div>
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<span style="font-family: "calibri";">If you didn’t installed all the components of Visual Studio
then you will have to install the templates by going in to <b style="mso-bidi-font-weight: normal;">Tools >> Extensions and Updates</b> <o:p></o:p></span></div>
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<span style="mso-no-proof: yes;"><v:shapetype coordsize="21600,21600" filled="f" id="_x0000_t75" o:preferrelative="t" o:spt="75" path="m@4@5l@4@11@9@11@9@5xe" stroked="f"><span style="font-family: "calibri";">
<v:stroke joinstyle="miter">
<v:formulas>
<v:f eqn="if lineDrawn pixelLineWidth 0">
<v:f eqn="sum @0 1 0">
<v:f eqn="sum 0 0 @1">
<v:f eqn="prod @2 1 2">
<v:f eqn="prod @3 21600 pixelWidth">
<v:f eqn="prod @3 21600 pixelHeight">
<v:f eqn="sum @0 0 1">
<v:f eqn="prod @6 1 2">
<v:f eqn="prod @7 21600 pixelWidth">
<v:f eqn="sum @8 21600 0">
<v:f eqn="prod @7 21600 pixelHeight">
<v:f eqn="sum @10 21600 0">
</v:f></v:f></v:f></v:f></v:f></v:f></v:f></v:f></v:f></v:f></v:f></v:f></v:formulas>
<v:path gradientshapeok="t" o:connecttype="rect" o:extrusionok="f">
<o:lock aspectratio="t" v:ext="edit">
</o:lock></v:path></v:stroke></span></v:shapetype><span style="font-family: "calibri";"></span></span></div>
<span style="font-family: "calibri";"></span><br />
<span style="font-family: "calibri";"></span><br />
<span style="font-family: "calibri";"></span><br />
<span style="font-family: "calibri";"></span><br />
<span style="font-family: "calibri";"></span><br />
<span style="font-family: "calibri";"></span><br />
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: "calibri";"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKcORDW8EsNMc2W_nXMiDcXWWw7YfsxbUsFqfdzFBuPR1IsXXx85-zjVVDGdKlcC9JfisosXQ9ZPyFsk1XKQOJi-ZdC0QwNoIUXAWvd6rZRGuzQaVUFYiZSIR-SDmyx3blkksUT0TRNZLB/s1600/tools.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="513" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKcORDW8EsNMc2W_nXMiDcXWWw7YfsxbUsFqfdzFBuPR1IsXXx85-zjVVDGdKlcC9JfisosXQ9ZPyFsk1XKQOJi-ZdC0QwNoIUXAWvd6rZRGuzQaVUFYiZSIR-SDmyx3blkksUT0TRNZLB/s640/tools.png" width="640" /></a></span></div>
<span style="font-family: "calibri";">
</span><o:p></o:p>
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<span style="font-family: "calibri";">When the popup opens go click on Online from left pane and
then Search for <b style="mso-bidi-font-weight: normal;">.Net Compiler SDK:<o:p></o:p></b></span></div>
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<br />
<span style="font-family: "calibri";"></span><br />
<span style="font-family: "calibri";"></span><br />
<span style="font-family: "calibri";"></span><br />
<span style="font-family: "calibri";"></span><br />
<span style="font-family: "calibri";"></span><br />
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: "calibri";"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQsh1o9lijl4HfpYGkh1mwlPFNjWIsKBvG-OPGGPwLCd4qNKc4vfCPIpgJ_yG3ldS7fQjsbeEJdwV5ZEMXOT8lhtlQOBUkFyJ-vaBV89ALTwctG-g6jvXIWdCgD60kp93LQxJ9La5HT_Mr/s1600/.Net+Compiler+SDK.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="441" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQsh1o9lijl4HfpYGkh1mwlPFNjWIsKBvG-OPGGPwLCd4qNKc4vfCPIpgJ_yG3ldS7fQjsbeEJdwV5ZEMXOT8lhtlQOBUkFyJ-vaBV89ALTwctG-g6jvXIWdCgD60kp93LQxJ9La5HT_Mr/s640/.Net+Compiler+SDK.png" width="640" /></a></span></div>
<span style="font-family: "calibri";">
</span></div>
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<span style="font-family: "calibri";"><span style="mso-spacerun: yes;"> </span>After installation
restart visual studio and now you will be able to see Code Refactoring VISX
template under <b style="mso-bidi-font-weight: normal;">C# >> Extensibility</b>
when creating new Project.<o:p></o:p></span></div>
<o:p><span style="font-family: "calibri";"></span></o:p><br />
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<span style="font-family: "calibri";">When you are done with installation of templates, you can
find the Extensibility option in Project templates list when you go for
creating new project, and on selecting extensibility you will see the templates
available under it, from there select Code Refactoring (VISX) project.<o:p></o:p></span></div>
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZlFzW4SVTdQZ3X5dqI_97R3cUro_bq0hyphenhyphenEj1KhvUI9ef4YZ0GPxYll_9FMmDb5HkZlG4JR9AIC5a3G9BF1BKpOAHNsC9hxcwGKvc664MI2GWNpmyI3a5OMDjsybUztiz5fK3K-spRKF7m/s1600/Code+Refactoring.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="440" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZlFzW4SVTdQZ3X5dqI_97R3cUro_bq0hyphenhyphenEj1KhvUI9ef4YZ0GPxYll_9FMmDb5HkZlG4JR9AIC5a3G9BF1BKpOAHNsC9hxcwGKvc664MI2GWNpmyI3a5OMDjsybUztiz5fK3K-spRKF7m/s640/Code+Refactoring.png" width="640" /></a></div>
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
</div>
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<span style="font-family: "calibri";">Now you can create project for it, give a name to your
project and click Ok. You are done with your first Code Refactoring Extension.</span><span style="font-family: "calibri";">By default the project contains a simple example extension that
reverses that reverses the declaration type name.<o:p></o:p></span></div>
<o:p><span style="font-family: "calibri";"></span></o:p><br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<span style="font-family: "calibri";">If we right click on type declaration line we can see Quick
Action in Menu, clicking on it will show the Reverse extension button and
clicking it will update the class name by reversing the characters of it:<o:p></o:p></span><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwBWFj6OgdoadpiVjxzDt2ImYnIviX1aaz0SRT54HYuVLceIJDhPln0EoJP-uGmc3NowXkrpRituwOjkgxjqKIOgHsKBeZ_f1QBpIOl78KPRBEkPKkRCbW8hOczGKhawB4XV1oEN4_Hkpf/s1600/Extension.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwBWFj6OgdoadpiVjxzDt2ImYnIviX1aaz0SRT54HYuVLceIJDhPln0EoJP-uGmc3NowXkrpRituwOjkgxjqKIOgHsKBeZ_f1QBpIOl78KPRBEkPKkRCbW8hOczGKhawB4XV1oEN4_Hkpf/s1600/Extension.png" /></a></div>
</div>
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
</div>
<br />
<div class="MsoNormal" style="margin: 0in 0in 8pt;">
<span style="mso-no-proof: yes;"><v:shape id="Picture_x0020_3" o:spid="_x0000_i1025" style="height: 192pt; mso-wrap-style: square; visibility: visible; width: 468pt;" type="#_x0000_t75"><span style="font-family: "calibri";">
<v:imagedata o:title="" src="file:///C:\Users\EhsanS.SNL\AppData\Local\Temp\msohtmlclip1\01\clip_image004.png">
</v:imagedata></span></v:shape></span><o:p></o:p></div>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-74871246788080240602016-01-10T07:21:00.000-08:002016-06-26T10:52:33.013-07:00WCF service injection in Controller using Castle Windsor in asp.net mvc<div dir="ltr" style="text-align: left;" trbidi="on">
<h2>
Introduction:</h2>
<br />
In this post, we will see how we can inject WCF service dependency in the controller in asp.net mvc.<br />
<br />
<h2>
Background:</h2>
When working with web applications, normally we have persistent storage of data like Database, xml, Files , NoSQL , and we have data access in place in our controller actions to do operations on that data. Somtimes we fetch it for diaplying, saving new data, or updating existing recrods.<br />
<br />
Nowadays service oriented applications are very common and there is trend of making service oriented applications so that we can add or remove faetures from applications easily or alter implementation without making things mess.<br />
<br />
WCF is one of the technologies used which acts as a communication bridge between client application and persistent storage or database. We will discuss next with code sample how it is done nomally.<br />
<br />
<h2 style="text-align: left;">
Ordinary Approach:</h2>
Normally, we create a WCF service project, Create our Service Contratcs in form of interfaces which tells what i take input and what i would return to callee and then others can implement those service contracts to tell how to do that. Here is an example Service Contract :<br />
<br />
<pre class="brush: csharp"> [ServiceContract]
public interface IUserService
{
[OperationContract]
IList<user> GetUsers();
[OperationContract]
User RegisterUser(User user);
[OperationContract]
User Login(string id,string password);
[OperationContract]
bool UserNameExists(string username, string email);
}
</pre>
<br />
and we then provide the implementation of contract:<br />
<br />
<pre class="brush: csharp"> public class UserService : IUserService
{
private IConnectionFactory connectionFactory;
public IList<user> GetUsers()
{
connectionFactory = ConnectionHelper.GetConnection();
var context = new DbContext(connectionFactory);
var userRep = new UserRepository(context);
return userRep.GetUsers();
}
public User RegisterUser(User user)
{
connectionFactory = ConnectionHelper.GetConnection();
var context = new DbContext(connectionFactory);
var userRep = new UserRepository(context);
return userRep.CreateUser(user);
}
public User Login(string id, string password)
{
connectionFactory = ConnectionHelper.GetConnection();
var context = new DbContext(connectionFactory);
var userRep = new UserRepository(context);
return userRep.LoginUser(id,password);
}
public bool UserNameExists(string username,string email)
{
connectionFactory = ConnectionHelper.GetConnection();
var context = new DbContext(connectionFactory);
var userRep = new UserRepository(context);
var user = userRep.GetUserByUsernameOrEmail(username,email);
return !(user != null && user.UserID > 0);
}
}
</pre>
<br />
<br />
Now client application (in our case mvc application) would add Service Reference in the project and call the Service as shown below:<br />
<br />
<pre class="brush: csharp"> public class AccountController : Controller
{
[HttpPost]
[AllowAnonymous]
public ActionResult SignUp(RegisterViewModel registerVM)
{
if (ModelState.IsValid)
{
UserService authenticateService = new UserService(); // this is bad design high coupling of components
var result = authenticateService.RegisterUser(registerVM);
RegisterViewModel vm = result;
return View(vm);
}
return View(registerVM);
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult SignIn(LoginViewModel loginVm)
{
if (ModelState.IsValid)
{
UserService authenticateService = new UserService(); // this is bad design high coupling of components
var user = authenticateService.Login(loginVm.UserName, loginVm.Password);
if (user == null)
ModelState.AddModelError("", "The user name or password provided is incorrect.");
Session["User"] = user;
return RedirectToAction("Index", "Home");
}
return View(loginVm);
}
}
</pre>
<br />
<br />
<h2>
What's the Problem:</h2>
If you note the above two action methods, they look fine but there is one line which is a bad design approach and voild Single Responsibility Principle and it also create high coupling between our controller and Service implementation, in future if we have to use some different implementation of <b>IUserService</b> , let's say new implemention which uses Entity Framework or some other Data Access Technique like MongoDB, Azure or Rest Services with JSON, we will have to change our all actions to use different class, which is not very pleasant.<br />
<h2 style="text-align: left;">
Dependency Injection :</h2>
<div style="text-align: left;">
Here comes the role of <a href="https://en.wikipedia.org/wiki/Dependency_injection">dependency injection</a> is a technique / design pattern which we will be using here. As <b>IUserService </b>a dependency of our Controller which is needed for the <b>AccountController</b> to do the job successfully.</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
As it name reflects it is used for injecting dependencies of an implementation, there can be many dependencies or can be one only depends on the scenario, but in our this example we have one dependency of our Controller which is <b>IUserService</b>.</div>
<div style="text-align: left;">
</div>
<h2 style="text-align: left;">
Castle Windsor to Help Here:</h2>
<div style="text-align: left;">
<a href="https://www.nuget.org/packages/Castle.Windsor/">Castle Windsor</a> is a <a href="https://en.wikipedia.org/wiki/Inversion_of_control">Inversion of Control</a> container, it can instantiate the dependencies right at the place where we need them. Dependency Injection and Inversion of Control are mostly used together, when we want dependencies to be injected, we have to use Inversion of Control as well.</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
For this, first of all we will have to add the library in out project from Nuget or we can download assemblies and add references to assemblies explictly. After installing the library we can see reference to <b>Castle.Core </b>and <b>Castle.Windsor </b>in <b>References</b> of project:<br />
<br />
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ_NevdyyyB7686rhJm4djnlDjk1vFTEyXG9GpAAcetYbTXTBQC2sZ5dP0bULkWoU5FaS62wkm6T1akvQmKUMj46PHMolrQObhNb40e-AQ-b18C41_Z7wJmt7DChQwhJhE6KHr-DbKCr66/s1600/Castle+Windsor.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ_NevdyyyB7686rhJm4djnlDjk1vFTEyXG9GpAAcetYbTXTBQC2sZ5dP0bULkWoU5FaS62wkm6T1akvQmKUMj46PHMolrQObhNb40e-AQ-b18C41_Z7wJmt7DChQwhJhE6KHr-DbKCr66/s640/Castle+Windsor.PNG" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: left;">
</div>
<h4>
</h4>
Now first step is to implement the installer for CastleWindsor in which we will be telling the dependencies which will be injected by container on runtime when needed.<br />
<br />
<pre class="brush: csharp"> public class WindsorInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
// registering all Controllers of the Assembly
container.Register(Classes.FromThisAssembly()
.BasedOn<icontroller>()
.LifestyleTransient());
// registeting our WcfInterceptor to intercept all WCF Service calls
container.Register(Component
.For<iinterceptor>()
.ImplementedBy<wcfinterceptor>()
.Named("wcf"));
// Registering IUserService
container.Register(Types
.FromAssemblyContaining<iuserservice*gt;()
.Where(x => x.IsInterface)
.LifestyleTransient()
.Configure(x =>
{ var res = x.Interceptors(InterceptorReference.ForKey("wcf")).Anywhere; }));
// Registering implementation for IClientFactory which is dependency of WCFInterceptor implementation
container.Register(Component
.For<iclientfactory>()
.ImplementedBy<wcfclientfactory>());
}
</pre>
<br />
<h2>
</h2>
Following is the implementation of registered dependencies above. First of all here is implementation for <b>WcfInterceptor</b>:<br />
<br />
<pre class="brush: csharp"> public class WcfInterceptor : IInterceptor
{
public IClientFactory ClientFactory { get; set; }
public void Intercept(IInvocation invocation)
{
var clientProvider = ClientFactory.GetClientProvider(invocation.Method.DeclaringType);
try
{
clientProvider.Open();
invocation.ReturnValue = CallClientProviderMethod(invocation, clientProvider);
}
finally
{
clientProvider.Close();
}
}
private object CallClientProviderMethod(IInvocation invocation, IClientProvider clientProvider)
{
var proxy = clientProvider.GetProxy();
return invocation.Method.Invoke(proxy, invocation.Arguments);
}
}
</pre>
<br />
You can see the property ClientFactory of type <b>IClientFactory </b>which is a dependency as it is being used in Intercept method, and Intercept will get called when from client side we will exceute any method of WCF Service e.g : <b>RegisterUser() </b>method of SignUp action.<br />
<br />
Here is the implementation of WcfClientFactory:<br />
<br />
<pre class="brush: csharp">
public class WcfClientFactory : IClientFactory
{
public IClientProvider GetClientProvider(Type type)
{
var closedType = typeof(WcfClientProvider<>).MakeGenericType(type);
return (IClientProvider)Activator.CreateInstance(closedType);
}
}
</pre>
<div>
</div>
<div>
which just returns instance of <b>WcfClientProvider<T></b>, the implementation of <b>WcfClientprovide<T> </b>is:</div>
<div>
</div>
<div>
<pre class="brush: csharp"> public class WcfClientProvider<t> : IClientProvider
{
private ChannelFactory<t> factory;
public WcfClientProvider()
{
factory = new ChannelFactory<t>(string.Empty);
}
public object GetProxy()
{
return factory.CreateChannel();
}
public void Open()
{
if (this.factory.State != CommunicationState.Opened)
{
factory.Open();
}
}
public void Close()
{
factory.Close();
}
}
</pre>
</div>
Now
we have to define Controller Factory as well, because we have Registered <b>IController </b>in container we now will have to provide our own implementation of Controller Factory whose purpose is to create controller instance passing the instantiated dependencies of it.<br />
<br />
Now the last step is to install Castle Windsor on Application start and instantiation of our Controller Facotry in <b>Global.asax</b>.<br />
<br />
This is how your Global.asax code should look like:<br />
<br />
<pre class="brush: csharp"> public class MvcApplication : System.Web.HttpApplication
{
private static IWindsorContainer container;
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BootstrapContainer();
}
private static void BootstrapContainer()
{
container = new WindsorContainer()
.Install(FromAssembly.This());
var controllerFactory = new WindsorControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}
}
</pre>
<br />
Now we will have to change our AccountController code to add a contructor which takes <b>IUserService </b>instance as parameter (dependency) which will be instantiated by our Ioc Container.<br />
<br />
Now our controller will look like :<br />
<br />
<pre class="brush: csharp"> public class AccountController : Controller
{
private IUserService authenticateService;
public AccountController(IUserService authenticateService)
{
this.authenticateService = authenticateService;
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult SignIn(LoginViewModel loginVm)
{
if (ModelState.IsValid)
{
var user = authenticateService.Login(loginVm.UserName, loginVm.Password);
if (user == null)
ModelState.AddModelError("", "The user name or password provided is incorrect.");
Session["User"] = user;
return RedirectToAction("Index", "Home");
}
return View(loginVm);
}
[HttpPost]
[AllowAnonymous]
public ActionResult SignUp(RegisterViewModel registerVM)
{
if (ModelState.IsValid)
{
var result = authenticateService.RegisterUser(registerVM);
RegisterViewModel vm = result;
return View(vm);
}
return View(registerVM);
}
</pre>
<br />
Now our code is much better, it is following single responsibility principle and it is component based, we can also write Unit Tests for our actions as our all dependencies are to be provided via constructor, so unit tests are easy to write and run.</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-48387771453838212552015-11-05T05:27:00.001-08:002016-06-26T12:13:25.020-07:00How to get First N digits of a number without Converting to String<div dir="ltr" style="text-align: left;" trbidi="on">
Few days back i was asked by my senior colleague to make a method which takes two arguments as input, first the number and second the number of digits to be returned from the first argument number.<br />
<br />
After sometime i was able to make logic of it, which was to get the number of digits of the input number and then i used that to get the number of digits using second parameter.<br />
<br />
<br />
Here is the method:<br />
<br />
<pre class="brush: csharp"> private static int takeNDigits(int number, int N)
{
int numberOfDigits = (int)Math.Floor(Math.Log10(number) + 1);
if (numberOfDigits >= N)
return (int)Math.Truncate((number / Math.Pow(10, numberOfDigits - N)));
else
return number;
}
</pre>
<br />
and use it :<br />
<br />
<pre class="brush: csharp"> int Result1 = takeNDigits(666, 4);
int Result2 = takeNDigits(987654321, 5);
int Result3 = takeNDigits(123456789, 7);
int Result4 = takeNDigits(35445, 1);
int Result5 = takeNDigits(666555, 6);
</pre>
<br />
<h3 style="text-align: left;">
Output:</h3>
<br />
<strong>Result1</strong> : 666<br />
<strong>Result2</strong> : 98765<br />
<strong>Result3</strong> : 1234567<br />
<strong>Result4</strong> : 3<br />
<strong>Result5</strong> : 666555</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-18130010192522872762015-10-23T12:37:00.000-07:002016-06-26T12:15:08.838-07:00Custom Validation Message Helper in asp.net mvc<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
As i wrote earlier a post about <a href="http://developmentpassion.blogspot.com/2014/09/creating-custom-html-helper-extensions.html" target="_blank">Creating Custom Html Helpers in asp.net mvc</a> which emphasized on how we can write custom html helper extensions in asp.net mvc according to the need, so that we can reuse them in the whole application, instead of writing plan html in View.<br />
<br />
The example in that article was using ActionLink, today i am going to tell how we can implement custom Validation Message helper.I wanted to modify the validation message displaying in my application so that it displays * in front of required fields and the error message in tooltip of it like:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK7gLwGD1jTcU4glJzYhITk_62D-mFWdbiRipHStJjfqSy2fVmyneyZC02JaN-aanvuLzFaqZy9leWmp8uXt7I8Gml78E_in7mxoOMJfDmIV4wtfarsGpXp9xM6KAViSdGzBFzW9UYNG24/s1600/CustomValidation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="351" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK7gLwGD1jTcU4glJzYhITk_62D-mFWdbiRipHStJjfqSy2fVmyneyZC02JaN-aanvuLzFaqZy9leWmp8uXt7I8Gml78E_in7mxoOMJfDmIV4wtfarsGpXp9xM6KAViSdGzBFzW9UYNG24/s400/CustomValidation.png" width="400" /></a></div>
<br />
<br />
<br />
For that add a class in the project and add an extension method which will render our custom html that will be displayed for error message:<br />
<br />
<pre class="brush: csharp">namespace CustomValidationMessageHelper.Helpers
{
public static class Validator
{
public static MvcHtmlString MyValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
TagBuilder containerDivBuilder = new TagBuilder("div");
containerDivBuilder.AddCssClass("tip_trigger");
containerDivBuilder.InnerHtml = "*";
TagBuilder midDivBuilder = new TagBuilder("div");
midDivBuilder.AddCssClass("classic");
midDivBuilder.AddCssClass("tip");
midDivBuilder.InnerHtml = helper.ValidationMessageFor(expression).ToString();
containerDivBuilder.InnerHtml += midDivBuilder.ToString(TagRenderMode.Normal);
return MvcHtmlString.Create(containerDivBuilder.ToString(TagRenderMode.Normal));
}
}
}
</pre>
<br />
and then define following css in a css file in my case it is <b>site.css</b> or you can add it in the view:<br />
<br />
<pre class="brush: css">.validated {
border-color: #DCE4EC !important;
}
textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input {
padding: 3px 3px;
border: 1px solid #DCE4EC;
}
.tip {
background: none repeat scroll 0 0 #FFFFFF;
border: 1px solid #808080;
border-radius: 10px;
box-shadow: 0 1px 10px rgba(32, 32, 32, 0.5);
color: red;
display: none;
font-size: 12px;
font-style: normal;
margin-left: 10px;
margin-top: -24px;
padding: 4px;
position: absolute;
z-index: 999999;
}
.tip_trigger {
width: 10px;
float: right;
color: red;
margin-left: 3px;
}
</pre>
<br />
Now we have to add client side code, which i have written in jquery in a js file or directly in view, in my case i have it in <b>CustomValidation.js </b>file:<br />
<br />
<pre class="brush: js">$(document).ready(function () {
//Tooltips
var tip;
$(".tip_trigger").hover(function () {
console.log("hovered");
tip = $(this).find('.tip');
console.log($(this).find('.tip').find('span').html())
if ($(this).find('.tip').find('span').html() != '') {
$(this).find('.tip').show(); //Show tooltip
}
}, function () {
$(this).find('.tip').hide(); //Hide tooltip
});
////Required fields
$('input').each(function () {
var req = $(this).attr('data-val-required');
if (undefined != req) {
$(this).css("border-color", "#DA9BA2")
}
if ($(this).val() != '') {
$(this).addClass("validated");
}
});
$('input').blur(function () {
if ($(this).val() != '') {
$(this).addClass("validated");
}
else {
$(this).css("border-color", "#DA9BA2")
}
});
});
</pre>
<br />
Now in the View add the reference to the related js and css files in the head section of View:<br />
<br />
<pre class="brush: html"> <link href="@Url.Content("~/Content/site.css")" rel="stylesheet"/>
<script src="@Url.Content("~/Scripts/jquery-1.9.1.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/CustomValidation.js")" type="text/javascript"></script>
</pre>
<br />
<br />
Now in your view add using statement of the namespace and now you can access the Helper method in the View:<br />
<br />
<pre class="brush: csharp">@model CustomValidationMessageHelper.ViewModels.SignUpViewModel
@using CustomValidationMessageHelper.Helpers
@{
Layout = null;
}
@Html.TextBoxFor(model => model.FirstName, new { @class = "form-control input-sm" })
@Html.MyValidationMessageFor(model => model.FirstName)
</pre>
<br />
The sample project can be <a href="https://drive.google.com/open?id=0Bzzb_9_aasccdlN6c19aR3Vkdmc" target="_blank">downloaded from here</a>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-61572567402879642832015-09-21T12:26:00.000-07:002016-06-26T12:19:01.127-07:00Misconceptions regarding Pass By Value and Pass By Reference in C#<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display:none;">CodeProject</a>
<br />
<h2 style="text-align: left;">
Introduction:</h2>
<div style="text-align: left;">
It is a common question which is asked by interviewers in interviews that <b>"What is Pass By Value and Pass By Reference"</b> or <b>"What is the difference between Pass By Value and Pass By Reference"</b>. Most of the beginner level developers and also many of intermediate level developers have misconception on it and they answer it wrong during interview.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
When i didn't knew that real difference, i used to answer it like, when we pass primitive types they are passed by value but when we pass reference type, they are passed by reference which i was not aware that it is wrong.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
So, today i decided to write on this topic so that readers reading my blog could be aware of the real difference and they can correct their misconception regarding it.</div>
<div style="text-align: left;">
<br /></div>
<h2 style="text-align: left;">
Pass By Value in Value Types:</h2>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
In .Net Framework all objects are by default passed by value not passed by reference either it is a <b><a href="https://msdn.microsoft.com/en-us/library/s1ax56ch.aspx" target="_blank">Value Type</a> </b>(so called Primitive types like <b>int</b>,<b>char</b>,<b>double</b> etc) or <a href="https://msdn.microsoft.com/en-us/library/490f96s2.aspx" target="_blank"><b>Reference Type </b></a>(<b>class</b>,<b>interface</b>,<b>delegate</b>,<b>string</b> etc).<br />
<br />
I will not go in to the details of Value Type and Reference Type definition and concept, you can read about them <a href="https://msdn.microsoft.com/en-us/library/4d43ts61%28v=vs.90%29.aspx" target="_blank">here</a>. </div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Consider the following Examples:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
First i will show a example using Value Type.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">int num1 = 5;
int num2 = num1;
num2 = 10;
Console.WriteLine(num1);
</pre>
</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
So what will be printed on Console?</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
If your answer is <b>5</b>,then you are right, because <b>int </b>is a value type, it is passed by value, which means for the above code <b>num1 </b>has 5 stored in it, when we create <b>num2 </b>and assign it <b>num1</b> value of <b>num1</b> is copied to <b>num2</b> and after that if we change <b>num2</b> it will not affect <b>num1</b>, ofcourse because we have copied value of <b>num1</b> to <b>num2</b>, why <b>num1</b> is to be change.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
The same happens when we pass value types to methods. For Example:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
We have created a method with sets the value of a <b>int </b>variable to 10.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">private void ChangeValue(int i)
{
i = 10;
}
</pre>
</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Now we call it using our previous example:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">int num1 = 5;
ChangeValue(num1);
Console.WriteLine(num1);
</pre>
</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
What would be the output on Console now?</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Yes it will still output <b>5 </b>as i already said that value is copied, so when ChangeValue method is called, <b>num1 </b>variable value is copied to <b>i </b>so changing i does not changes num1.</div>
<div style="text-align: left;">
<br /></div>
<h2 style="text-align: left;">
Diagrammatic/Pictorial Representation of Pass By Value in Value Types: </h2>
<h2 style="text-align: left;">
</h2>
<div style="text-align: left;">
Here is diagrammatic representation of Pass By Value.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ-x226QUJHX-SBr9EnBE7KyQwwE5WyRolWyCZb4VR1gQRHB7mV2sc2UlgfBKjCZEolUyTEVijq_A3Dc8BnWdgoryCrsixR-f41gB7sGSJGniCcxU7XhQ_speYlM-CBg9o94YL-we5dSzr/s1600/value-type.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="359" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ-x226QUJHX-SBr9EnBE7KyQwwE5WyRolWyCZb4VR1gQRHB7mV2sc2UlgfBKjCZEolUyTEVijq_A3Dc8BnWdgoryCrsixR-f41gB7sGSJGniCcxU7XhQ_speYlM-CBg9o94YL-we5dSzr/s640/value-type.png" width="640" /></a></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<h2 style="text-align: left;">
Pass By Value in Reference Types:</h2>
<div style="text-align: left;">
I have following class of User which is a reference type as classes are reference types :</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">public class User
{
public int UserID {get;set;}
public string Name {get;set;}
}
</pre>
<br />
<br />
we create an instance and set its properties then we assign it to another instance and change Name property and then we print Name on Console to check what is printed:<br />
<br />
<pre class="brush: csharp">User objUser = new User()
{
UserID = 1,
Name = "Ehsan Sajjad"
};
User objUser2 = objUser;
objUser2.Name = "Jon Doe";
</pre>
<br />
<br />
When we create Instance of class User, an object is create in memory(<b>Heap</b>) and
memory is allocated to it and we are storing reference to that memory
location in <b>objUser </b>reference memory (<b>mostly Stack</b>)<b> </b>so that we can use it further, otherwise it
will get lost in the memory so we need to keep a reference to it for
doing different operation in memory.<br />
<br />
When we assign<b> objUser </b>to <b>objUser2</b> reference of object memory location which <b>objUser</b> is holding copied to<b> objUser2</b> , now we have two seperate copies of reference but they are both are pointing to same memory
location which means they both are referencing to same memory
location,so changing the value of Name property will change
the value in the object in memory of which we have reference in <b>objUser
</b>and <b>objUser</b>, hence <b>"Jon Doe" </b>will be printed on console and it will be reflected in both references.<br />
<br />
<h2 style="text-align: left;">
Diagrammatic/Pictorial Representation of Pass By Value in Reference Types: </h2>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn6uuxiAU0Y5TZgTQXdXFme60vXRlH9GuPnHkfOG1uEVkI4P05cWiqjzM_NoT5H5JlPhjMjs2o1pMIvHYVpGjF_3GqiSQN60CW6JBSUkeggmKcTOp4FS-6SRuM7NuNRJ2jlU1101d7UHvp/s1600/reference+types+-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="359" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhn6uuxiAU0Y5TZgTQXdXFme60vXRlH9GuPnHkfOG1uEVkI4P05cWiqjzM_NoT5H5JlPhjMjs2o1pMIvHYVpGjF_3GqiSQN60CW6JBSUkeggmKcTOp4FS-6SRuM7NuNRJ2jlU1101d7UHvp/s640/reference+types+-2.png" width="640" /></a></div>
<br />
<br />
We can see the same behavior using a method,see the following method to change <b>Name</b> property of User object:<br />
<br />
<pre class="brush: csharp">public static void ChangeName(User user)
{
user.Name = "Jon Doe";
}
</pre>
<br />
<br />
We call it to change the object state, it will give the same behavior what we saw in assignment case:<br />
<br />
<pre class="brush: csharp">User objUser = new User() { UserID = 1, Name = "Ehsan Sajjad" };
ChangeName(objUser);
Console.WriteLine(objUser.Name);
</pre>
<br />
<br />
When we are passing reference <b>objUser </b>of User object<b> </b>to method <b>ChangeName</b>, reference of memory location is copied to the local object user of method but they are both are pointing to same memory location which means they both are having reference to same memory location,so changing the value the value of Name property will change the value in the object in memory of which we have reference in <b>objUser </b>and <b>user</b>, hence <b>"Jon Doe" </b>will be printed on console.<br />
<br />
<br />
Here is diagramatic representation of it:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU7VtOxHLpla9N6re7VcMfEA26EU-tEmxH3Q3-TUnCSHKjQK26Yc1an3haM7fnD-yuIAxUJHTsBb3eTwkD6eIft_Y-uw3ooq-FGQRpsULO1wTfFvhnKVzBXiw1vygbB5r9XfpxrpwyXlR_/s1600/reference+types+-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="356" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU7VtOxHLpla9N6re7VcMfEA26EU-tEmxH3Q3-TUnCSHKjQK26Yc1an3haM7fnD-yuIAxUJHTsBb3eTwkD6eIft_Y-uw3ooq-FGQRpsULO1wTfFvhnKVzBXiw1vygbB5r9XfpxrpwyXlR_/s640/reference+types+-1.png" width="640" /></a></div>
<div style="text-align: left;">
When the <b>ChangeName(objUser) </b>is called, as it is referring to same memory location, it will modify the Name property of <b>User</b> object to <b>"Jon Doe"</b>.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigtQM2wQ9UhcAxLGPqAzzWTV0ojFdCJYW40FcP1uYoXCbgHnqfmAyrYZsKk5haCCkaIfznS3YBeij_uNnMkegGvoLPox87ypDaH03IhNXpljMBwq3i_d_KJVElw0_Id8DUZlEqhy6148fF/s1600/reference+types+-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="358" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigtQM2wQ9UhcAxLGPqAzzWTV0ojFdCJYW40FcP1uYoXCbgHnqfmAyrYZsKk5haCCkaIfznS3YBeij_uNnMkegGvoLPox87ypDaH03IhNXpljMBwq3i_d_KJVElw0_Id8DUZlEqhy6148fF/s640/reference+types+-3.png" width="640" /></a></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
But think about what would happen if i set the user to null inside ChangeName method like:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">public static void ChangeName(User user)
{
user = null;
}
</pre>
</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
and now we call it for <b>objUser </b>:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">User objUser = new User()
{
UserID = 1,
Name = "Ehsan Sajjad"
};
ChangeName(objUser);
Console.WriteLine(objUser.Name);
</pre>
</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
If you are thinking that it will throw <b>Null Reference Exception</b>, then you are wrong, and if you are thinking that it will output <b>Ehsan Sajjad</b>, then you are right and you have understood that reference are passed by value in C# not by reference.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
See the pictorial representation to understand better:</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggXZ66xN6cEcLvlMMhTcQ61hO2Bsxd7lmrqKPAEMl3HH3WScuIYhDeEFbOJTX51uQs4xNh2uklrM9Z_OQjc-DunoAmKXX8M4ISXI2Xga7oKC48aOrA5pqk4J0dW-3340qk-FkjJHRpnUrQ/s1600/reference+types+-4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="358" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggXZ66xN6cEcLvlMMhTcQ61hO2Bsxd7lmrqKPAEMl3HH3WScuIYhDeEFbOJTX51uQs4xNh2uklrM9Z_OQjc-DunoAmKXX8M4ISXI2Xga7oKC48aOrA5pqk4J0dW-3340qk-FkjJHRpnUrQ/s640/reference+types+-4.png" width="640" /></a></div>
<h2 class="separator" style="clear: both; text-align: center;">
</h2>
<h2 style="text-align: left;">
</h2>
<h2 style="text-align: left;">
Pass By Reference:</h2>
<div style="text-align: left;">
If we want to make <b>objUser </b>null, we will have to pass it to the method via reference which is done in C# using <a href="https://msdn.microsoft.com/en-us/library/14akc2c7.aspx" target="_blank">ref Keyword</a>. We will use the above examples again but this time we will pass them by reference and will see what happens so that we can inderstand the difference between these two.</div>
<div style="text-align: left;">
</div>
<h2 style="text-align: left;">
Pass By Reference in Value Types:</h2>
<div style="text-align: left;">
We will use the same above example but this time we will be passing by reference. For that first of all we have to change the method signatures of method <b>ChangeValue(int i) </b>to <b>ChangeValue(ref int i)</b>, we have added ref keyword with the input parameter which means that when calling this method the argument should be passed by reference to it:</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<pre class="brush: csharp">private void ChangeValue(ref int i)
{
i = 10;
}
</pre>
</div>
<div style="text-align: left;">
Now we will use the same code as above but we have to use <b>ref </b>keyword at calling side for the parameters that method expect to be passed by reference otherwise you will get compile time error, and your code will not build:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre class="brush: csharp">int num1 = 5;
ChangeValue(ref num1);
Console.WriteLine(num1);
</pre>
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
This will output <b>10 </b>on the screen, because we are using ref keyword, in the above code when <b>ChangeValue </b>is called the incoming parameter of it has the same memory address of <b>num1 </b>which is passed as argument that's why now modifying the value of <b>i </b>would reflect the change in <b>num1 </b>as well, in pass by reference new memory location is not used for the method parameter so changing the value of it will reflect the variable that is passed from calling side.</div>
<h2 style="text-align: left;">
Pass By Reference in Reference Types:</h2>
<div style="text-align: left;">
We will now check the same thing with reference types, and the behaviour would be same for reference types case as well,first modify the signature of method so that it takes parameter as reference:</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<pre class="brush: csharp">public static void ChangeName(ref User user)
{
user = null;
}
</pre>
<br />
and we will call it simply this way:<br />
<br />
<pre class="brush: csharp">User objUser = new User()
{
UserID = 1,
Name = "Ehsan Sajjad"
};
ChangeName(objUser);
Console.WriteLine(objUser.Name);
</pre>
<br />
<br />
Now when we will call it on objUser setting user to null inside ChangeName will also make objUser null because instead of passing the reference by value (in that a new reference memory location is create which points the same object) it is passed by reference, so in this case new copy of reference is not created but the reference of objUser is passed to method which results setting the calling side reference to also change the memory location where it is pointing.</div>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-87855614012969905932015-09-14T12:48:00.000-07:002016-06-26T12:22:11.603-07:00How to Convert DataTable to List in C#<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
When writing Data Access Layer, when we get data from the database using ADO.net, most of the times we use <b>DataTable</b> or <b>DataSet </b>to hold the data in memory, then we have to map the <b>DataTable </b>to List of Model type.<br />
<br />
<br />
One way is to iterate on the rows of DataTable and create objects of Model and add to List one. Let me show you with example.<br />
<br />
<br />
I have table in database which has information about Doctors, my table name is <b>Doctor </b>which contains different columns which are for capturing information of Doctor.<br />
<br />
<br />
I have following Model class on front end which represents Doctor :<br />
<br />
<pre class="c#" name="code">public class Doctor
{
public int ID { get; set; }
public string Name { get; set; }
public string ImagePath { get; set; }
public string Type { get; set; }
}
</pre>
<br />
<br />
When we will get Doctors from database in datatable we can create a list of Doctors with following approach in our Data Access:<br />
<br />
<pre class="brush: csharp">List<doctor> doctors = new List<doctor>();
for (int i = 0; i < dtDoctors.Rows.Count; i++)
{
Doctor objDoctor = new Doctor();
objDoctor.ID = dtDoctors.Rows[i]["DoctorID"].ToString();
objDoctor.Name = dtDoctors.Rows[i]["Name"].ToString();
objDoctor.ImagePath = dtDoctors.Rows[i]["Image"].ToString();
objDoctor.Type = dtDoctors.Rows[i]["Type"].ToString();
doctorList.Add(objDoctor);
}
</pre>
<br />
It will surely do the job for you, but think that you have many tables in your database and whenever you will fetch data you will have to do a loop the way i showed above and will have to map properties from datatable, which does not look cool as we are rewriting same thing again and again which is against DRY principle.<br />
<br />
<br />
We can achieve what we have did above using generics,relection and extension methods feature provided by .Net Framework.We can add the following extension method in our project and just call it to convert DataTable to List of Type which we want to.<br />
<br />
Following is the extension method for it:<br />
<br />
<pre class="brush: csharp">
public static class ExtensionMethods
{
public static List<T> ToList<T>(this DataTable dt)
{
List<T> data = new List<T>();
foreach (DataRow row in dt.Rows)
{
T item = GetItem<T>(row);
data.Add(item);
}
return data;
}
private static T GetItem<T>(DataRow dr)
{
Type temp = typeof(T);
T obj = Activator.CreateInstance<T>();
foreach (DataColumn column in dr.Table.Columns)
{
foreach (PropertyInfo pro in temp.GetProperties())
{
if (pro.Name == column.ColumnName && dr[column.ColumnName] != DBNull.Value)
pro.SetValue(obj, dr[column.ColumnName], null);
else
continue;
}
}
return obj;
}
}
</pre>
<br />
Now we can call it on instance of DataTable and can specify that convert it to which type of List.<br />
<br />
For Example:<br />
<br />
<pre class="brush: csharp">List<Doctor> doctors = dtDoctors.ToList<Doctor>();
</pre>
</div>
<br />
<br />
Now that looks cool, we have just written two extension method for DataTable and now we can reuse it anywhere which enables us to reduce code redundancy.<br />
<br />
<br />
One thing to consider is that the column names you are returning from your sql query or Stored Procedure should be same as of the properties in the Model class and the datatype should also be matched so that i can be converted. </div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-35469110304376545132015-09-04T11:12:00.002-07:002016-06-26T12:27:07.725-07:00Implementing Repository pattern and Dependency Injection in ADO.net using Generics in C#<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
Nowadays i am trying to learn different design patterns in object oriented paradigm that are pretty useful to implement generic solutions for different scenarios, few weeks back for a job hunt i got an assignment to do which was a web application which would interact with database, so i took it as a challenge and decided to make it loosely coupled using design patterns which were applicable in that scenario.<br />
<br />
One of them which implemented in my assignment is repository pattern using generics and with that Dependency Injection using which i injected dependencies of Repository class via constructor.<br />
<br />
<br />
<br />
I made generic class which would be inherited by other types against the different tables in the application. in this class i have used different framework features like Reflection and Generics.<br />
<br />
<br />
My generic class is an abstract class, so it needs to be inherited for making use of it, you will see next how we will use it.<br />
<br />
<br />
Here is the Repository class:<br />
<br />
<pre class="brush: csharp">public abstract class Repository<TEntity> where TEntity : new()
{
DbContext _context;
public Repository(DbContext context)
{
_context = context;
}
protected DbContext Context
{
get
{
return this._context;
}
}
protected IEnumerable<TEntity> ToList(IDbCommand command)
{
using (var record = command.ExecuteReader())
{
List<TEntity> items = new List<TEntity>();
while (record.Read())
{
items.Add(Map<TEntity>(record));
}
return items;
}
}
protected TEntity Map<TEntity>(IDataRecord record)
{
var objT = Activator.CreateInstance<TEntity>();
foreach (var property in typeof(TEntity).GetProperties())
{
if (record.HasColumn(property.Name) && !record.IsDBNull(record.GetOrdinal(property.Name)))
property.SetValue(objT, record[property.Name]);
}
return objT;
}
}
</pre>
<br />
Now i have table in database <b>User </b>whose schema is :<br />
<br />
<pre class="brush: sql">CREATE TABLE [dbo].[tblUser] (
[UserID] INT IDENTITY (1, 1) NOT NULL,
[FirstName] NVARCHAR (25) NULL,
[LastName] NVARCHAR (25) NULL,
[UserName] NVARCHAR (25) NULL,
[Password] NVARCHAR (25) NULL,
[IsActive] BIT NULL,
[IsDeleted] BIT NULL,
[CreatedBy] INT NULL,
[CreatedAt] DATETIME NULL,
[UpdatedBy] INT NULL,
[UpdatedAt] DATETIME NULL,
[Email] NVARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([UserID] ASC)
);
</pre>
<br />
<br />
Against this table i have Model class for mapping from table to that type which looks :<br />
<br />
<pre class="brush: csharp">public class User
{
public int UserID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public bool IsActive { get; set; }
public bool IsDeleted { get; set; }
public DateTime CreatedAt { get; set; }
public int CreatedBy { get; set; }
public DateTime UpdatedAt { get; set; }
public int UpdatedBy { get; set; }
public string Email { get; set; }
}
</pre>
<br />
We want to fetch data from User table for which we will create a Repository class for User type and the we will write implementation to fetch records from User table from database. Our all methods that need to get data, insert data,update data or delete data from User table will reside in the <b>UserRepository</b> class.<br />
<br />
Here is the implementation of User Repository class:<br />
<br />
<pre class="brush: csharp">public class UserRepository : Repository<User>
{
private DbContext _context;
public UserRepository(DbContext context)
: base(context)
{
_context = context;
}
public IList<User> GetUsers()
{
using (var command = _context.CreateCommand())
{
command.CommandText = "exec [dbo].[uspGetUsers]";
return this.ToList(command).ToList();
}
}
public User CreateUser(User user)
{
using (var command = _context.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "uspSignUp";
command.Parameters.Add(command.CreateParameter("@pFirstName", user.FirstName));
command.Parameters.Add(command.CreateParameter("@pLastName", user.LastName));
command.Parameters.Add(command.CreateParameter("@pUserName", user.UserName));
command.Parameters.Add(command.CreateParameter("@pPassword", user.Password));
command.Parameters.Add(command.CreateParameter("@pEmail", user.Email));
return this.ToList(command).FirstOrDefault();
}
}
public User LoginUser(string id, string password)
{
using (var command = _context.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "uspSignIn";
command.Parameters.Add(command.CreateParameter("@pId", id));
command.Parameters.Add(command.CreateParameter("@pPassword", password));
return this.ToList(command).FirstOrDefault();
}
}
public User GetUserByUsernameOrEmail(string username, string email)
{
using (var command = _context.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "uspGetUserByUsernameOrEmail";
command.Parameters.Add(command.CreateParameter("@pUsername", username));
command.Parameters.Add(command.CreateParameter("@pEmail", email));
return this.ToList(command).FirstOrDefault();
}
}
}
</pre>
<br />
We are done for the <b>UserRepository </b>for new, i have added methods are wrote Stored Procedure to complete the assignment and now i will tell how to make use of it in the Service Layer or in Business Rule to do operations.<br />
<br />
<br />
<br />
<br />
First create an interface namely IUserService:<br />
<br />
<pre class="brush: csharp">[ServiceContract]
public interface IUserService
{
[OperationContract]
IList<User> GetUsers();
[OperationContract]
User RegisterUser(User user);
[OperationContract]
User Login(string id, string password);
[OperationContract]
bool UserNameExists(string username, string email);
}
</pre>
<br />
<br />
Here is my <b>WCF Service</b> for User that calls the <b>UserRepository </b>for doing operations:<br />
<br />
<pre class="brush: csharp">public class UserService : IUserService
{
private IConnectionFactory connectionFactory;
public IList<User> GetUsers()
{
connectionFactory = ConnectionHelper.GetConnection();
var context = new DbContext(connectionFactory);
var userRep = new UserRepository(context);
return userRep.GetUsers();
}
public User RegisterUser(User user)
{
connectionFactory = ConnectionHelper.GetConnection();
var context = new DbContext(connectionFactory);
var userRep = new UserRepository(context);
return userRep.CreateUser(user);
}
public User Login(string id, string password)
{
connectionFactory = ConnectionHelper.GetConnection();
var context = new DbContext(connectionFactory);
var userRep = new UserRepository(context);
return userRep.LoginUser(id, password);
}
public bool UserNameExists(string username, string email)
{
connectionFactory = ConnectionHelper.GetConnection();
var context = new DbContext(connectionFactory);
var userRep = new UserRepository(context);
var user = userRep.GetUserByUsernameOrEmail(username, email);
return !(user != null && user.UserID > 0);
}
}
</pre>
<br />
You can see that when creating instance of <b><span style="font-family: Thread-0000125c-Id-00000001;">UserRepository </span></b>i am injecting database context via constructor and then i am calling different methods from <b><span style="font-family: Thread-0000125c-Id-00000001;">userReposiory</span></b> according to need.<br />
<br />
Now in future when i add another table in database, i would create another Repository type and implement its Data Access logic and will call it same way, so applying Dependency Injection and Repository pattern we are following <b><span style="font-family: Thread-0000125c-Id-00000001;">DRY</span></b> principle to some extent, but i am sure we can make it more better than this.</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com1tag:blogger.com,1999:blog-5386436084600983822.post-38902028478913932242015-09-01T12:29:00.002-07:002016-06-26T16:27:42.176-07:00Check If username/email already registered using Remote Validation attribute in asp.net mvc<div dir="ltr" style="text-align: left;" trbidi="on">
<div>
When we create Registration form on a web application, we have to check that the email address and username that user is entering is unique and is not already. In asp.net mvc we have Validation Attribute feature in under <b>System.ComponentModel.DataAnnotations</b> and <b>System.Web.Mvc </b>which we can use for different type of Validations before sending data to be saved in persistent location.<br />
<br />
In <b>System.Web.Mvc </b>we have <b>Remote </b>attribute which is available in <b>asp.net mvc 4 </b>in which i am implementing it for this post, i am not sure if it is available in the earlier version of <b>asp.net mvc</b>.<br />
<br />
<br />
So i have this ViewModel:</div>
<br />
<pre class="brush: csharp"> public class SignUpViewModel
{
public int UserID { get; set; }
[Required(ErrorMessage = "First Name is required")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Last Name is Required")]
public string LastName { get; set; }
[Required(ErrorMessage = "Username is Required")]
[RegularExpression(@"^[a-zA-Z0-9]+$", ErrorMessage = "user name must be combination of letters and numbers only.")]
public string UserName { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string Password { get; set; }
[Required(ErrorMessage = "Password is Required")]
[System.Web.Mvc.Compare("Password",ErrorMessage="Both Password fields must match.")]
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "Email Address is required")]
[EmailAddress(ErrorMessage = "Invalid Email Address")]
public string Email { get; set; }
}
</pre>
<div>
<br />
As you can see there are laready attributes on the properties of ViewModel like <b>Required </b>which are mandatory fields, <b>RegularExpression </b>attribute for Email Address format validation and <b>Compare </b>attribute for comparing two properties values which is useful here for Password and Repeat Password textbox for making sure that user has verified what password he is setting.<br />
<br />
Now what will happen if user enters a username or Email Address which is already registered, one way is to check in post action for username and Email Address and show user error message that username or Email Address is already taken which does not looks though, as validation should be done before posting data to action using unobtrusive validtion.<br />
<br />
Now here we will use <b>Remote </b>attribute which will check for both UserName and Email Address field, here is how it will be done:<br />
<br />
<pre class="brush: csharp"> [Required(ErrorMessage = "Username is Required")]
[RegularExpression(@"^[a-zA-Z0-9]+$", ErrorMessage = "user name must be combination of letters and numbers only.")]
[Remote("UsernameExists","Account",HttpMethod="POST",ErrorMessage="User name already registered.")]
public string UserName { get; set; }
[Required(ErrorMessage = "Email Address is required")]
[EmailAddress(ErrorMessage = "Invalid Email Address")]
[Remote("EmailExists", "Account", HttpMethod = "POST", ErrorMessage = "Email address already registered.")]
public string Email { get; set; }
</pre>
<br />
Remote Attribute has different parameters to be specified:<br />
<br />
<ol style="text-align: left;">
<li><b>Action Name which will be called which will have input parameter for this property value</b></li>
<b>
</b>
<li><b>Controller Name of which action will be executed</b></li>
<b>
</b>
<li><b>HttpMethod (Get or Post)</b></li>
<b>
</b>
<li><b>ErrorMessage (Error Message that will be displayed if validation fails) </b></li>
</ol>
</div>
Let's come to the action part we need to write action method in the Account controller for Validation, for this post just for clearing to readers i am just checking for specific username and email (my name and dummy email address), but in your project you will need to check in your database for that particular criteria and return true or false respectively.<br />
<br />
<br />
Here is the action code:<br />
<br />
<pre class="brush: csharp">public JsonResult UsernameExists(string username)
{
return Json(!String.Equals(username,"ehsansajjad",StringComparison.OrdinalIgnoreCase));
}
public JsonResult EmailExists(string email)
{
return Json(!String.Equals(email, "ehsansajjad@yahoo.com", StringComparison.OrdinalIgnoreCase));
}
</pre>
<br />
Here is the complete View code:<br />
<br />
<pre class="brush: html">@model CustomValidationMessageHelper.ViewModels.SignUpViewModel
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>SignUp</title>
<link href="@Url.Content("~/Content/jquery.qtip.css")" rel="stylesheet" />
<script src="@Url.Content("~/Scripts/jquery-1.9.1.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.qtip.min.js")" type="text/javascript"></script>
</head>
<body>
<div>
@using (Html.BeginForm("SignUp", "Account", FormMethod.Post, new { @class = "form-inline", role = "form" }))
{
@Html.AntiForgeryToken()
<div class="row">
<div class="span8 offset5 aui-page-panel">
<div>
<h2>Sign Up</h2>
</div>
<fieldset style="margin-bottom: 40px;">
<legend style="border-bottom: 1px solid gray; font-size: 16px;">Basic Information</legend>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr id="tr_basic">
<td style="vertical-align: top;" width>
<div id="basicinfo" style="width: 100%">
<div style="height: auto !important; overflow-y: visible;">
<table cellpadding="3">
<tbody>
<tr>
<td width="150">
@Html.LabelFor(model => model.FirstName, new { @class = "sr-only" })
</td>
<td>
@Html.TextBoxFor(model => model.FirstName, new { @class = "form-control input-sm" })
@Html.ValidationMessageFor(model => model.FirstName)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.LastName)
</td>
<td>
@Html.TextBoxFor(model => model.LastName, new { @class = "input-xsmall" })
@Html.ValidationMessageFor(model => model.LastName)
</td>
</tr>
<tr>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</table>
<legend style="border-bottom: 1px solid gray; font-size: 16px;">Account Information</legend>
<table cellpadding="5">
<tr>
<td width="150">
@Html.LabelFor(model => model.UserName)
</td>
<td>
@Html.TextBoxFor(model => model.UserName)
@Html.ValidationMessageFor(model => model.UserName)
</td>
<td id="tdValidate">
<img id="imgValidating" src="@Url.Content("~/Images/validating.gif")" style="display:none;" /></td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.Password)
</td>
<td>
@Html.PasswordFor(model => model.Password)
@Html.ValidationMessageFor(model => model.Password)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "control-label" })
</td>
<td>
@Html.PasswordFor(model => model.ConfirmPassword)
@Html.ValidationMessageFor(model => model.ConfirmPassword)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(m => m.Email, new { @class = "control-label" })
</td>
<td>
@Html.TextBoxFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
</td>
</tr>
<tr>
<td>
<p>
<div class="control-group">
<div class="controls">
<input id="btnRegister" type="submit" class="btn btn-primary" value="Register" />
</div>
</div>
</p>
</td>
<td></td>
</tr>
</table>
</div>
</div>
}
</div>
</body>
</html>
</pre>
<br />
Now when i will enter username <b>"ehsansajjad" </b>or Email Address<b> "ehsansajjad@yahoo.com" </b>validation will get fired that user already exists :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCvb-LBMxJaviVDW-qCpPTh64p7wnuXsQSM9oQJ-lbzCzE0e-nLpf4A2ua0qqYisZf1ldTz8sy4ThzEZzxhyM6YN0BSIkNtKioy1jXTfMOcMaFJcgw0487I5Y5T5-EwbXwOs-WhYplYL1H/s1600/Validation.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCvb-LBMxJaviVDW-qCpPTh64p7wnuXsQSM9oQJ-lbzCzE0e-nLpf4A2ua0qqYisZf1ldTz8sy4ThzEZzxhyM6YN0BSIkNtKioy1jXTfMOcMaFJcgw0487I5Y5T5-EwbXwOs-WhYplYL1H/s1600/Validation.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-TxxF7qgJ5toXc_Pc_0u4yn_9oOxsCXN1hEE8nHYQG2_KfDTyH4Zrvv1bWW3bz2fgOMOZzI9btXXdsYK6ytUS_YVA5aGx57Z0c1LUrtMCzGmfpVUTA40SLTpN8xaTH-IqFMZPtQomZ9C5/s1600/Validation.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYIfGYc1ZQAWscWAYofKg-YyjLkeYr29-lDTzffTc7kRGwJmhHEm9bJ50UCnuFHt4Mow4hzC5u2m085dleEfSuB6DUC7_dd4zzb6GmiQV6Pd05Zsln5oOfFzj1v9EjTAqazsODvZzLGOMu/s1600/Validation.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<br />
<br />
You can <a href="https://drive.google.com/file/d/0Bzzb_9_aasccbURzTEJwUG5mUDQ/view?pli=1" target="_blank">download the sample project from here</a>.<br />
<br />
<div>
<ol style="text-align: left;">
</ol>
</div>
</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0tag:blogger.com,1999:blog-5386436084600983822.post-61677130850835215302015-08-27T11:24:00.000-07:002016-06-26T16:30:32.127-07:00Mapping ViewModel to Model in asp.net mvc using implicit operator in C#<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.codeproject.com/" rel="tag" style="display: none;">CodeProject</a>
<br />
<h2 style="text-align: left;">
Background:</h2>
In asp.net mvc we have three important things in which we are moving all the time which is Model, View and Controller. Sometimes we want specific information of model to be passed from View to action, but if we use the Model classes that are mapped to our database tables make things messy, as all the model is round tripping from View to action or vice versa.<br />
<br />
<br />
Consider the following model class which is mapped to the user table in my database.<br />
<br />
<pre class="brush: csharp">namespace JIRA.Domain.Models
{
public class User
{
public int UserID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public bool IsActive { get; set; }
public bool IsDeleted { get; set; }
public DateTime CreatedAt { get; set; }
public int CreatedBy { get; set; }
public DateTime UpdatedAt { get; set; }
public int UpdatedBy { get; set; }
public string Email { get; set; }
}
}
</pre>
<br />
Here is my database table :<br />
<br />
<pre class="brush: sql">CREATE TABLE [dbo].[tblUser] (
[UserID] INT IDENTITY (1, 1) NOT NULL,
[FirstName] NVARCHAR (25) NULL,
[LastName] NVARCHAR (25) NULL,
[UserName] NVARCHAR (25) NULL,
[Password] NVARCHAR (25) NULL,
[IsActive] BIT NULL,
[IsDeleted] BIT NULL,
[CreatedBy] INT NULL,
[CreatedAt] DATETIME NULL,
[UpdatedBy] INT NULL,
[UpdatedAt] DATETIME NULL,
[Email] NVARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([UserID] ASC)
);
</pre>
<br />
<br />
So what happens normally is developers strongly type their view with the model class that is mapped with the table in our db which is not a good approach, as our View don't needs all information of the table every time.<br />
<h2 style="text-align: left;">
Scenario: </h2>
Now consider the scenario of Register/SignUp of user in which we have different fields form which some will map to the User class but as User is registering so some properties of Model are useless here which will be posted when user submits form and there are some properties that we may need additional but they are not mapped in the table, you can take example when user registers we take Password from user two times for Confirming, in that case we don't want to change our <b>Model </b>that represents our <b>Entity </b>in the database, so <b>ViewModel </b>comes in. <br />
<br />
<h2 style="text-align: left;">
ViewModels and Models:</h2>
<b>ViewModels </b>are specific to the Views, we put information in View Model that we need on the particular View.Here is the snippet that is not a preferred way,So now we will create a <b>ViewModel</b> for Register View which will have properties specific to that View that it needs to post and we will map the <b>ViewModel </b>properties to <b>Entity Model</b> that represents our table and will insert it in the database.<br />
<h2 style="text-align: left;">
Example:</h2>
Following is the ViewModel for the current use case that i explained above:<br />
<br />
<pre class="brush : csharp">namespace JIRA.ViewModels
{
public class RegisterViewModel
{
public int UserID { get; set; }
[Required(ErrorMessage = "First Name is required")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Last Name is Required")]
public string LastName { get; set; }
[Required(ErrorMessage = "Username is Required")]
[RegularExpression(@"^[a-zA-Z0-9]+$", ErrorMessage = "user name must be combination of letters and numbers only.")]
[Remote("UsernameExists","Account",HttpMethod="POST",ErrorMessage="User name already registered.")]
public string UserName { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string Password { get; set; }
[Required(ErrorMessage = "Password is Required")]
[System.Web.Mvc.Compare("Password",ErrorMessage="Both Password fields must match.")]
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "Email Address is required")]
[EmailAddress(ErrorMessage = "Invalid Email Address")]
[Remote("EmailExists", "Account", HttpMethod = "POST", ErrorMessage = "Email address already registered.")]
public string Email { get; set; }
}
}
</pre>
<br />
<br />
<br />
Now we will strongly type our View with the <b>RegisterViewModel </b>type which only contains properties that are related with the Register View:<br />
<br />
<pre class="brush: html">@model JIRA.ViewModels.RegisterViewModel
using (Html.BeginForm("SignUp", "Account", FormMethod.Post, new { @class = "form-inline", role = "form" }))
{
@Html.AntiForgeryToken()
<div class="row">
<div class="span8 offset5 aui-page-panel">
<div>
<h2>Sign Up</h2>
</div>
<fieldset style="margin-bottom: 40px;">
<legend style="border-bottom: 1px solid gray; font-size: 16px;">Basic Information</legend>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr id="tr_basic">
<td style="vertical-align: top;" width>
<div id="basicinfo" style="width: 100%">
<div style="height: auto !important; overflow-y: visible;">
<table cellpadding="3">
<tbody>
<tr>
<td width="150">
@Html.LabelFor(model => model.FirstName, new { @class = "sr-only" })
</td>
<td>
@Html.TextBoxFor(model => model.FirstName, new { @class = "form-control input-sm" })
@Html.MyValidationMessageFor(model => model.FirstName)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.LastName)
</td>
<td>
@Html.TextBoxFor(model => model.LastName, new { @class = "input-xsmall" })
@Html.MyValidationMessageFor(model => model.LastName)
</td>
</tr>
@*<tr>
<td>
@Html.LabelFor(model => model.Email)
</td>
<td>
@Html.TextBoxFor(model => model.Email, new { @class = "required" })
@Html.MyValidationMessageFor(model => model.Email)
</td>
</tr>*@
<tr>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</table>
<legend style="border-bottom: 1px solid gray; font-size: 16px;">Account Information</legend>
<table cellpadding="5">
<tr>
<td width="150">
@Html.LabelFor(model => model.UserName)
</td>
<td>
@Html.TextBoxFor(model => model.UserName)
@Html.MyValidationMessageFor(model => model.UserName)
</td>
<td id="tdValidate">
<img id="imgValidating" src="@Url.Content("~/Images/validating.gif")" style="display:none;" /></td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.Password)
</td>
<td>
@Html.PasswordFor(model => model.Password)
@Html.MyValidationMessageFor(model => model.Password)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "control-label" })
</td>
<td>
@Html.PasswordFor(model => model.ConfirmPassword)
@Html.MyValidationMessageFor(model => model.ConfirmPassword)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(m => m.Email, new { @class = "control-label" })
</td>
<td>
@Html.TextBoxFor(model => model.Email)
@Html.MyValidationMessageFor(model => model.Email)
</td>
</tr>
<tr>
<td>
<p>
<div class="control-group">
<div class="controls">
<input id="btnRegister" type="submit" class="btn btn-primary" value="Register" />
</div>
</div>
</p>
</td>
<td></td>
</tr>
</table>
</fieldset>
</div>
</div>
}
}
</pre>
<br />
and our action would look like:<br />
<br />
<pre class="brush: csharp"> [HttpPost]
[AllowAnonymous]
public ActionResult SignUp(RegisterViewModel registerVM)
{
if (ModelState.IsValid)
{
// save to database
}
return View(registerVM);
}
</pre>
<br />
<br />
Our service method takes object of type <b>User</b> as input which is our Domain or Entity Model so we will have to convert <b>RegisterViewModel </b>object to <b>User </b> object, a quick and dirty way is to create an instance of type <b>User </b>and map it to <b>RegisterViewModel </b>before calling service method.<br />
<br />
Here it is:<br />
<br />
<pre class="brush: csharp"> [HttpPost]
[AllowAnonymous]
public ActionResult SignUp(RegisterViewModel registerVM)
{
if (ModelState.IsValid)
{
User user = new User
{
FirstName = registerVM.FirstName,
LastName = registerVM.LastName,
UserName = registerVM.UserName,
Email = registerVM.Email,
Password = registerVM.Password
};
var result = authenticateService.RegisterUser(user);
</pre>
<br />
<br />
The above code will obviously work but it will cause code redundancy and in result it will be violation of <b>DRY </b>principle,because
in future there is possibility of mapping ViewModel instance to Model
instance or vice versa and we will end up writing same code again and again at different
places where it is needed which is not good.<br />
<br />
<h2 style="text-align: left;">
implicit operator in c#:</h2>
<br />
Here comes in the <b><a href="https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx" target="_blank">implicit operator feature</a></b> provide by c#, we will write our operator for <b>RegisterViewModel </b>and <b>User </b>class so that they can be implicitly converted to each other where ever needed. We will have to modify the implementation of <b>RegisterViewModel </b>for this:<br />
<br />
We will have to add these two operators in the <b>RegisterViewModel </b>class:<br />
<br />
<pre class="brush: csharp"> public static implicit operator RegisterViewModel(User user)
{
return new RegisterViewModel
{
UserID = user.UserID,
FirstName = user.FirstName,
UserName = user.UserName,
Password = user.Password,
ConfirmPassword = user.Password,
Email = user.Email
};
}
public static implicit operator User(RegisterViewModel vm)
{
return new User
{
FirstName = vm.FirstName,
LastName = vm.LastName,
UserName = vm.UserName,
Email = vm.Email,
Password = vm.Password
};
}
</pre>
<br />
So we have written the implicit conversion between these two types at one place and we will be reusing it everywhere we need.<br />
<br />
yes i mean that, now these two types can be implicitly convertible / cast-able in to each other.<br />
<br />
My action would look like this now:<br />
<br />
<pre class="brush: csharp"> [HttpPost]
[AllowAnonymous]
public ActionResult SignUp(RegisterViewModel registerVM)
{
if (ModelState.IsValid)
{
var result = authenticateService.RegisterUser(registerVM); // implicit conversion from RegisterViewModel to User Model
RegisterViewModel vm = result; // see implicit conversion from User model to RegisterViewModel
return View(vm);
}
return View(registerVM);
}
</pre>
<h2 style="text-align: left;">
</h2>
<h2 style="text-align: left;">
Summary:</h2>
By implementing implicit operator for <b>Model</b> to <b>ViewModel </b>mapping and vice versa,we can see that our action is more cleaner now, as conversion is being moved to a central place due to which our code is reusable as well, and we are trying to follow <b>DRY </b>principle to some extent.<br />
<br />
You can read more about <a href="https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx" target="_blank">implicit operator at MSDN here</a>.</div>
Ehsan Sajjadhttp://www.blogger.com/profile/17686377274911040657noreply@blogger.com0