Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

Friday, 3 February 2012

Ext.Net 1.2 and Mono 2.10 on Ubuntu Oneiric

We have upgraded all the code of OpenPetra to .net 4.0.
We also upgraded to Ext.Net 1.2.

There were two bugs in Mono 2.10, which were show-stoppers:
http://bugzilla.xamarin.com/show_bug.cgi?id=2505 was a problem with the mono compiler, in Mono 2.10.x
This was fixed in mono master.

So I tried to build mono from master, but then I had problems with fastcgi, while xsp4 was serving the content correctly:
http://bugzilla.xamarin.com/show_bug.cgi?id=2876
This was also fixed in mono master.

Below is a link to a tar.gz file, that contains the build of Mono, with mod_mono and xsp, at the beginning of February 2012.

I wanted to use lighttpd and fastcgi with Mono and Ext.Net, but that did not work.
The error that I got was similar as to described here, but without a solution that works for me:
http://forums.ext.net/showthread.php?14040-All-DirectEvents-Is-Error
It works fine with xsp4.

I then tried with mod_mono and apache2:
I came across this issue http://forums.ext.net/showthread.php?12348-404-Not-Found-for-a-few-resources-requests, that the resources cannot be loaded. The solution from that thread also helped me:
Add CleanResourceUrl = "false" to your .aspx file:
<ext:ResourceManager  runat="server" CleanResourceUrl="false" />

So here are my configuration steps for Ext.Net with Mono and Apache2:

This works with Ubuntu Oneiric 64 bit (11.04). But it might work on other Ubuntu/Debian version as well. I have also used it on CentOS.

apt-get install apache2
cd /opt
wget http://download.pokorra.de/mono/ubuntu/mono.tar.gz
for 32 bit: wget http://download.pokorra.de/mono/ubuntu32/mono.tar.gz
tar xzf mono.tar.gz
cd /usr/lib/apache2/modules/
wget http://download.pokorra.de/mono/ubuntu/mod_mono.so
for 32 bit: wget http://download.pokorra.de/mono/ubuntu32/mod_mono.so
cd /etc/apache2/mods-enabled
wget http://download.pokorra.de/mono/ubuntu/mod_mono.conf
# note that mod_mono.conf contains this line:
# MonoServerPath /opt/mono-2.10-git/bin/mod-mono-server4
vi /etc/init.d/apache2
# search for LANG, and replace with this line:
ENV="env -i LANG=en_GB PATH=/opt/mono-2.10-git/bin:/usr/local/bin:/usr/bin:/bin"
Mono will create a directory /var/www/.mono which should not be public.
In your apache site configuration file, add just before  <Directory /var/www/>
<directorymatch \.mono>

           Deny from all
</directorymatch>
cd /var/www
wget http://download.pokorra.de/mono/ubuntu/extnet-sample-mono.tar.gz
tar xzf extnet-sample-mono.tar.gz
chown -R www-data:www-data /var/www
/etc/init.d/apache2 restart

See the result here:
http://demo.openpetra.org/DemoDesktop

This is the demo for the Desktop from Ext.Net 1.2, with a slight modification in Default.aspx and Desktop.aspx for the ResourceManager as described above.

Tuesday, 15 March 2011

Ext.Net and Mono

I like ext.js/Sencha for having a rich client in the browser.

On the other hand, we are using Mono for running our .Net server.

ext.net is a good library that helps you to easily write web applications, based on your .net libraries.

For OpenPetra, I have created an online application system, and the backend for the registration office is written with ext.net.

Here are some problems I came across, and how I solved them:

First, I had to recompile the ext.net dlls and also the Newtonsoft.Json.Net20.dll.

The Newtonsoft.Json.Net20.dll has been compiled with the latest compiler built from Mono 2.8 trunk. This was necessary so that no Microsoft dlls were linked in.
The ext.net dll was built against the Mono compiled Newtonsoft.Json.Net20.dll on Windows with SharpDevelop. The mono compiler crashed on Linux when trying to build the ext.net solution.
The resulting files are available from the online source repository of OpenPetra, eg. http://bazaar.launchpad.net/~openpetracore/openpetraorg/trunkhosted/files/head:/csharp/ThirdParty/ext.net/

I was not able to get Ext.Net to run with the latest Mono 2.8, but it is working fine with 2.6.7.
I had to build it from the sources.
Some links related to the problems I had with Mono 2.8 and Ext.Net:
compile ext.net: There is no implicit reference conversion from `Ext.Net.ComboBox' to `Ext.Net.ComboBoxBase'

Running ext.net on Mono 2.8: get the error: Cannot add a Ext.Net.Parameter to System.String
For the moment, the solution for me was to use Mono 2.6.7.

The examples of ext.net only show the c# code inside the aspx file, but with growing size of the code it would be good to be able to split the code behind code from the UI code.
This is possible, but you need to define all controls in the .cs file, at least those you want to use in your code behind code.
In the aspx file, make sure you have at the top:
<%@ Page Language="C#"
Inherits="Ict.Petra.WebServer.MConference.TPageOnlineApplication"
src="Desktop.aspx.cs" %>
<%@ Register assembly="Ext.Net" namespace="Ext.Net" tagprefix="ext" %>
see the whole file here: OnlineRegistrationBackend/Desktop.aspx

Now I ran into errors like this when Mono was compiling the code on the fly:
Compiler Error Message: CS1644: Feature `anonymous types' cannot be used because it is not part of the C# 2.0 language specification
I found on the Internet this page: http://www.4guysfromrolla.com/articles/121207-1.aspx
linked from http://web.archiveorange.com/archive/v/c2PM7RMRJf7Ti7PP7uVb, where they discuss how to use "extension methods" and "collection initializers" with Mono.

I have added all those settings to my web.config, see the result here:

You can see a running demo here: http://demo.openpetra.org:8009/

Monday, 10 May 2010

CruiseControl.net and Mono

I have set up CruiseControl.net (http://sourceforge.net/projects/ccnet/) on Mono for building our OpenPetra.org project, which is quite a big project.

Here are the steps I followed, and my config files so that people can benefit from it:

Here is some advice how to change the ccnet.exe.config to make it work for Mono: http://markmail.org/message/uyfqysd55u4xqhfs; main things are to change the xsl paths' backslash to forward slash, and to replace ColoredConsoleAppender with ConsoleAppender, and to remove mappings for the ConsoleAppender.

You can see my modified ccnet.exe.config, and also the ccnet.config for OpenPetra here in the online git repository:

http://openpetraorg.git.sourceforge.net/git/gitweb.cgi?p=openpetraorg/openpetraorg;a=tree;f=csharp/ICT/PetraTools/ContinuousIntegration

You will also find a cruisecontrol.sh which I use as a init.d script for starting and stopping my CruiseControl server.

I had to install Mono XSP from the Lenny backports repository, to get Mono 2.x. It was also important to install sendmail, otherwise the EmailProvider would obviously not work (which took me quite a while to notice).
apt-get -t lenny-backports install mono-xsp
apt-get install sendmail sendmail-bin

Then I had a nasty problem with the logging. After a failed build, I had this exception:

[OpenPetraOrg:ERROR] Publisher threw exception: ThoughtWorks.CruiseControl.Core.CruiseControlException: Unable to read the contents of the file: /home/timop/CruiseControl.NET/Server/OpenPetraOrg/Artifacts/nant-results-b2f2a299-05c5-42a6-a311-24df30a59b9a.xml ---> System.NotImplementedException: The requested feature is not implemented.
at ThoughtWorks.CruiseControl.Core.Tasks.FileTaskResult.ReadFileContents () [0x00000]
--- End of inner exception stack trace ---
at ThoughtWorks.CruiseControl.Core.Tasks.FileTaskResult.ReadFileContents () [0x00000]
at ThoughtWorks.CruiseControl.Core.Tasks.FileTaskResult.get_Data () [0x00000]
at ThoughtWorks.CruiseControl.Core.Publishers.XmlIntegrationResultWriter.WriteTaskResults (IIntegrationResult result) [0x00000]
at ThoughtWorks.CruiseControl.Core.Publishers.XmlIntegrationResultWriter.WriteBuildElement (IIntegrationResult result) [0x00000]
at ThoughtWorks.CruiseControl.Core.Publishers.XmlIntegrationResultWriter.Write (IIntegrationResult result) [0x00000]
at ThoughtWorks.CruiseControl.Core.Publishers.XmlLogPublisher.Execute (IIntegrationResult result) [0x00000]
at ThoughtWorks.CruiseControl.Core.Tasks.TaskBase.Run (IIntegrationResult result) [0x00000]
[OpenPetraOrg:ERROR] Unable to build email message: ThoughtWorks.CruiseControl.Core.CruiseControlException: Unable to read the contents of the file: /home/timop/CruiseControl.NET/Server/OpenPetraOrg/Artifacts/nant-results-b2f2a299-05c5-42a6-a311-24df30a59b9a.xml ---> System.NotImplementedException: The requested feature is not implemented.
After some searching, I realised that the log file had become quite big, and in the CruiseControl.net code in FileTaskResult.cs the function ReadFileContents would call MemoryFailPoint, but this class has not been implemented yet in Mono 2.x (http://anonsvn.mono-project.com/viewvc/tags/mono-2-4-2-2/mcs/class/corlib/System.Runtime/MemoryFailPoint.cs).

My solution was to download the sources of Mono, and modify MemoryFailPoint.cs to not throw that NotImplementedException, but just stay quiet. I then copied the resulting file (eg. mono-2.4.2.3/mcs/class/lib/net_2_0/mscorlib.dll) to my server with the CruiseControl.net, to /usr/lib/mono/2.0/mscorlib.dll

Now CruiseControl.net works quite nicely, though I have not played with NUnit yet, and there are more things to explore...

Tuesday, 28 October 2008

DTAUS with C#

I needed to export Lastschriften (instructions for direct debit) for our german office, and after looking for some solutions, I realised that it is not that hard to write it yourself...

Here is the result: http://download.pokorra.de/coding/Dtaus.cs
Please feel free to use the code any way you like.
I read the input data from an XML file, of course this needs to be modified to your specific situation.

A good help was this documentation of the german DTAUS bank file format:
http://www.infodrom.org/projects/dtaus/dtaus.html

Another useful tool was the JDTAUS editor, a java editor that can process and create DTAUS files:
http://www.jdtaus.de/de/
I use this to validate and test the files written with my C# program.

Friday, 29 August 2008

Use the CSParser to process C# files

I wanted to generate code but at the same time parse the target file first to see if any changes have been manually made or with the graphical designer.


I found the following parser for c# code: http://www.codeplex.com/csparser; it seems very active at the moment, and it parsed my test cs file without any problems.



I had some issues first understanding how to look for the current line number and how to know the name of the classes and methods etc. But a look at the sample file cmc.cs helped a lot.

using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using DDW.Collections;
using DDW;
using Microsoft.CSharp;

namespace test
{
class Program
{
private static void PrintErrors(IEnumerable errors)
{
foreach (Parser.Error error in errors)
{
if(error.Token.ID == TokenID.Eof && error.Line == -1)
{
Console.WriteLine(error.Message + "\nFile: " + error.FileName + "\n");
}
else
{
Console.WriteLine(error.Message + " in token " + error.Token.ID
+ "\nline: " + error.Line + ", column: " + error.Column
+ "\nin file: " + error.FileName + "\n");
}
}
}

private static CompilationUnitNode ParseUnit(string fileName, List errors)
{
Console.Write("\nParsing " + fileName);
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs, true);
Lexer l = new Lexer(sr);
TokenCollection toks = l.Lex();

Parser p = null;
CompilationUnitNode cu = null;

p = new Parser(fileName);
cu = p.Parse(toks, l.StringLiterals);

if(p.Errors.Count != 0)
{
Console.WriteLine();
PrintErrors(p.Errors);
errors.AddRange(p.Errors);
return null;
}
return cu;
}

public static void Main(string[] args)
{
string filename = "c:\\myfile.cs";
List errors = new List();
CompilationUnitNode cu = ParseUnit(filename, errors);

StringBuilder sb = new StringBuilder();
cu.ToSource(sb);
Console.WriteLine(sb.ToString());
foreach (NamespaceNode nnode in cu.Namespaces)
{
foreach (ClassNode cnode in nnode.Classes)
{
Console.WriteLine("class name: " + cnode.Name.Identifier.ToString());
foreach (FieldNode fnode in cnode.Fields)
{
foreach (QualifiedIdentifierExpression qexpr in fnode.Names)
{
sb = new StringBuilder();
qexpr.Expressions.ToSource(sb);
Console.WriteLine("Field: " + sb.ToString());
}
}
foreach (MethodNode mnode in cnode.Methods)
{
sb = new StringBuilder();
mnode.Names.ToSource(sb);
if (sb.ToString() == "InitializeComponent")
{
Console.WriteLine("Line number of InitializeComponent starting: " +
mnode.RelatedToken.Line.ToString());
int firstLine = -1;
int lastLine = -1;
foreach (StatementNode snode in mnode.StatementBlock.Statements)
{
if (firstLine == -1)
{
firstLine = snode.RelatedToken.Line;
}
lastLine = snode.RelatedToken.Line;
sb = new StringBuilder();
snode.ToSource(sb);
string line = sb.ToString();
Console.Write(snode.RelatedToken.Line.ToString() + ": " + line);

}
}
}

}
}

Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}