-
According to browser statistics on w3school.com Internet Explorer lost 70%:
and 10 years ago
| 2003 | Internet Explorer | Mozilla | Netscape | Opera |
| January | 84.6 % | 4.0 % | 4.0 % | |
It can be seen that IE is still loosing every month. Should we still design pages for IE6 or IE7?
-
There’s many articles how to check local IP addresses in C#, but many of them (OK, first few links on Google) uses DNS. The problem is that DNS is in Application layer in OSI model, so the algorithm relies on DNS usage on server. I think that better is to use Network layer directly:
1: public static bool IsLocalHost(IPAddress ipAddress)
2: {
3: var allNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
4: return allNetworkInterfaces
5: .Contains(adapter => adapter.GetIPProperties().UnicastAddresses
6: .Where(address => address.Address.AddressFamily == AddressFamily.InterNetwork || address.Address.AddressFamily == AddressFamily.InterNetworkV6)
7: .Contains(address => address.Address.Equals(ipAddress)));
8: }
I skipped some checks of the method input just to demonstrate how it can be done.
Hopefully you’ll find this useful
-
This is a real life example of Smurf naming convention :)
-
Few days ago I had to re-implement some piece of code. It should be easy, but I spent 20 minutes to change one line of code. Why?
Some background
Because I always try to write unit tests I had to change creation of a dependent class. The instantiation and main call was done like this:
var version = new Version(BuildInfo.Version.Major, 0, 0, BuildInfo.Version.Revision);
var manager = new LicenseManager();
var license = manager.GetLicense(appName, version);
Because the class implements ILicenseManager and we're using Service Locator, I rewrited the code to use interface instead:
var version = new Version(BuildInfo.Version.Major, 0, 0, BuildInfo.Version.Revision);
var manager = ServiceLocator.GetService<ILicenseManager>();
var license = manager.GetLicense(appName, version.ToString());
Great, now the call is testable by a unit test. But as you can notice there's a change in GetLicense() method call. It's because the interface doesn't include the overloaded method with strongly typed parameter version. It takes string instead. But I don't mind let's call ToString().
Step-by-step to solve the problem
After testing the code I found that the overloaded GetLicense() method returns null. Why? I had to do some steps to find the reason, here they are:
- Analyzing log files and founding the NullReferenceException - 20 seconds
- I checked method documentation (it was fast, ReSharper has a nice shortcut Ctrl+Shift+F1), but no documentation exists - 10 seconds
- I had to debug the program to be sure that parameters are correct, so I started debugging (remember It should be small change and I didn't have written unit tests yet) - it took 5 minutes to start the program (because of compilation and web site optimization)
- I put breakpoint to the source code and I was going to web site to test the call - 30 seconds
- I checked parameters using Watch - parameters were OK,expression version.ToString() returned "5.0.0.565" properly - 10 seconds
- I checked manager instance if it was instantiated properly (some casting problems) - 60 seconds
- I found out that the manager is in referenced assembly, so I cannot step into source codes directly, so I tried to find source codes - 10 minutes
- I found that I'm not able to find source code in our version control system, I have to treat it as third-party library, so I started ILSpy and looked at the method implementation - 30 seconds
- I finally got it, the method requires version.Major.ToString() – 5 seconds
- I had to go to coffee - 3 minutes
Final implementation
var version = new Version(BuildInfo.Version.Major, 0, 0, BuildInfo.Version.Revision);
var manager = ServiceLocator.GetService<ILicenseManager>();
var license = manager.GetLicense(appName, version.Major.ToString());
Conclusion
We all know such problem solving. It happens to us every day. Checking documentation, log analyzing, debugging code. We spend a lot of time with solving such issues. If you study the step-by-step above you can easily find out that if the method had documentation the solution would take 30 seconds instead of 20 minutes. Following takes me about 30 seconds to write:
/// <summary>
/// Returns license based on application name and major version number.
/// </summary>
But it isn't the only way how to precede errors. In first place the interface should contain the overloaded method with strongly typed version parameter.
I found some other problems with designing classes:
- If we publish a method on a concrete class instead on an interface, consumers will always use concrete implementation, not the interface.
- If we write documentation on public methods we will safe our time
- If we design strongly typed parameters we will avoid typo and additionally we will safe time with parsing strings
It can be seen that good class design matters. And I think that matters a lot. We have to remember that
We design classes for us
Do you have your own suggestions how to design classes or what anti-patterns we should avoid?
-
Using WinMerge with TFS
Great, thank you Rory
Ernest
-
This is
brief comparison of code some development tools integrated in Visual Studio.NET, which I did for my new company. This post doesn't try to compare all refactorings, but it tries to compare product as a whole. The comparison targets VS.NET 2010 and C#.
JetBrains ReSharper
- http://www.jetbrains.com/resharper/
DevExpress CodeRush
- http://devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/
Telerik JustCode
- http://www.telerik.com/products/justcode.aspx
I used Google as an information source. If anything is wrong please write a comment, I will update the table.
UPDATE: I updated the table with some details according comments below. Thank you all for your help.
|
Feature\Product
|
JetBrains
RerSharper C#
v7.0
|
DevExpress
CodeRush Refactor! Pro
v12.1.5
|
Telerik
JustCode
v2012.1.608.4
|
|
Personal
Price
|
€142+VAT
|
$249.99
|
$249
|
|
Commercial
Price
|
From €237+VAT
|
Contact
|
$249.99
|
|
Free
version
|
Trial
|
Xpress
11.2.12
|
Trial
|
|
VS.NET
2010 (.NET 4.0)
|
Yes
|
Yes
|
Yes
|
|
VS.NET
2012 (.NET 4.5)
|
Yes
|
Yes
|
Yes
|
|
Technologies/Languages
|
|
EDM
|
No
|
No
|
No
|
|
Silverlight
|
Yes
|
Yes
|
Yes
|
|
Windows
Phone
|
Yes
|
No
|
Yes
|
|
Metro
style apps
|
Yes
|
No
|
Yes
|
|
WinRT
|
Yes
|
No
|
Yes
|
|
XAML
|
Yes
|
Yes
|
Yes
|
|
Javascript
|
Yes
|
Yes
|
Yes
|
|
CSS
|
Yes
|
Yes
|
Yes
|
|
XML
|
Yes
|
Yes
|
Yes
|
|
Scripting
|
MSBuild/NAnt
|
No
|
No
|
|
Extensibility
(plugins)
|
Yes
|
Yes
|
Yes
|
|
Features
|
|
Code
analysis
|
Class/Solution
|
Class/Solution
|
Class/Solution
|
|
Unit test
runner
|
NUnit,MSTest,MbUnit,NBehave,csUnit,xUnit.Net
|
NUnit,MSTest,MbUnit,
MSpec,xUnit
|
MSTest,
xUnit, NUnit, MbUnit, Galio, MSpec, QUnit, Jasmine
|
|
Silverlight
unit test runner
|
AgUnit
plugin (v 0.6)
|
SlUnitTesting
included
|
No
|
|
Call/Value
tracking
|
Yes
|
No
|
No
|
|
Annotated
Framework
|
Yes (with
own annotations too)
|
No
|
No
|
|
Code
coverage
|
JetBrains dotCover
product
|
No
|
No
|
|
Duplicate
Detection and Consolidation
|
No
|
Yes
|
No
|
|
Code
metrics
|
No
|
Yes
|
No
|
|
Navigation
|
|
Navigation
|
Camel Humps
|
Camel
Humps
|
Camel
Humps
|
|
Type
Hierarchy
|
Yes
|
No
|
|
|
File
Structure
|
Yes
|
No
|
|
|
Stack
Trace Explorer
|
Yes
|
No
|
|
|
Find
Usages
|
Yes
|
Yes (The References Toolwindow)
|
Yes
|
|
Tab to
next reference
|
No
|
Yes
|
Yes (Ctrl+Alt+Up/Down)
|
|
Code Generation/Refactoring
|
|
Create
from usage
|
Yes
|
Yes
|
Yes
|
|
Templates
|
Yes
|
Yes
|
Yes
|
|
Cleanup
|
Yes
|
Yes
|
Yes
|
|
Move
Class/Method
|
Yes
|
Smart
Copy&Paste
|
Yes
|
|
Naming
Style checker
|
Yes
|
Code Style Enforcer plug-in
|
Yes
|
|
Intelligent
paste
|
No
|
Yes (type cast, field declaration, color reference …)
|
No
|
|
Context menu fixes
|
Yes
|
Yes
|
Yes
|
-
Probably all of you have some own programming jargon. You will probably fall in love to New programming jargon post (I did). In my last job, the favorite was Smurf Naming Convention and MEGAMOTH!
-
Inversion of Control (IoC) is a very nice concept, one of my favourite. It helps easily extend existing code without need to make change to the extended library. It is based on an idea of injecting class dependency into an object oriented code. What does it mean?
There is many posts on the Net with subject Inversion of Control (IoC). Shortly it means exactly what it says: the pattern inverses the way how objects controls other objects. The straightforward way of using other object is to create it directly with constructor. The other way (in IoC manner) is to request/gain the object from someone else.
Nice simple example can be seen here.
This concept is not new to many developers. For example about 18 years ago this concept was used in Turbo Vision to create text user interface:
TMenuBar *newMenu = new TMenuBar( r,
*new TSubMenu( "~\360~", kbAltSpace ) +
*new TMenuItem( "~A~bout", cmAbout, kbAltA, hcNoContext ) +
newLine() +
// this TMenuItem will bring up another menu
*new TMenuItem( "Exit", 0, new TMenu(
*new TMenuItem( "Exit & ~S~ave", cmQuit, kbAltX, hcNoContext, 0,
new TMenuItem( "Exit & ~A~bandon", cmQuit, kbAltY, hcNoContext, 0,
new TMenuItem( "Just ~Q~uit", cmQuit, kbAltZ, hcNoContext, 0,
new TMenuItem( "~N~ext Level", 0, new TMenu(
*new TMenuItem( "~O~ne", cmQuit, kbAltX, hcNoContext, 0,
new TMenuItem( "~T~wo", cmQuit, kbAltX ))))
)))), hcNoContext)
);
However I think that in these days the concept is more important than ever. It is so important that I recommend to think about it a little. What it can bring to us today?
Every customer has different needs
First, it may solve the problem of customizations. Think that you have a software which you sell to many customers. The problem is that every customer wants the software to behave in a different manner and if you have dependencies between classes hard coded using constructors you have only 2 choices. You may tell the customer that the software doesn’t support this behavior, because the change will influence other customers when you give them upgrade. When you say this you may loose the customer.
Probably you change the software. However you need to make the change only for this customer so you create a copy of the source code and make changes in the copy. Now you have a separate copy of a software for each customer and everybody is happy. Except a developer, who must keep many programs up to date (think that every copy is independent program). Copy and paste approach raises many problems for example bug fixing.
IoC (along with good object oriented design) allows developers not to make source code copies. Instead of copying developers are able to take advantage of inheritance. With IoC concept you can inherit the class, change its behaviour and let dependent objects use instances of your inherited class. Sounds good, doesn’t?
Error free upgrades
Another problem is quality. If you have a complex software it’s very hard to keep it in a good quality (so without errors) while you add new features. Any change in the software may arise to a problem because a small change in one class may cause an error in another dependent class. How can IoC help us to solve this problem? The solution to this is not IoC itself but it’s unit testing. And in unit testing is IoC very important.
Unit test is piece of code which tests output of methods and classes. Proper unit test needs a tested class to have good object oriented design and it must use IoC. Then the unit test is able to run very fast (milliseconds) and it ensures that the class remains in a good condition after you’ve made a change in it. Unit tests must test functionality of a single class not the whole underlying framework so you need to simulate dependent objects and here is the IoC concept important, because in unit testing you usually create fake/mock objects on which tested classes depends.
Conclusion
You may see that the Inversion of Control concept becomes more and more important, because developers are pushed by customers to deliver programs in some quality and flexible enough to meet individual customer requirements. However the concept is not the only solution. The code needs to meet object oriented design mainly it must use encapsulation of its inner fields. It’s not difficult to achive this encapsulation. You can use many of refactoring methods to clean smelly code, but this is not goal of this post.
If you found my article useful you can continue to read what Martin Fowler writes about Inversion of Control.
I wish you happy coding
-
How to get rid of the annoying prompt of UAC (User Access Control) when starting applications in Windows 7/Vista, if you don't want to turn the security down?
Run application using special shortcut!
http://social.technet.microsoft.com/Forums/en/itprovistaact/thread/56cd9a67-ebff-4151-91a7-3a215a3ba15f
-
Did you know that nullable column MobileAlias of table aspnet_Users has default constraint which inserts NULL value into the column?
Here is part of a create script generated with Management Studio. The table was originally created by aspnet_regsql.exe utility in .NET 2.0.
CREATE TABLE [dbo].[aspnet_Users](
[ApplicationId] [uniqueidentifier] NOT NULL,
[UserId] [uniqueidentifier] NOT NULL DEFAULT (newid()),
[UserName] [nvarchar](256) NOT NULL,
[LoweredUserName] [nvarchar](256) NOT NULL,
[MobileAlias] [nvarchar](16) NULL DEFAULT (NULL),
[IsAnonymous] [bit] NOT NULL DEFAULT ((0)),
[LastActivityDate] [datetime] NOT NULL,
PRIMARY KEY NONCLUSTERED
(
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
It's funny. Isn't it?
-
Před časem běžela na blog.vyvojar.cz série článků od Tomáše Pastorka porovnávajících skriptovací jazyky pro .NET (mimochodem, moc díky za to porovnání). Můj oblíbený jazyk Boo se neumístil vůbec špatně. Proto se s vámi chci podělit o Boo Quick Reference Cards, které jsem si pro sebe kdysi vytvořil. Je to zatím první verze, která ukazuje pouze práci se základními typy.
Enjoy
-
If you need to integrate PayPal into your WebSite, you may encounter several small problems starting from choosing the right Payment service, through finding the right library and ending with testing payments. Here are some useful links, which I gathered over a period of time when I developed a payment service.
- On PayPal WebSite, you can find some Payment services comparison. There is a Recommendation wizard which you can start with.
- After that you'll need some documentation about PayPal protocols. The documentation is placed at a Developer central, where you can find many useful information. Along with the documentation it is good to use some existing library. Some libraries you can find on PayPal SDKs page. I compiled a library named com.paypal.wps, see later in this article.
- Next you will need some testing account. For this purpose PayPal provides a Testing SandBox - PayPal. Its a copy of real server and to access the testing environment you need to register with your email to this sandbox. The registration email is not your testing account! The email only allows you to enter the PayPal Sandbox where you can create as many testing account as you need.
For our needs we choose to implement Website Payment Standard, which uses a HTML form to communicate with PayPal server. The form must contain some HTML variables, which are described in the Website Payments Standard Integration Guide, which is accesible on the documentation page introduced earlier.
ASP.NET and PayPal Forms Problem
Here you will probably encounter a problem with HTML forms, because PayPal requires a form with action attribute set to PayPal server, however in ASP.NET 4.0 the Page still could contain only one HTML form, So you cannot include two forms (one for ASP.NET and one for PayPal) on the same page. Fortunately there was many articles written about this topic and I found very useful article How to Integrate Both Google Checkout and PayPal In 3 Steps which offers simple solution using Button.PostBackUrl Property which is new in .NET 2.0. These guys found that PayPal server accepts the form which is redirected using this property:
<asp:imagebutton id="btnSubmitPaypal" runat="server"
imageurl="/images/checkout-paypal.gif" alternatetext="Purchase Using
Paypal" postbackurl="https://www.paypal.com/us/cgi-bin/webscr" />
If you develop in some older .NET frameworks, try solution with nested MasterPages.
Website Payments Library Toolkit for .NET
PayPal allows developers to download Website Payments Standard Toolkit (WPST). However this toolkit was written by some java developer, who didn't know ASP.NET programming environment. I think the object oriented part of the code is written very well, but the web forms part is very bad. The author of the toolik integrates classes into WebApplication so it is not feasible to use the code directly in your own application. So I split the web application and I compiled the classes with the VS.NET 2005 into the library called com.paypal.wps. I adhere to the naming convention of the author and I didn't change the code at all, except a small change in calling CAPICOM component
You can find the solution in attached zip file.
-
Did you ever hear about Smelly Code? No? Those of you, who are not always satisfied with their code, will be delighted with
this article Smelly Code. Shortgun Surgery, Feature Envy and Smelly Switches are refactoring methods, how to detect and improve existing code. The motivation is to minimize code duplication, aggregate similar code and thus accelerate developing of quality code.
-
ViewState in ASP.NET is very complex subject. There are several problems in saving data in ViewState. Here is one of them. The problem is demonstrated with Repeater control, but I think the problem will raise when you use GridView or any other Data-Bound control too, but I didn't test it.
Hope this will help somebody out there who is in trouble.
Summary
When you develop custom control, you usually need to save some data into ViewState. This is usually done like this:
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(false)]
[Themeable(false)]
public string UploadedFileName
{
get
{
object o = ViewState["UploadedFileName"];
if (o == null)
return string.Empty;
return (string) o;
}
set
{
ViewState["UploadedFileName"] = value;
}
}
This is the way how to persist some state to survive PostBack. However sometimes you should notice, that on PostBack the property is not loaded with the value which was to it set last request. This article tries to describe one of many reasons, what should cause this problem.
The problem with programatically databinding repeater rows
Assume that your control is in ItemTemplate of your Repeater, so the control will be instantiated when the repeater will perform Databind.
If your control perform databinding too and needs to have filled some property (the property UploadedFileName in my case), you have two ways, how to programatically fill these properties during the Databind.
- Repeater.ItemCreated
- Repeater.ItemDataBound
The second case is worst because it will lead in two times databindings of your control. If you don't mind about two times databinding you will probably notice no error.
The first case is bettter, because you can deliver your data from repeaters Datasource to your control BEFORE your control will be databind for the first time.
You will probably do this like this:
protected void Page_Load(object sender, EventArgs e)
{
repFiles.ItemCreated += repFiles_ItemCreated;
}
void repFiles_ItemCreated(object sender, RepeaterItemEventArgs e)
{
MyControl view = (MyControl) e.Item.FindControl("myControl");
DataRowView dataItem = (DataRowView)e.Item.DataItem;
if (dataItem != null && view != null)
{
view.UploadedFileName = (string) dataItem["UploadedFileName"];
}
Button btnShowData= (Button)e.Item.FindControl("btnShowData");
if (btnShowData!= null) btnShowData.Click += btnShowData_Click;
}
void btnShowData_Click(object sender, EventArgs e)
{
MyControl view = (MyControl)((Button)sender).NamingContainer.FindControl("myControl");
}
You will notice no problem, because everything is filled with proper values.
You can see that in this example there is a button which perform databinding of my control and it is the the case you will notice a problem.
If i click the button which is in the repeaters ItemTemplate, i could debug that the property UploadedFileName which was set programatically is not filled properly and the second databinding process was not successfull. I set the property during repeater databinding and I save the value into ViewState. Why the value is not accesible during PostBack? It is because the ViewState for my control is not properly saved to the page and thus the value is not extracted on PostBack request.
Deeper into .NET
I mentioned that the problem is in saving ViewState of my control. I performed some investigation and I found the problem. If you look at the SaveViewState method you will see that the method "Saves any state that was modified after the TrackViewState method was invoked.".
The problem is that ViewState property of my control is filled properly, the IsTrackingViewState property is true, however the SaveViewState method returns null!
To solve the problem let's look to the state of child controls of the repeater. Every control must go through several phases, see Control Execution Lifecycle. My control participate in this life cycle too. When repeater performs databinding, it ensures that instantiated controls participates in this phases.
When repeater fires ItemCreated event than the state of my control is Constructed. It is nor initialized nor loaded with viewstate and the IsTrackingViewState property is false so control is not tracking its ViewState! It is why the SaveViewState method returns null. The control don't know about change in ViewState, so it doesn't try to save its state.
The TrackViewState method of controls created by the repeater is called through their initialization which is performed AFTER the ItemCreated event and BEFORE the ItemDataBound event. The phases goes in this order:
- Repeater creates child controls
- Repeater.ItemCreated event is fired - child controls are created, but they are not initialized
- Repeater adds controls to its Controls collection, this ensures control initialization, the initialization process is done thanks to notification to owner of the controls collection using the AddedControl method), during initialization the TrackViewState method is called.
- Repeater.ItemDataBound event - child controls are initialized and they are tracking their ViewState
This is why the value is not saved into page. Simple solution
Move the code which fills child controls to ItemDataBound event like this:
protected void Page_Load(object sender, EventArgs e)
{
repFiles.ItemDataBound += repFiles_ItemDataBound;
}
private void repFiles_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
MyControl view = (MyControl) e.Item.FindControl("myControl");
DataRowView dataItem = (DataRowView)e.Item.DataItem;
if (dataItem != null && view != null)
{
view.UploadedFileName = (string) dataItem["UploadedFileName"];
view.DataBind();
}
}
This is nice simple solution, but we need to some better solution than this to ensure that the problem will not repeat in the future.
Better solution
The main problem is in wrong understanding what is going on. When we are developing control and we want to rely on data which comes through the DataBind process we are devloping Data-Bound control and we should do it correctly, because ASP.NET DataBinding is very complex feature.
The right way is to implement DataSource property and ensure that the control remembers values from the DataSource during DataBind process. You can see details in the article Developing Custom Data-Bound Web Server Controls for ASP.NET on MSDN.
In my case the solution is to implement my control in different way:
// this method is used to save value to ViewState
private string UploadedFileName
{
get
{
object o = ViewState["UploadedFileName"];
if (o == null)
return string.Empty;
return (string) o;
}
set
{
ViewState["UploadedFileName"] = value;
}
}
private string _dataSource;
public string DataSource
{
get { return _dataSource; }
set { _dataSource = value; }
}
public override void DataBind()
{
UploadedFileName = _dataSource;
EnsureChildControls();
...
}
-
... Satelity programů suplující sběrné kanály čehokoliv mohou vystupovat autonomně,
ale VŽDY do budoucna mohou kterémukoliv našemu IS poskytnout svoje data. ...
Text je vyjmut z mailu vysvětlujícího potřebu jednoduché webové aplikace. Chvíli jsem na to koukal a říkal jsem si, že už přece nespím, že je to můj obor a že bych tomu měl rozumět :-)
Ale je to super věta, já bych asi nikdy takovou nestvořil. Chtěl jsem se s vámi o ni podělit.
ernest