My favorites | Sign in
Project Home Downloads Wiki Issues Source
Project Information
Members
Featured
Downloads
Wiki pages

What csharp-servlets is

  • A C# based server technology entirely built on Mono. Uses a servlet-style approach. The goal is to create a new, fully open source, easy to use, Mono supported server.
  • csharp-servlets borrows syntax and ideas from other web servers I've seen and used but with my own little twist.
  • The overall goal is to create a framework that is everything I ever wished Java servlets were. And the obvious starting point was with a language with my favorite features.

What csharp-servlets is not

  • A full implementation of a Java Container or of J2EE in any way (or Django, or Rails, or ...). As much as I like J2EE, Java Servlets, etc, I don't intend or want to recreate it. However, I was heavily influenced by much of the design of Java Servlets.
  • A fully working, complete, bug free framework (yet!). Heck I don't even know if you can even call it a "framework" at this point.

Features

  • Fully abstracted Request and Response objects
  • Request scoped variables
  • Session scoped variables (persistent)
  • Built using Mono. (Some earlier builds were tested with Visual Studio and .Net and worked)
  • Request forwards
  • Response redirects

Example Code

You can download this example from the featured downloads section. It's bundled with the compiled server so you can easily run it and test it out.

A very basic blog example using Dictionaries as a 'database' (makes for a better 'drop-in' solution that way):

HomemadeBlog.cs

namespace HomemadeBlog {
	[Servlet]
	public class BlogServlet {
		static int postCount = 0;
		static int commentCount = 0;
		
		static Dictionary<int, Article> articles = new Dictionary<int, Article>();
		static Dictionary<int, Comment> comments = new Dictionary<int, Comment>();
		
		[GetMethod("/")]
		[GetMethod("/index")]
		public void Index(IRequest request, IResponse response) {
			request.Attributes["articles"] = articles.Values.AsEnumerable();
			request.RequestDispatcher.Forward("/index.milk");
		}
		
		[PostMethod("/article")]
		public void AddArticle(IRequest request, IResponse response) {
			string title = request.Body.Value["title"];
			string body = request.Body.Value["body"];
			
			Article article = new Article(postCount, title, body, DateTime.UtcNow);
			articles[postCount] = article;
			response.Redirect("/article/"+postCount.ToString());
			postCount++;
		}
		
		[GetMethod("/article/$articleId$")]
		public void GetArticle(IRequest request, IResponse response, string articleId) {
			int aId = int.Parse(articleId);
			Article article = articles[aId];
			request.Attributes["article"] = article;
			request.Attributes["comments"] = article.Comments;
			request.RequestDispatcher.Forward("/article.milk");
		}
		
		[PostMethod("/article/$articleId$/comment")]
		public void AddComment(IRequest request, IResponse response, string articleId) {
			int aId = int.Parse(articleId);
			string body = request.Body.Value["body"];
			
			Comment comment = new Comment(commentCount, body, DateTime.UtcNow);
			articles[aId].AddComment(comment);
			comments[commentCount] = comment;
			commentCount++;
			
			response.Redirect("/article/"+aId.ToString());
		}
	}
}

csharp-servlets has basic support for markup files called milk files (for no particular reason). Milk files are very similar in syntax to JSPs. The above blog uses only two views:

index.milk

<%@ MILK %>
<%@ using namespace="HomemadeBlog" %>
<html>
	<head>
		<title>Index - Joel's Blog</title>
	</head>
	<body>
		<% foreach(Article article in (IEnumerable<Article>)request.Attributes["articles"]) { %>
			<div>
				<a href="/article/<%= article.Id %>"><%= article.Title %></a>
				<span>Created on: <%= article.TimeCreated %></span>
			</div>
		<% } %>
		<hr/>
		<form method="post" action="/article">
			<input type="text" name="title"/><br/>
			<textarea name="body" rows="20" cols="30"></textarea><br/>
			<input type="submit" value="Post" /><br/>
		</form>
	</body>
</html>

article.milk

<%@ MILK %>
<%@ using namespace="HomemadeBlog" %>
<%
	Article article = request.Attributes["article"] as Article;
%>

<html>
	<head>
		<title><%= article.Title %> - Joel's Blog</title>
	</head>
	<body>
		<h1><%= article.Title %></h1>
		<p><%= article.Body %></p>
		<span><%= article.TimeCreated %></span>
		<hr/>
		<h2>Comments</h2>
		<% foreach(Comment comment in (IEnumerable<Comment>)request.Attributes["comments"]) { %>
			<div>
				<p><%= comment.Body %></p>
				<span>Created on: <%= comment.TimeCreated %></span>
				<div>--</div>
			</div>
		<% } %>
		
		<form method="post" action="/article/<%= article.Id %>/comment">
			<textarea name="body" rows="15" cols="25"></textarea><br/>
			<input type="submit" value="Comment" /><br/>
		</form>
	</body>
</html>

Milk files are compiled to .net assemblies at runtime.

Powered by Google Project Hosting