Tuesday, October 29, 2013

Kentico: Running API Examples from within CMS Desk

If API Examples is installed, the examples can be run from Support –> API examples.

Many of the examples have been hard coded with culture “en-us”, they will be most likely failed if the site is using a culture different from “en-us”.

The example code is like below, it fails on the red line:

#region "API examples - Creating documents"

   /// <summary>
   /// Creates the initial document strucutre used for the example. Called when the "Create document structure" button is pressed.
   /// </summary>
   private bool CreateDocumentStructure()
   {
       // Add a new culture to the current site
       CultureInfo culture = CultureInfoProvider.GetCultureInfo("de-de");
       CultureSiteInfoProvider.AddCultureToSite(culture.CultureID, CMSContext.CurrentSiteID);

       // Create new instance of the Tree provider
       TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);

       // Get parent node
      TreeNode parentNode = tree.SelectSingleNode(CMSContext.CurrentSiteName, "/", "en-us");

       if (parentNode != null)
       {
           // Create the API Example folder
           TreeNode newNode = TreeNode.New("CMS.Folder", tree);

           newNode.DocumentName = "API Example";
           newNode.DocumentCulture = "en-us";

           newNode.Insert(parentNode);

           parentNode = newNode;

           // Create the Source folder - the document to be moved will be stored here
           newNode = TreeNode.New("CMS.Folder", tree);

           newNode.DocumentName = "Source";
           newNode.DocumentCulture = "en-us";

           newNode.Insert(parentNode);

           // Create the Target folder - a document will be moved here
           newNode = TreeNode.New("CMS.Folder", tree);

           newNode.DocumentName = "Target";
           newNode.DocumentCulture = "en-us";

           newNode.Insert(parentNode);

           return true;
       }

       return false;
   }

You can modify the culture to your site’s culture and the example should be able to run on your site.

Tuesday, September 3, 2013

Tips for upgrading Kentico CMS site from v6 to v7

Recently I upgraded one web site written in Kentico CMS v6 to v7 and would like to share my experience.

Preparation

Due to the some API changes in v7, you might need to change your code a lot if your web site is mainly using ASPX template.
To track your changes, it is better if the changes can be recorded down and can be revert any time if it is needed. This is where
source control comes in place. If you have not apply source control to your web site yet, this is the good opportunity to start
using source control.

Here are the suggestions for using SVN as the source control for this upgrading purpose:

  1. create a new repository
  2. create trunk and branches in the repository
  3. check out the trunk to a local folder
  4. copy all files and folders from your web site folder into trunk folder
  5. add all files and folders and commit to SVN repository
  6. create a branch into branch folder based on the trunk

The idea behind this is to record all changes to the branch during the upgrading. Depends on the complexity of the web site,
the changes you will make to the source code might take few days/weeks, so that I do not recommend that upgrade the
production directly, instead, you should make a copy to your development machine and upgrade this copy first. All the changes
made to the local instance will be committed into the new created branch. When the upgrade is done and has been test,
production then can be upgraded. The upgrade to the production will be as simple as following steps:

  1. copy files from the production server into trunk.
  2. commit all the modifications if there is any.
  3. merge changes from the branch
  4. copy file back to production from the trunk

Upgrade

The database upgrade script might contains changes to the views. But I have found that in Micorsoft SQL 2008 R2, after execution
of the upgrade script, the views might not be synchronized properly. In my case the error was some data conversion failures.
The root cause seemed to be the changes on base views had not propagated properly to other views which were base on the base
views.

If you need to perform the upgrade manually, it requires to delete a lot files and folders before updating files to new version’s.
The instruction has listed the files and folders, but it is very fussy if you go through the list and delete file/folder one by one.
A easier way is to copy the content of the list to a text file, then add “del “ to the beginning of the full name of the file and add
”del /s/q “ to the beginning of the full name of the path, save the text file as a .BAT file, this batch file can delete files and folders
in one go and save you a lot of time.

There is an undocumented change you need to take care if your page uses CMSForm for editing a document in the same way as
the Form tab in the CMS Desk content page, you need to assign DocumentManager.LocalMessagesPlaceHolder to the the CMSForm
element’s MessagesPlaceHolderto property, otherwise, there will be an exception when the form is submitted.

Tuesday, August 20, 2013

My Weapons (Tool set)

  1. 7-Zip.
  2. Adobe Reader
  3. EditPad and Notepad++: Advanced text editor.
  4. Fiddler Web Debugger: http/https traffic inspector.
  5. firstobject XML Editor: Formatting XML and browsing nodes in a tree view.
  6. Google Chrome: HTML/Javascript/CSS inspector/debugger.
  7. IDE:
    1. Delphi:
      components:
      1. CnPack IDE Wizards
      2. madshi’s madCollection
    2. Microsoft Visual Studio
  8. Kentico CMS.
  9. Link Shell Extension: Managing file’s hard link.
  10. Microsoft Network Monitor.
  11. Nullsoft Install System
  12. Paint.Net: Graphic tool.
  13. Pdf995.
  14. soapUI.
  15. Synergy: one set of mouse and keyboard for multiple PC.
  16. TeamViewer
  17. VisualSVN Server, TortoiseSVN and WinMerge
  18. WinDirStat: shows disk usage in colour blocks
  19. Windows Live Writer: Writing blogs.
    Plugins:
    1. Live Writer Code Prettify Plugin

Sunday, July 28, 2013

An easy to use tool for query Oracle database

LINQPad can be used for query Oracle database as well. All you need to do is download IQ Driver for Oracle.
The steps are:
1. Click “Add connection” in the connection tree.
2. Click “View more drivers …” in the “Choose Data Context” dialog
3. Click “Download & Enable Driver” under the “IQ Driver – for MySQL, SQLite, Oracle” section.

In my case, parameters in Advanced tab of IQ Connection need to be populated to be able to connect to Oracle database directly.

Wednesday, July 10, 2013

A way to validate your email address

http://verify-email.org/index.php?option=com_emailverifier&check=bochen.lin@global-health.com&view=emailverifier&layout=verify&format=raw&2f8b80496c78ca0e01ff56a06da6bc8f=1

×

bochen.lin@global-health.com - Result: Ok
MX record about global-health.com exists.
Connection succeeded to mx.global-health.com SMTP.
220 mailhub.ws.com.au ESMTP

> HELO verify-email.org
250 mailhub.ws.com.au

> MAIL FROM: <check@verify-email.org>
=250 ok

> RCPT TO: <bochen.lin@global-health.com>
=250 ok

Wednesday, June 19, 2013

Upgrade Orchard 1.3 site from MVC3 (VS2010) to MVC4 (VS2012)

  1. Uses NuGet Package to install MVC4 into the project
  2. Manually change Rozer and MVC assembly configuration in the Web.Config files from old version to version 2 and 4. Add to Web.Config in each View folder of the project.
    1. <configuration>

      <system.web.webPages.razor>
              <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
              <pages pageBaseType="Orchard.Mvc.ViewEngines.Razor.WebViewPage">
                  <namespaces>
                      <add namespace="System.Web.Mvc" />
                      <add namespace="System.Web.Mvc.Ajax" />
                      <add namespace="System.Web.Mvc.Html" />
                      <add namespace="System.Web.Routing" />
                      <add namespace="System.Linq"/>
                      <add namespace="System.Collections.Generic"/>
                      <add namespace="Orchard.Mvc.Html"/>
                  </namespaces>
              </pages>
          </system.web.webPages.razor>

      </configuration>

  3. Remove “@” if it is in and “@{}” block.
  4. Replace “jQueryUtils_TimePicker”

Sunday, June 16, 2013

Javascript scope in HTML page which contains iframe

If a HTML page contains a “iframe”, what is the relationship between the javascripts in the two HTML pages in terms of function/variable scope?

Tuesday, March 26, 2013

Failed Web Service Call Due to Big Time Difference Between Servers

The other day, a working web site was suddenly down. Its registration and login related functionalities were all failed.
The error was caught but the error message was kind of “Unknown”. Dug to the code, the caught exception “e” in below code is a null:
   1:  try
   2:  {                   
   3:      return client.Proxy.IdentityTypeList();
   4:   }
   5:  catch (Exception e)
   6:  {
   7:      this.HandleException(e);
   8:   }

what line 3 does is calling a web service, but it was failed and throwing an null exception. As there was no message text at all, it seemed it was getting into a dead end in for trouble shooting.

It finally turned out it was caused by there was a big time different between the tow machines (the calling web server and the web service server). The difference was more than 5 minutes.

What I have done to find out the cause was I wrote a test program in C#. The test program was a WinForm application. The function of the application was to call the same web service as above code did.

When the application was deployed to the web service, it failed to call the web service and threw an exception. This time the exception did have a error message text complaining that the web service returned in future time and the time in the future was longer than 5 minutes.

What is still mystery to me from the above case is that the same code in Web application and WinForm application throws different exception. The exception threw in Web application does not make sense at all which make it very difficult to do the trouble shooting.

Tuesday, March 12, 2013

XML Data Binding in Delphi 2007 (2)

In my previous blog [XML Data Binding in Delphi 2007 (1)], I have described there were issues when using XML Data Binding facility in Delphi 2007.

We are going to solve name space issue in this blog.

Let’s have a look at the schemas we are going to map.

Book.xsd:

  1: <?xml version="1.0" encoding="utf-8"?>
  2: <xs:schema targetNamespace="http://www.bochenlin.com/book"
  3:     elementFormDefault="qualified"
  4:     xmlns="http://tempuri.org/XMLSchema.xsd"
  5:     xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
  6:     xmlns:xs="http://www.w3.org/2001/XMLSchema"
  7: 	xmlns:a="http://www.bochenlin.com/author"
  8: >
  9: 	<xs:import namespace ="http://www.bochenlin.com/author"
 10: 			   schemaLocation ="author.xsd"></xs:import>
 11: 	<xs:element name="book">
 12: 		<xs:complexType>
 13: 			<xs:sequence>
 14: 				<xs:element name ="title" type="xs:string" ></xs:element>
 15: 				<xs:element name ="subject" type ="xs:string"></xs:element>
 16: 				<xs:element ref ="a:author" ></xs:element>
 17: 			</xs:sequence>
 18: 		</xs:complexType>
 19: 	</xs:element> 		
 20: </xs:schema>
 21: 

Author.xsd:


 



  1: <?xml version="1.0" encoding="utf-8"?>
  2: <xs:schema targetNamespace="http://www.bochenlin.com/author"
  3:     elementFormDefault="qualified"
  4:     xmlns="http://tempuri.org/XMLSchema.xsd"
  5:     xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
  6:     xmlns:xs="http://www.w3.org/2001/XMLSchema"
  7: >
  8: 	<xs:element name ="author">
  9: 		<xs:complexType>
 10: 			<xs:sequence >
 11: 				<xs:element name ="title" type ="xs:string"></xs:element>
 12: 				<xs:element name ="firstName" type ="xs:string"></xs:element>
 13: 				<xs:element name ="lastName" type ="xs:string"></xs:element>
 14: 			</xs:sequence>
 15: 		</xs:complexType>
 16: 	</xs:element>
 17: </xs:schema>
 18: 

 

By using the XML Data Binding Wizard in XE, we can get following code:

  1: unit book;
  2: 
  3: interface
  4: 
  5: uses xmldom, XMLDoc, XMLIntf;
  6: 
  7: type
  8: 
  9: { Forward Decls }
 10: 
 11:   IXMLBook = interface;
 12: 
 13: { IXMLBook }
 14: 
 15:   IXMLBook = interface(IXMLNode)
 16:     ['{C013C828-0F4C-4537-ACD3-B7C550D3B813}']
 17:     { Property Accessors }
 18:     function Get_Title: WideString;
 19:     function Get_Subject: WideString;
 20:     function Get_Author: WideString;
 21:     procedure Set_Title(Value: WideString);
 22:     procedure Set_Subject(Value: WideString);
 23:     procedure Set_Author(Value: WideString);
 24:     { Methods & Properties }
 25:     property Title: WideString read Get_Title write Set_Title;
 26:     property Subject: WideString read Get_Subject write Set_Subject;
 27:     property Author: WideString read Get_Author write Set_Author;
 28:   end;
 29: 
 30: { Forward Decls }
 31: 
 32:   TXMLBook = class;
 33: 
 34: { TXMLBook }
 35: 
 36:   TXMLBook = class(TXMLNode, IXMLBook)
 37:   protected
 38:     { IXMLBook }
 39:     function Get_Title: WideString;
 40:     function Get_Subject: WideString;
 41:     function Get_Author: WideString;
 42:     procedure Set_Title(Value: WideString);
 43:     procedure Set_Subject(Value: WideString);
 44:     procedure Set_Author(Value: WideString);
 45:   end;
 46: 
 47: { Global Functions }
 48: 
 49: function Getbook(Doc: IXMLDocument): IXMLBook;
 50: function Loadbook(const FileName: string): IXMLBook;
 51: function Newbook: IXMLBook;
 52: 
 53: const
 54:   TargetNamespace = 'http://www.bochenlin.com/book';
 55: 
 56: implementation
 57: 
 58: { Global Functions }
 59: 
 60: function Getbook(Doc: IXMLDocument): IXMLBook;
 61: begin
 62:   Result := Doc.GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
 63: end;
 64: 
 65: function Loadbook(const FileName: string): IXMLBook;
 66: begin
 67:   Result := LoadXMLDocument(FileName).GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
 68: end;
 69: 
 70: function Newbook: IXMLBook;
 71: begin
 72:   Result := NewXMLDocument.GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
 73: end;
 74: 
 75: { TXMLBook }
 76: 
 77: function TXMLBook.Get_Title: WideString;
 78: begin
 79:   Result := ChildNodes['title'].Text;
 80: end;
 81: 
 82: procedure TXMLBook.Set_Title(Value: WideString);
 83: begin
 84:   ChildNodes['title'].NodeValue := Value;
 85: end;
 86: 
 87: function TXMLBook.Get_Subject: WideString;
 88: begin
 89:   Result := ChildNodes['subject'].Text;
 90: end;
 91: 
 92: procedure TXMLBook.Set_Subject(Value: WideString);
 93: begin
 94:   ChildNodes['subject'].NodeValue := Value;
 95: end;
 96: 
 97: function TXMLBook.Get_Author: WideString;
 98: begin
 99:   Result := ChildNodes['a:author'].Text;
100: end;
101: 
102: procedure TXMLBook.Set_Author(Value: WideString);
103: begin
104:   ChildNodes['a:author'].NodeValue := Value;
105: end;
106: 
107: end.

In above Delphi code, there are two problems. First it does not generate correct code for element “author”. In line 27, type of property is WideString instead of a class type. Secondly, the generated Delphi code only specify the target name space http://www.bochenlin.com/book , no other name space http://www.bochenlin.com/author  is specified anywhere else, in stead, it uses fixed tag name “a:author” to map the element “author” in the name space http://www.bochenlin.com/author.  Even “author” is a simple type, this is only fine for XML instance which uses “a” as the prefix for name space http://www.bochenlin.com/author. If the final application will only deal with the XML coming from one source, it probably will be OK. It definitely has problem if the XML instances are coming from different sources in which they might have choose different prefixes for the same name space. Besides, the XML instance generated by using above code will be invalid as it will be missing the name space http://www.bochenlin.com/author for the element “author”. To solve these problems, schema “author” needs to have a small tweak.



Tweaked Author.xsd


  1: <?xml version="1.0" encoding="utf-8"?>
  2: <xs:schema targetNamespace="http://www.bochenlin.com/author"
  3:     elementFormDefault="qualified"
  4:     xmlns="http://tempuri.org/XMLSchema.xsd"
  5:     xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
  6:     xmlns:xs="http://www.w3.org/2001/XMLSchema"
  7:     xmlns:a="http://www.bochenlin.com/author"		   
  8: >
  9: 	<xs:element name ="author">
 10: 		<xs:complexType>
 11: 			<xs:sequence >
 12: 				<xs:element name ="title" type ="xs:string"></xs:element>
 13: 				<xs:element name ="firstName" type ="xs:string"></xs:element>
 14: 				<xs:element name ="lastName" type ="xs:string"></xs:element>
 15: 			</xs:sequence>
 16: 		</xs:complexType>
 17: 	</xs:element>
 18: </xs:schema>
 19: 


Line 7 in above tweaked Author.xsd is added for Delphi to generated correct type for element “author”, updated unit book is provided below:

  1: unit book;
  2: 
  3: interface
  4: 
  5: uses xmldom, XMLDoc, XMLIntf;
  6: 
  7: type
  8: 
  9: { Forward Decls }
 10: 
 11:   IXMLBook = interface;
 12:   IXMLAuthor_a = interface;
 13: 
 14: { IXMLBook }
 15: 
 16:   IXMLBook = interface(IXMLNode)
 17:     ['{C873AF71-B66F-4FC1-8273-93F023EFAFBB}']
 18:     { Property Accessors }
 19:     function Get_Title: WideString;
 20:     function Get_Subject: WideString;
 21:     function Get_Author: IXMLAuthor_a;
 22:     procedure Set_Title(Value: WideString);
 23:     procedure Set_Subject(Value: WideString);
 24:     { Methods & Properties }
 25:     property Title: WideString read Get_Title write Set_Title;
 26:     property Subject: WideString read Get_Subject write Set_Subject;
 27:     property Author: IXMLAuthor_a read Get_Author;
 28:   end;
 29: 
 30: { IXMLAuthor_a }
 31: 
 32:   IXMLAuthor_a = interface(IXMLNode)
 33:     ['{23B0F904-2759-4810-9DDA-4E79248128E8}']
 34:     { Property Accessors }
 35:     function Get_Title: WideString;
 36:     function Get_FirstName: WideString;
 37:     function Get_LastName: WideString;
 38:     procedure Set_Title(Value: WideString);
 39:     procedure Set_FirstName(Value: WideString);
 40:     procedure Set_LastName(Value: WideString);
 41:     { Methods & Properties }
 42:     property Title: WideString read Get_Title write Set_Title;
 43:     property FirstName: WideString read Get_FirstName write Set_FirstName;
 44:     property LastName: WideString read Get_LastName write Set_LastName;
 45:   end;
 46: 
 47: { Forward Decls }
 48: 
 49:   TXMLBook = class;
 50:   TXMLAuthor_a = class;
 51: 
 52: { TXMLBook }
 53: 
 54:   TXMLBook = class(TXMLNode, IXMLBook)
 55:   protected
 56:     { IXMLBook }
 57:     function Get_Title: WideString;
 58:     function Get_Subject: WideString;
 59:     function Get_Author: IXMLAuthor_a;
 60:     procedure Set_Title(Value: WideString);
 61:     procedure Set_Subject(Value: WideString);
 62:   public
 63:     procedure AfterConstruction; override;
 64:   end;
 65: 
 66: { TXMLAuthor_a }
 67: 
 68:   TXMLAuthor_a = class(TXMLNode, IXMLAuthor_a)
 69:   protected
 70:     { IXMLAuthor_a }
 71:     function Get_Title: WideString;
 72:     function Get_FirstName: WideString;
 73:     function Get_LastName: WideString;
 74:     procedure Set_Title(Value: WideString);
 75:     procedure Set_FirstName(Value: WideString);
 76:     procedure Set_LastName(Value: WideString);
 77:   end;
 78: 
 79: { Global Functions }
 80: 
 81: function Getbook(Doc: IXMLDocument): IXMLBook;
 82: function Loadbook(const FileName: string): IXMLBook;
 83: function Newbook: IXMLBook;
 84: 
 85: const
 86:   TargetNamespace = 'http://www.bochenlin.com/book';
 87: 
 88: implementation
 89: 
 90: { Global Functions }
 91: 
 92: function Getbook(Doc: IXMLDocument): IXMLBook;
 93: begin
 94:   Result := Doc.GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
 95: end;
 96: 
 97: function Loadbook(const FileName: string): IXMLBook;
 98: begin
 99:   Result := LoadXMLDocument(FileName).GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
100: end;
101: 
102: function Newbook: IXMLBook;
103: begin
104:   Result := NewXMLDocument.GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
105: end;
106: 
107: { TXMLBook }
108: 
109: procedure TXMLBook.AfterConstruction;
110: begin
111:   RegisterChildNode('author', TXMLAuthor_a);
112:   inherited;
113: end;
114: 
115: function TXMLBook.Get_Title: WideString;
116: begin
117:   Result := ChildNodes['title'].Text;
118: end;
119: 
120: procedure TXMLBook.Set_Title(Value: WideString);
121: begin
122:   ChildNodes['title'].NodeValue := Value;
123: end;
124: 
125: function TXMLBook.Get_Subject: WideString;
126: begin
127:   Result := ChildNodes['subject'].Text;
128: end;
129: 
130: procedure TXMLBook.Set_Subject(Value: WideString);
131: begin
132:   ChildNodes['subject'].NodeValue := Value;
133: end;
134: 
135: function TXMLBook.Get_Author: IXMLAuthor_a;
136: begin
137:   Result := ChildNodes['author'] as IXMLAuthor_a;
138: end;
139: 
140: { TXMLAuthor_a }
141: 
142: function TXMLAuthor_a.Get_Title: WideString;
143: begin
144:   Result := ChildNodes['title'].Text;
145: end;
146: 
147: procedure TXMLAuthor_a.Set_Title(Value: WideString);
148: begin
149:   ChildNodes['title'].NodeValue := Value;
150: end;
151: 
152: function TXMLAuthor_a.Get_FirstName: WideString;
153: begin
154:   Result := ChildNodes['firstName'].Text;
155: end;
156: 
157: procedure TXMLAuthor_a.Set_FirstName(Value: WideString);
158: begin
159:   ChildNodes['firstName'].NodeValue := Value;
160: end;
161: 
162: function TXMLAuthor_a.Get_LastName: WideString;
163: begin
164:   Result := ChildNodes['lastName'].Text;
165: end;
166: 
167: procedure TXMLAuthor_a.Set_LastName(Value: WideString);
168: begin
169:   ChildNodes['lastName'].NodeValue := Value;
170: end;
171: 
172: end.

Although above code has generated “author” as a class instead of a WideString, it has not put in its name space http://www.bochenlin.com/author at all. It can be solved by modify line 111 in above code:



111:   RegisterChildNode(‘author’, TXMLAuthor_a, ‘http://www.bochenlin.com/author’);


Yes, it is simple, but it is not perfect yet. If the schemas are as simple as these two in this blog and you are pretty sure they won’t going to be changed, congratulations, you have done the job. But if the number of involved schemas is large and they are likely to change in the near future, it means you are going to regenerate the code again and again so that you are going to loose the modifications and have to redo manually. Don’t know if you have noticed that it does not only loose the changes you have put in but also the GUIDs of the interfaces are changed every time the code is regenerated. So the maintenance of the code becomes very trivial and difficult. I have a better solution in terms of maintaining these auto-generated code. I will introduce Class Helpers to solved this problem in my next blog.

Wednesday, February 6, 2013

XML Data Binding in Delphi 2007 (1)

Problem overview

  1. Wizards. There is a wizard named “XML Data Binding” in Delphi to help you generate a new unit which contains classes and interfaces mapped to a specified XML schema.
    image
    (F1: XML Data Binding in Delphi 2007)
    image
    (F2: XML Data Binding in Delphi XE)
    As the same wizard in Delphi XE is much advanced than the same one in Delphi 2007, I strongly suggest that you should use XE’s to generated the unit and copy it to your Delphi 2007’s project. Basically the unit generated by Delphi 2007 is not useful when the schema is complex (i.e it contains multiple name spaces and multiple imports etc.) The wizard in afterwards is always the one in Delphi XE.
  2. Name spaces. When the schema contains multiple name spaces, although the wizard can still generated the correct structure of the schema, the elements are always in the target name space regardless which name space they are actual in, according to the schema. This is due to the generated code does not use any name space to register a child node at all. This is not DOM’s problem, the MSXMLDOM has the capability to represent multiple name spaces. It is the implementation of the wizard that makes assumption that the XML has all elements in only one name space which is the target name space.
  3. Conformance to the schema. XML Data Binding is a mapping between the XML schema and the Delphi class. They describe the same thing in different format. These two formats have  overlap which covers most of the thing they are describing. But there are some areas that a Delphi class cannot easily achieve as same as the XML schema can. One of these area is the “sequence” restriction to element. XML Data Binding uses properties to represent the child element. Before reading from or writing to the property, the corresponding element has not been created into the DOM yet, it creates it immediately once a reading or writing operation is occurred. In another word, the order of the element is created by the order of the properties reading and writing. And this reading or writing order is totally decided by the programmer according to his/her taste. When it is time to output the final XML document, the order of the element will be the same of their creation order. This order might or might not conform the order specified by the XML schema it is mapping.

I have provided the solution for the first problem, in the next blog, I will provide solutions for the other two problems.

Monday, January 21, 2013

ASP.Net 4.5 + Report Viewer 11.0 having blank report

Recently, I did a ASP.Net application. It is developed by VS 2012. There is a page showing a report by using Report Viewer which comes with VS2012.

 

Everything runs OK in my local machine until the application is deployed onto a remote server. The issue was that the report content is blank. It seems

no error at all until the debug window of the browser is opened. In the Console tab, it complains that “Ajax client-side framework failed to load”.

 

According to Khaled in the below thread (http://stackoverflow.com/questions/3695351/ajax-client-side-framework-failed-to-load-asp-net-4-0),

it is fixed by having below section:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

 

without changes in Global.asax.