- Open Resource editor
To do that right click on your project and choose "Properties" option. When the properties screen opens choose "Resources" tab: If you haven't defined any resources before you'll be asked if you'd like to create a default Resource file for that project: "This project does not contain a default resource file. Click here to create one". - Creat resource file
When you confirm to do that the default resource file is created (see file marked on picture below) you can now choose to add a new file as resource: - Add file as resource
After you select the file it's available as resource. In my sample project I selected text file "test.txt". It also appeared in solution explorer (marked with red): - Access file content from code
After you save all the changes you made to resources you can access the file content from your code simply by using its name:using SampleProject.Properties;
...
string fileContent = Resources.test;
You have to admit it's much easier then manually opening and reading from files.
Thursday, 4 November 2010
Visual Studio: Adding and using resource files
Monday, 18 October 2010
The report server has encountered a configuration error. (rsServerConfigurationError)
- Open Configuration Manager
Go to: Microsoft Sql Server 2008 > Configuration Tools > Reporting Services Configuration Manager - Configure Web Service Url
I used the default values suggested by configuration manager. To do that simply choose 'Apply'. Result: - Configure Report Manager Url
Again, I used the default values:
After doing that I tried to to access: http://localhost/Reports
In my case I got displayed the following error:
The report server has encountered a configuration error. (rsServerConfigurationError).
To get rid of this I needed to perform to 2 extra steps:
- Define database to use
I created a new database for Reporting Services using the same configuration manager: - Set folder security
Now check which account is used by reporting services:
...and grant access for that user to the Reporting Services installation folder. In my case it is:
C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services
Wednesday, 6 October 2010
WCF Endpoint ABC
- Where?
- What?
- How?
- A - Address (Where?)
This is the network address of your service saying where to find it. WCF support several address types/protocols. E.g. if you are creating a regular SOAP web service you would use an HTTP or HTTPS address. The type of the address depends directly on the binding type (see next definition). - B - Binding (How?)
Binding defines how clients can communicate with our service. It specifies the transport protocol that should be used (HTTP, TCP, ...), web service protocol, encoding, security settins etc. - C - Contract (What?)
Contract defines what functionality your service exposes. This is simply the interface that your WCF service implements.
Simple as ABC, isn't it? :)
Friday, 24 September 2010
Javascript parseInt() gotcha
'00' => 0
'01' => 1
'02' => 2
'03' => 3
'04' => 4
'05' => 5
'06' => 6
'07' => 7
'08' => 8
'09' => 9
I used parseInt() function to achieve that. I was surprised to discover that the variables values where a bit different than I expected:
var i = parseInt('00'); // i = 0
i = parseInt('01'); // i = 1
i = parseInt('02'); // i = 2
i = parseInt('03'); // i = 3
i = parseInt('04'); // i = 4
i = parseInt('05'); // i = 5
i = parseInt('06'); // i = 6
i = parseInt('07'); // i = 7
i = parseInt('08'); // i = 0
i = parseInt('09'); // i = 0
Solution
As you can see parseInt('08') and parseInt('09') returned 0. This is because this function treats strings beginning with '0' as octal numbers and strings beginning with '0x' as hexadecimal numbers. To fix that you can provide the radix to use as a second parameter (optional):
var i = parseInt('00', 10); // i = 0
i = parseInt('01', 10); // i = 1
i = parseInt('02', 10); // i = 2
i = parseInt('03', 10); // i = 3
i = parseInt('04', 10); // i = 4
i = parseInt('05', 10); // i = 5
i = parseInt('06', 10); // i = 6
i = parseInt('07', 10); // i = 7
i = parseInt('08', 10); // i = 8
i = parseInt('09', 10); // i = 9
Monday, 30 August 2010
Multilingual database design approaches
Additional columns
This is the simplest one, it's basically about creating an additional column for each text that needs to be translated e.g.CREATE TABLE app_product (
Id Int IDENTITY NOT NULL,
Description_en Text,
Description_pl Text,
PRIMARY KEY (Id)
);
Advantages:
+ simplicity
+ easy querying (no joins required)
Disadvantages:
- adding new language support requires schema changes for each table with multilingual content
- if not all translations are required (e.g. at some places default language should always be used) it may cause redundant data or empty db fields.
- hard to maintain- Single translations table
Approach with single translation table seems to be the cleanest one from database structure perspective. You store all texts that need to be translated in a single translation table:CREATE TABLE ref_language (
Code Char(2)NOT NULL,
Name Varchar(20) NOT NULL,
PRIMARY KEY (Code)
);
CREATE TABLE app_translation (
Id Int IDENTITY NOT NULL,
PRIMARY KEY (Id)
);
CREATE TABLE app_translation_entry (
TranslationId Int NOT NULL,
LanguageCode Char(2) NOT NULL,
Text Text NOT NULL,
FOREIGN KEY (TranslationId) REFERENCES app_translation(Id),
FOREIGN KEY (LanguageCode) REFERENCES ref_language(Code)
);
CREATE TABLE app_product (
Id Int IDENTITY NOT NULL,
Description Int NOT NULL,
PRIMARY KEY (Id),
FOREIGN KEY (Description) REFERENCES app_translation(Id)
);
Advantages:
+ adding new languages doesn't require schema changes
+ seems like clean, relational approach
+ all translations in one place (some may say it's a disadvantage because less readable/maintainable)
Disadvantages:
- complex querying (multiple joins required to retrieve correct product description)
- overcomplicated - Additional translation table for each table with multilingual content
For each table that stores information that may need to be translated an additional table is created. The original table stores only language insensitive data and the new one all translated info:CREATE TABLE ref_language (
Code Char(2)NOT NULL,
Name Varchar(20) NOT NULL,
PRIMARY KEY (Code)
);
CREATE TABLE app_product (
Id Int IDENTITY NOT NULL,
PRIMARY KEY (Id)
);
CREATE TABLE app_product_translation (
ProductId Int NOT NULL,
LanguageCode Char(2) NOT NULL,
Description Text NOT NULL,
FOREIGN KEY (ProductId) REFERENCES app_product(Id),
FOREIGN KEY (LanguageCode) REFERENCES ref_language(Code)
);
Advantages:
+ adding new languages doesn't require schema changes
+ relatively simple querying (1 join required)
Disadvantages:
- may double the amount of tables
The 3 examples presented above give us an idea how different approaches may be used here. These are of course not all possible options, just the most popular ones. You can always modify them e.g. by introducing some additional views that would save you writing complex joins direct from your code.
The solution you choose depends mostly on your project requirements. If you need simplicity and are sure that the number of supported languages is small and fixed you could go with option 1. If you require bit more flexibility and can afford a simple join when querying for multilingual data option 3 would be a possible solution.
Friday, 27 August 2010
Using custom fonts on your website
In this case if the first font is not installed on client's machine the next one will be used.
.someclass {
font-family: Arial, Verdana;
}
Custom fonts
In some cases you may need to use a custom font that is most likely not installed on most of the client machines. Common example for such situation is when you receive a design from your client who insists you implement their website exactly like it was designed.
One of possible solutions would be using graphics for all page elements that were designed to use custom fonts. Disadvantages of this approach are:
- This is not SEO friendly
- Not suitable for dynamic text
Please not that browser needs to download the font first so it may slow down initial loading of your page. For IE you'll need the .eot version of the font. You can convert your ttf font into eot using this free converter. Each browser should only download one of the files.
@font-face {
font-family: custom_font;
/* for IE */
src: url(fonts/custom_font.eot);
/* non-IE */
src: local("Unique font name"), url(fonts/custom_font.ttf) format("truetype");
}
/* now you can use your custom font like any other */
.someclass {
font-family: custom_font;
}
If possible always try to use web safe fonts which can also produce great results.
Tuesday, 29 June 2010
PowerShell in Windows 7
Recently I changed my machine and system (XP -> W7) and discovered that the scripts don't work anymore. The reason for that was the insufficient execution policy set in PowerShell by default. I changed it to the one previously used on my old machine and... no effect!
I started to think that the problem may not be caused by execution policy (although the error message was quite obvious) but then I found out there are actually 2 PowerShell versions installed: 64 a 32 bit. You can find them under "Windows PowerShell" folder in Accessories:
Changing execution policy for both versions solved my problem.
Friday, 25 June 2010
Mysql foreign keys don't work
Solution:
It came out that the problem was caused by the default ENGINE used by my MySql database i.e. MyISAM. Foreign key constraint is not implemented in its current version (read more here). To enable the FOREIGN KEY constraint I decided to use InnoDb ENGINE. I forced that by adding engine selection for each table:
CREATE TABLE IF NOT EXISTS `my_table` (
`id` INT NOT NULL ,
`other_table_id` INT NOT NULL ,
PRIMARY KEY (`id`) ,
FOREIGN KEY (`other_table_id` ) REFERENCES `other_table` (`id`)
) ENGINE = InnoDB;
Monday, 12 April 2010
Is tag a branch?
Recently I was very surprised when I was asked to commit my changes into a TAG.
So I asked:
- You mean branch?
- No, Tag!
- ???
I always thought that a tag is just a 'marker' that marks a point in a branch and it doesn't branch the code. So what does committing to a tag actually mean? How to commit something to a tag without affecting the branch it was created for?
The answer for those questions can be found in TortoiseSVN documentation explaining what tags and branches actually are from technical perspective:
Tags are typically used to create a static snapshot of the project at a particular stage. As such they not normally used for development - that's what branches are for, which is the reason we recommended the /trunk /branches /tags repository structure in the first place. Working on a tag revision is not a good idea, but because your local files are not write protected there is nothing to stop you doing this by mistake. However, if you try to commit to a path in the repository which contains /tags/, TortoiseSVN will warn you.
Although Tortoise actually allows you to commit into a tag you should never do that! It actually branches the code and makes the code repository messy! After such operations there are actual branches under tags structure. I can't imagine what merging such branched tag with its original branch would actually mean?
But what if you need to add changes to the tagged release (a.g. patches)? Here is the proper way to solve such problem:
It may be that you need to make further changes to a release which you have already tagged. The correct way to handle this is to create a new branch from the tag first and commit the branch. Do your Changes on this branch and then create a new tag from this new branch, e.g. Version_1.0.1.
Now when I understand the problem better I'm just wondering why TortoiseSVN (other tools probably too) allows such operation (with warning). Are there any situations where it would be necessary?
Thursday, 1 April 2010
Line numbers in stack trace
Solution:
To ensure that line numbers are included in stack trace you need to deploy .pdb files together with your dll-s. Program database (pdb) files are created when you build your app in Debug mode. You need to copy them to the same directory where dll-s are placed.
Tip: GAC dll-s are stored under folder structure described here
Monday, 15 February 2010
Microsoft Second Shot returns
The offer is available from January 13, 2010 and it ends on June 30, 2010 so it may be an additional motivation for you.
More details here: http://www.prometric.com/microsoft/ss_mcp.htm
Tuesday, 12 January 2010
CSS trick for IE
.myTestClass{
width: 5px; /* value used by all other browsers */
#width: 7px; /* value used by IE */
_width: 9px; /* value used by IE6 and older */
}
I don't think it's a part of the CSS official specification but it works ;)
Subscribe to:
Posts (Atom)