Archive for the '.NET 2.0' Category Page 3 of 5

18AugNew Base4 CTP a must have

I’ve been playing with the new base4 ctp that was released yesterday. And I must say that schema website thingy … NICE ;-)

I had trouble working out the joins from time to time but now I just browse my schema and it will show me the syntax if i click on a onetomany relationship which is SO cool.

 

I’d say Alex keep doing what you’re doing :D

16AugMake the object datasource support relations

One of the shortcomings of the object datasource is that it doesn’t support relations properly. It only gives you a single table view of an object if that object is a dataset or datatable.

But what about the relationships etc. Well my first choice was to create specific views etc. But I found it to be a real hassle combined with stored procedures to maintain once the project starts growing a bit.

From the dataset I want a structure that looks like my database. Nothing more nothing less. The same relations and constraints there etc.

How do you accomplish that ? Well it’s going to be a bit of a lengthy post this one because it’s a lot of code.

This is the schema I’ll be talking about :

I have a series of objects in my business layer .. all wrappers around tableadapters. to give you an idea of the complexity of the other classes.

I should also mention that I made the Connection property public on the dataset so that I could open it at will in my business object and save some time opening and closing objects.

I use a base class for all the datasource objects (this is not production code and has now been completely changed to use base4)

This would be the base class :

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Text;

    4 using NBlogr.Dal.NBlogrDataSetTableAdapters;

    5 using NBlogr.Dal;

    6 using System.ComponentModel;

    7 using System.Web;

    8 using System.Data.SqlClient;

    9 using System.Configuration;

   10 using System.Data;

   11 

   12 namespace NBlogr.Bll.Base

   13 {

   14     publicabstractclassDataSourceObject

   15     {

   16         protectedHttpContext _context;

   17         System.Web.Security.MembershipUser _user;

   18 

   19         privateNBlogrDataSet dataSet;

   20         privateSqlConnection connection;

   21         privatebool autoPersist;

   22         privateConnectionState previousState;

   23 

   24         publicbool AutoPersist

   25         {

   26             get { return autoPersist; }

   27             set { autoPersist = value; }

   28         }

   29 

   30 

   31         publicSqlConnection Connection

   32         {

   33             get

   34             {

   35                 if (connection == null)

   36                     this.connection = newSqlConnection(ConfigurationManager.ConnectionStrings["NBlogr.DAL.Properties.Settings.NBlogrConnectionString"].ConnectionString);

   37                 returnthis.connection;

   38             }

   39             set

   40             {

   41                 this.connection = value;

   42             }

   43         }

   44 

   45         publicNBlogrDataSet DataSet

   46         {

   47             get

   48             {

   49                 if (dataSet == null)

   50                     dataSet = newNBlogrDataSet();

   51                 return dataSet;

   52             }

   53             set { dataSet = value; }

   54         }

   55 

   56 

   57         public System.Web.Security.MembershipUser User

   58         {

   59             get {

   60                 if (_user == null)

   61                     _user = System.Web.Security.Membership.GetUser();

   62                 return _user; }

   63             set { _user = value; }

   64         }

   65 

   66         publicGuid UserId

   67         {

   68             get

   69             {

   70                 return (Guid)User.ProviderUserKey;

   71             }           

   72         }

   73 

   74         public DataSourceObject()

   75         {

   76             _context = HttpContext.Current;

   77         }

   78 

   79         protectedvoid OpenConnection(){

   80                 previousState = this.Connection.State;

   81             if (this.Connection.State != ConnectionState.Open)

   82                 Connection.Open();

   83         }

   84 

   85         protectedvoid CloseConnection(bool force)

   86         {

   87             if (previousState == ConnectionState.Closed||force)

   88             {

   89                 Connection.Close();

   90             }

   91         }

   92         protectedvoid CloseConnection()

   93         {

   94             CloseConnection(AutoPersist);

   95         }

   96     }

   97 }


 


And this is the object that gets the complete entries from the database and saves them again.


 

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Text;

    4 using NBlogr.Dal.NBlogrDataSetTableAdapters;

    5 using System.ComponentModel;

    6 using NBlogr.Dal;

    7 using System.Web;

    8 using System.Transactions;

    9 

   10 namespace NBlogr.Bll

   11 {

   12     [DataObject]

   13     publicclassFullEntry : Base.DataSourceObject

   14     {

   15         Entry entryObject;

   16         Comment commentObject;

   17         Category categoryObject;

   18         Attachment attachmentObject;

   19         Blog blogObject;

   20         EntryTableAdapter taEntry = newEntryTableAdapter();

   21         CategoryTableAdapter taCategory = newCategoryTableAdapter();

   22 

   23         EntryCategoryTableAdapter taEntryCategory;

   24         EntryAttachmentTableAdapter taEntryAttachment;

   25 

   26         public FullEntry()

   27         {

   28             entryObject = newEntry(false);

   29             commentObject = newComment(false);

   30             categoryObject = newCategory(false);

   31             attachmentObject = newAttachment(false);

   32             blogObject = newBlog(false);

   33 

   34             taEntryAttachment = newEntryAttachmentTableAdapter();

   35             taEntryCategory = newEntryCategoryTableAdapter();

   36             taEntryCategory.ClearBeforeFill = false;

   37             taEntryAttachment.ClearBeforeFill = false;

   38             entryObject.Connection = commentObject.Connection = entryObject.Connection = categoryObject.Connection =

   39                 taEntryCategory.Connection = taEntryAttachment.Connection = this.Connection;

   40             entryObject.DataSet = commentObject.DataSet = entryObject.DataSet = categoryObject.DataSet = this.DataSet;

   41         }

   42 

   43         publicNBlogrDataSet.EntryRow GetById(Guid Id)

   44         {

   45             OpenConnection();

   46 

   47             attachmentObject.GetByEntry(Id);

   48             commentObject.GetByEntry(Id);

   49             categoryObject.GetByEntry(Id);

   50             taEntryCategory.FillByEntry(DataSet.EntryCategory, Id);

   51             taEntryAttachment.FillByEntry(DataSet.EntryAttachment, Id);

   52 

   53             NBlogrDataSet.EntryRow entry = entryObject.GetRow(Id);

   54 

   55             blogObject.FindById(entry.BlogId);

   56 

   57             CloseConnection(true);

   58 

   59             return entry;

   60         }

   61 

   62         [DataObjectMethod(DataObjectMethodType.Select)]

   63         publicNBlogrDataSet.EntryDataTable GetEntryListByBlogId(Guid BlogId)

   64         {

   65             OpenConnection();

   66 

   67             categoryObject.GetByBlog(BlogId);

   68             taEntryCategory.FillByBlogId(DataSet.EntryCategory, BlogId);

   69             entryObject.GetByBlog(BlogId);

   70 

   71             CloseConnection(true);

   72 

   73             return DataSet.Entry;

   74         }

   75 

   76         [DataObjectMethod(DataObjectMethodType.Select)]

   77         publicNBlogrDataSet.EntryDataTable GetFrontpageEntryList(Guid BlogId)

   78         {

   79             OpenConnection();

   80 

   81             categoryObject.GetByBlog(BlogId);

   82             taEntryCategory.FillByBlogId(DataSet.EntryCategory, BlogId);

   83             entryObject.GetFrontPage(BlogId);

   84 

   85             CloseConnection(true);

   86 

   87             return DataSet.Entry;

   88         }

   89 

   90         [DataObjectMethod(DataObjectMethodType.Select)]

   91         publicNBlogrDataSet.EntryDataTable GetEntryListByMonthYear(decimal Month, decimal Year, Guid BlogId)

   92         {

   93             OpenConnection();

   94 

   95             categoryObject.GetByBlog(BlogId);

   96             taEntryCategory.FillByBlogId(DataSet.EntryCategory, BlogId);

   97             entryObject.GetByMonthYear(BlogId, Month, Year);

   98 

   99             CloseConnection(true);

  100 

  101             return DataSet.Entry;

  102         }

  103 

  104         [DataObjectMethod(DataObjectMethodType.Select)]

  105         publicNBlogrDataSet.EntryDataTable GetEntryListByCategory(string CategoryName, Guid BlogId)

  106         {

  107             OpenConnection();

  108 

  109             Guid categoryId = categoryObject.GetIdByName(CategoryName);

  110             categoryObject.GetById(categoryId);

  111             taEntryCategory.FillByCategory(DataSet.EntryCategory, categoryId);

  112             entryObject.GetByCategory(categoryId,BlogId);

  113 

  114             CloseConnection(true);

  115 

  116             return DataSet.Entry;

  117         }

  118 

  119         publicNBlogrDataSet.BlogRow GetDefaultBlog()

  120         {

  121             return blogObject.GetDefault()[0];

  122         }

  123 

  124 

  125         publicvoid AddComment(Guid Id, string Body, string AuthorName, string AuthorEmail, string AuthorHomepage, string AuthorIpAddress)

  126         {

  127             commentObject.Add(Id, Body, AuthorName, AuthorEmail, AuthorHomepage, AuthorIpAddress);

  128         }

  129 

  130         publicvoid AddFiles(HttpFileCollection files)

  131         {

  132             foreach (HttpPostedFile file in files)

  133             {

  134                 attachmentObject.Save(file);

  135             }

  136         }

  137 

  138         publicGuid AddEntry(Guid BlogId, string Title, string Body, bool IsPublic, bool Syndicated, bool ShowOnFrontPage, bool AllowComments, DateTime? CreateDate, List<Guid> Categories)

  139         {

  140             Guid Id = Guid.Empty;

  141             OpenConnection();

  142 

  143             try

  144             {

  145                 Id = entryObject.Add(BlogId, Title, Body, IsPublic, Syndicated, ShowOnFrontPage, AllowComments, CreateDate);

  146 

  147                 entryObject.Persist();

  148 

  149                 foreach (Guid category in Categories)

  150                 {

  151                     taEntryCategory.Insert(category, Id);

  152                 }

  153             }

  154             catch { }

  155             finally

  156             {

  157 

  158                 CloseConnection(true);

  159             }

  160 

  161             return Id;

  162         }

  163 

  164         publicvoid UpdateEntry(Guid BlogId, string Title, string Body, bool IsPublic, bool Syndicated, bool ShowOnFrontPage, bool AllowComments, DateTime? CreateDate, List<Guid> Categories, List<Guid> RemovedCategories, Guid Original_Id)

  165         {

  166 

  167             OpenConnection();

  168 

  169             try

  170             {

  171                 entryObject.Update(BlogId, Title, Body, IsPublic, Syndicated, ShowOnFrontPage, AllowComments, CreateDate,Original_Id);

  172 

  173                 entryObject.Persist();

  174 

  175                 taEntryCategory.FillByEntry(DataSet.EntryCategory, Original_Id);

  176 

  177                 foreach (Guid category in Categories)

  178                 {

  179                     if (DataSet.EntryCategory.FindByCategoryIdEntryId(category, Original_Id) == null)

  180                         taEntryCategory.Insert(category, Original_Id);                   

  181                 }

  182                 foreach (Guid category in RemovedCategories)

  183                 {

  184                     if (DataSet.EntryCategory.FindByCategoryIdEntryId(category, Original_Id) != null)

  185                         taEntryCategory.Delete(category, Original_Id);

  186                 }

  187             }

  188             catch { }

  189             finally

  190             {

  191 

  192                 CloseConnection(true);

  193             }

  194         }

  195 

  196         publicvoid DeleteEntry(Guid EntryId)

  197         {

  198             OpenConnection();

  199 

  200             NBlogrDataSet.EntryRow entry = GetById(EntryId);

  201 

  202             foreach (NBlogrDataSet.EntryAttachmentRow attachment in DataSet.EntryAttachment)

  203             {

  204                 attachment.Delete();

  205             }

  206             foreach (NBlogrDataSet.EntryCategoryRow category in DataSet.EntryCategory)

  207             {

  208                 category.Delete();

  209             }

  210             foreach (NBlogrDataSet.CommentRow comment in DataSet.Comment)

  211             {

  212                 comment.Delete();

  213             }

  214 

  215             entry.Delete();

  216 

  217             taEntryAttachment.Update(DataSet.EntryAttachment);

  218             taEntryCategory.Update(DataSet.EntryCategory);

  219             commentObject.Persist();

  220             entryObject.Persist();

  221 

  222             CloseConnection();

  223         }

  224 

  225     }

  226 }

 

Then all that is left to do is show you the code from the page and you know how I did it with success

 

So this is the declarative part :

 

<%
@

Page
Language
=”C#”
MasterPageFile
=”~/NBlogrMaster.master”
AutoEventWireup
=”true”
CodeFile
=”Default.aspx.cs”
Inherits
=”_Default”
Title
=”NBlogr – Open Source Atlas Blogging”
%>


 

<
asp
:
Content

ID
=”Content2″
ContentPlaceHolderID
=”SideBarTop”
runat
=”Server”>


 


asp
:
Content
>

<
asp
:
Content

ID
=”Content1″
ContentPlaceHolderID
=”Main”
Runat
=”Server”>


    



                



   
<
asp
:
GridView
ID
=”gvEntries”
AutoGenerateColumns
=”false”
DataSourceID
=”odsFullEntry”
Width
=”100%”
GridLines
=”none”
runat
=”server”
ShowHeader
=”false”
OnRowDataBound
=”gvEntries_RowDataBound”
DataKeyNames
=”Id”
>


       
<
Columns
>


           
<
asp
:
TemplateField
>


               
<
ItemTemplate
>


                   



            
       
<
asp
:
Image
SkinID
=”postbullet”
ID
=”postBullet”
AlternateText
=’
<%# Eval(“Title”) %>runat=”server”/><b><%# Eval(“Created”,”{0:dddd, dd MMMM yyyy}”) %>b>


                   
<
hr
/>


                   
<
div
>


      
                   
<
h5
><
asp
:
HyperLink
ID
=”hlTitle”
NavigateUrl
=’
<%# Eval(“Id”,”~/Detail.aspx?entry={0}”) %>Text=’<%# Eval(“Title”) %>runat=”server”>asp:HyperLink>h5>


      
                   
<%
# Eval(“Body”) %>                     


                   

div
>


                   
<
hr
/>


                   
<
div
style
=”float:right”><
asp
:
Literal
ID
=”litCategories”
runat
=”server”>
asp
:
Literal
>
div
>


                   
<%
# Eval(“Created”,”{0:r}”) %>


               

ItemTemplate
>


              



           

asp
:
TemplateField
>


       

Columns
>


       
<
EmptyDataTemplate
>


            There are currently no posts available. Try again later.


       

EmptyDataTemplate
>


   

asp
:
GridView
>


   
<
asp
:
ObjectDataSource
ID
=”odsCategories”
runat
=”server”
InsertMethod
=”Add”
OldValuesParameterFormatString
=”original_{0}”


           
SelectMethod
=”GetAll”
TypeName
=”NBlogr.BLL.Category”>


           
<
InsertParameters
>


               
<
asp
:
ControlParameter
Name
=”Name”
Type
=”String”
ControlID
=”Category”
PropertyName
=”Text”
/>


           

InsertParameters
>


       

asp
:
ObjectDataSource
>
   



 



   
<
asp
:
ObjectDataSource
ID
=”odsFullEntry”
runat
=”server”
OldValuesParameterFormatString
=”original_{0}”
OnObjectCreated
=”odsFullEntry_ObjectCreated”
SelectMethod
=”GetFrontpageEntryList”
TypeName
=”NBlogr.Bll.FullEntry”>


       
<
SelectParameters
>


           
<
asp
:
SessionParameter
Name
=”BlogId”
SessionField
=”CurrentBlog”
Type
=”Object”
/>


       

SelectParameters
>


   

asp
:
ObjectDataSource
>
      



   
<
asp
:
ObjectDataSource
ID
=”odsFullEntryMonthYear”
runat
=”server”
OnObjectCreated
=”odsFullEntry_ObjectCreated”
OldValuesParameterFormatString
=”original_{0}”
SelectMethod
=”GetEntryListByMonthYear”
TypeName
=”NBlogr.Bll.FullEntry”
>


       
<
SelectParameters
>


           
<
asp
:
QueryStringParameter
Name
=”Month”
QueryStringField
=”month”
Type
=”Decimal”
/>


           
<
asp
:
QueryStringParameter
Name
=”Year”
QueryStringField
=”year”
Type
=”Decimal”
/>


           
<
asp
:
SessionParameter
Name
=”BlogId”
SessionField
=”currentBlog”
Type
=”Object”
/>


       

SelectParameters
>


   

asp
:
ObjectDataSource
>


   
<
asp
:
ObjectDataSource
ID
=”odsFullEntryCategory”
runat
=”server”
OnObjectCreated
=”odsFullEntry_ObjectCreated”
OldValuesParameterFormatString
=”original_{0}”
SelectMethod
=”GetEntryListByCategory”
TypeName
=”NBlogr.Bll.FullEntry”>


       
<
SelectParameters
>


           
<
asp
:
QueryStringParameter
Name
=”CategoryName”
QueryStringField
=”category”
Type
=”String”
/>


           
<
asp
:
SessionParameter
Name
=”BlogId”
SessionField
=”CurrentBlog”
Type
=”Object”
/>


       

SelectParameters
>


   

asp
:
ObjectDataSource
>


asp
:
Content
>


 


 





 

And here is the code behind. The bit you’re interested in, is the gvEntries_RowDataBound and setDataSource method:

 

    1 using System;

    2 using System.Data;

    3 using System.Configuration;

    4 using System.Collections;

    5 using System.Web;

    6 using System.Web.Security;

    7 using System.Web.UI;

    8 using System.Web.UI.WebControls;

    9 using System.Web.UI.WebControls.WebParts;

   10 using System.Web.UI.HtmlControls;

   11 using NBlogr.Bll;

   12 using NBlogr.Dal;

   13 using System.Collections.Generic;

   14 using System.Collections.Specialized;

   15 using NBlogr.Dal.NBlogrDataSetTableAdapters;

   16 

   17 publicpartialclass_Default : System.Web.UI.Page

   18 {

   19 

   20     FullEntry entryObject = newFullEntry();

   21 

   22 

   23     public _Default()

   24     {

   25 

   26         this.LoadComplete += newEventHandler(_Default_LoadComplete);

   27     }

   28 

   29     void _Default_LoadComplete(object sender, EventArgs e)

   30     {

   31         if (!IsPostBack)

   32         {

   33             setDataSource();

   34         }

   35     }

   36 

   37     privateBlogListRetrieval displayMode()

   38     {

   39         if(!string.IsNullOrEmpty(Request.QueryString["category"])) returnBlogListRetrieval.ByCategory;

   40 

   41         string year = Request.QueryString["year"];

   42         string month = Request.QueryString["month"];

   43         if (!string.IsNullOrEmpty(year) && !string.IsNullOrEmpty(month))

   44         {

   45                 returnBlogListRetrieval.ByMonthYear;

   46         }

   47         returnBlogListRetrieval.HomePage;

   48     }

   49 

   50     protectedvoid Page_Load(object sender, EventArgs e)

   51     {

   52     }

   53     privatevoid setDataSource()

   54     {

   55         gvEntries.DataSource = null;

   56         switch (displayMode())

   57         {

   58             default:

   59             caseBlogListRetrieval.HomePage:

   60                 gvEntries.DataSourceID = odsFullEntry.ID;

   61                 break;

   62             caseBlogListRetrieval.ByMonthYear:

   63                 gvEntries.DataSourceID = odsFullEntryMonthYear.ID;

   64                 break;

   65             caseBlogListRetrieval.ByCategory:

   66                 gvEntries.DataSourceID = odsFullEntryCategory.ID;

   67                 break;

   68 

   69         }

   70 

   71     }

   72 

   73     protectedvoid gvEntries_RowDataBound(object sender, GridViewRowEventArgs e)

   74     {

   75         if (e.Row.RowType == DataControlRowType.DataRow)

   76         {

   77             if (e.Row.RowState == DataControlRowState.Normal || e.Row.RowState == DataControlRowState.Alternate)

   78             {

   79                 Literal litCategories = ((Literal)e.Row.FindControl(“litCategories”));

   80                 litCategories.Text = “”;

   81                 NBlogrDataSet.EntryCategoryRow[] entrycats = entryObject.DataSet.Entry[e.Row.DataItemIndex].GetEntryCategoryRows();

   82                 foreach (NBlogrDataSet.EntryCategoryRow entrycat in entrycats)

   83                 {

   84 

   85                     litCategories.Text += entrycat.CategoryRow.Name + ” | “;

   86                 }

   87                 if (entrycats.Length > 0)

   88                     litCategories.Text = litCategories.Text.Remove(litCategories.Text.LastIndexOf(” | “));

   89 

   90             }

   91             elseif(e.Row.RowState == DataControlRowState.Edit)

   92             {

   93                 CheckBoxList lst = (CheckBoxList)e.Row.FindControl(“CategoryList”);

   94                 NBlogrDataSet.EntryCategoryRow[] entrycats = entryObject.DataSet.Entry[e.Row.RowIndex].GetEntryCategoryRows();

   95                 foreach (NBlogrDataSet.EntryCategoryRow entrycat in entrycats)

   96                 {

   97                     lst.Items.FindByValue(entrycat.CategoryId.ToString()).Selected = true;

   98                 }

   99 

  100             }

  101         }

  102 

  103 

  104     }

  105 

  106 

  107     protectedvoid odsFullEntry_ObjectCreated(object sender, ObjectDataSourceEventArgs e)

  108     {

  109         e.ObjectInstance = entryObject;

  110     }

  111 }

11AugUser group atlas presentations

This week I went to do a couple of presenations on atlas in the regional user groups here in New Zealand.

At first I was really nervous, so I apologise to the people in hamilton for not getting the best presenation I could give you, I even forgot some stuff that would make all the pieces fit together.

But after the first talk I started to get the hang of it, and now I regret that I can’t do more talks but who knows what the future brings.

It was really interesting to see that there are a lot of really skilled people with a passion for programming in New Zealand.

 

So in all I would like to thank everybody for taking the time to come and listen to my ramblings on Atlas.
And perhaps we’ll meet on Teched next week.

 

29JulBase4 Totally rocks !!!

The last couple of days I have been playing around with base4 and I have to tell you if you aren’t using it now. You should hurry yourself to their site and start downloading.

We are in the process of testing a schema generator that will wrap your existing databases to the base4 schema file.

I have a code reduction of at least 33% with another OR/mapper so that counts in my book.

Hurry to base4.net

 

People interested in testing the mapper please email me or something.

23JulSome choices made regarding NBlogr

For the development of NBlogr I had to say goodbye to some of my favorite controls.

The idea of NBlogr is that it is Open Source so that means I can’t use anything that is not open source / free in my project.  I use component arts excellent menu whenever I see fit except for now.

ComponentArt have 2-3 controls in their range that I really like. The other ones aren’t really usefull in my case.

I’ve been using the freetextbox control for 3,5 years now. But the latest versions aren’t really good implementations. If I load up my control in a firefox browser and I reload the site by entering in the address bar.. I get 3-5 errors @ pageLoad.  And that just sucks because the rest of the javascript doesn’t get executed and an atlas page won’t execute.

So for me it’s down with the freetextbox control and up with the tinymce control from moxiecode.
That one is the only true cross browser (IE, FF, Safari, Opera) richt text editor I can find

Another benefit : It’s smaller than the freetextbox and loads way faster.

Captcha isn’t a good solution for blocking comment spam. I’ve decided to use akismet as a refferer and comment blacklist service for NBlogr.

 

21JulMake the freetextbox work inside an atlas updatpanel

A while ago I blogged about making the freetextbox work inside an updatepanel. I didn’t put the code at that time because it wasn’t what it should be.

For the NBlogr engine I do need a working version of that control. And it should work on firefox and internet explorer. Now I have it somewhat working.  I thought it would be best to share this, as I’m sure that there are others that are facing the same problem.

You basically wrap it in an iframe so that it loads it’s script in a page that does not have an update panel on it.
through javascript you get the value of the entered in the freetextbox and set it in an hiddenfield. and voila you’re done.

FreeTextBoxWrapper.ascx :

<


iframe


runat
=”server”


id
=”ifrmTxt”


width
=”600″


height
=”400″


frameborder
=”0″


>
iframe
>

<


asp
:
HiddenField


ID
=”hfFtbValue”


runat
=”server”


/>

And the codebehind for the ascx :

12 [ValidationProperty("Text")]

13 publicpartialclassApp_Components_FreeTextBoxWrapper : System.Web.UI.UserControl

14 {

15 publicstringText

16 {

17 get

18 {

19 returnhfFtbValue.Value;

20 }

21 set

22 {

23 hfFtbValue.Value = value;

24 }

25 }

26 publicstringWidth

27 {

28 get

29 {

30 returnifrmTxt.Attributes["width"];

31 }

32 set

33 {

34 ifrmTxt.Attributes["width"] = value;

35 }

36 }

37 publicstringHeight

38 {

39 get

40 {

41 returnifrmTxt.Attributes["height"];

42 }

43 set

44 {

45 ifrmTxt.Attributes["height"] = value;

46 }

47 }

48 protectedvoidPage_Load(objectsender, EventArgse)

49 {

50 //load the freetextbox page that has no theme and no masterpage set. The background color is the one I chose to blend in with my design

51 ifrmTxt.Attributes["Src"] = ResolveUrl(string.Format(“~/App_Components/FreeTextBox.aspx?hf={0}&w={1}&h={2}”, hfFtbValue.ClientID,Width,Height));

52 ifrmTxt.Attributes["Name"] = ifrmTxt.ClientID;

53

54 if (!IsPostBack)

55 {

56 Session[hfFtbValue.ClientID] = hfFtbValue.Value;

57 }

58 }

59

60 protectedoverridevoidOnDataBinding(EventArgse)

61 {

62 base.OnDataBinding(e);

63 Session[hfFtbValue.ClientID] = hfFtbValue.Value;

64 }

65 }


And the page that contains the freetextbox control :

<%


@


Page


Language
=”C#”


AutoEventWireup
=”true”


Theme
=”"


CodeFile
=”FreeTextBox.aspx.cs”


Inherits
=”App_Components_FreeTextBox”


ValidateRequest
=”false”
%>


DOCTYPE


html


PUBLIC


“-//W3C//DTD XHTML 1.0 Transitional//EN”


“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<

html


xmlns
=”http://www.w3.org/1999/xhtml”


>
<

head


runat
=”server”>

<
title
>
A wrapper for the freetextbox in an atlas:updatepanel

title
>

<
style


type
=”text/css”>

body
{

background
:
#ffdaa0
;//Set your color here

margin
:
0
;
}


style
>

head
>
<

body
>

<
form


id
=”form1″


runat
=”server”>

<
div
>

<
FTB
:
FreeTextBox


ID
=”ftb”


runat
=”server”


SupportFolder
=”~/”


ClientSideTextChanged
=”onFtbClientTextChanged”>

FTB
:
FreeTextBox
>


div
>


<
script


type
=”text/javascript”>

//The lengthy constructor is there so that firefox also knows where to get the text.

function


onFtbClientTextChanged
(){

window
.
parent
.
document
.
getElementById
(
‘<%= MainPageField %>’
).
value
=
document
.
getElementById
(
‘<%= ftb.ClientID %>_designEditor’
).
contentWindow
.
document
.
body
.
innerHTML
;
};


if
(
navigator
.
userAgent
.
indexOf
(
“Firefox”
)!=-1)

document
.
getElementById
(
“<%= ftb.ClientID %>_htmlEditorArea”
).
addEventListener
(
‘change’
,
onFtbClientTextChanged
,
true
);
//for firefox


script
>



form
>

body
>

html
>

With it’s codebehind:

12 publicpartialclassApp_Components_FreeTextBox : System.Web.UI.Page

13 {

14 protectedstringMainPageField;

15

16 protectedvoidPage_Load(objectsender, EventArgse)

17 {

18 MainPageField = Request.QueryString["hf"];

19

20 if (!IsPostBack)

21 {

22 //When the page first loads we need to set the freetextbox with the value from the hiddenfield for databinding etc.

23 stringsetTextScript = string.Empty;

24 if(Request.Browser.Browser != “IE”)//for firefox we need to reach the freetextbox design editor to place our html

25 setTextScript = string.Format(“document.getElementById(‘{0}_designEditor’).contentWindow.document.body.innerHTML = window.parent.document.getElementById(‘{1}’).value;\r\n”, ftb.ClientID, MainPageField);

26 else

27 setTextScript = string.Format(“document.getElementById(‘{0}’).innerHTML = window.parent.document.getElementById(‘{1}’).value;\r\n”, ftb.ClientID, MainPageField);

28

29 Page.ClientScript.RegisterStartupScript(this.GetType(), “setText”, setTextScript, true);

30 ftb.Text = Session[MainPageField].ToString();

31 }

32 //Set the width to 99% so that the freetextbox displays completely

33 ftb.Width = Unit.Percentage(99);

34

35 //Get the height and widht and set the height relative to the width of the iframe (the toolbars move)

36 intheight = int.Parse(Request.QueryString["h"]);

37 intwidth = int.Parse(Request.QueryString["w"]);

38 if (width < 550)

39 ftb.Height = Unit.Pixel(height – 130);

40 elseif (width < 600)

41 ftb.Height = Unit.Pixel(height – 120);

42 else

43 ftb.Height = Unit.Pixel(height – 90);

44

45 }

46

47 }

20JulEvent logging made easy in asp.net

To log events/errors in your application, asp.net 2.0 has the healthmonitoring api that lives in System.Diagnostics.

You can get it to log just about anything that happens on your web app. To configure it, it takes you 15 minutes the first time and after that about 2 minutes.

You configure the asp.net services in the sql database.

To run the aspnet scripts on the database : attach the database to sql express via the management studio or something Give it a shorter name.

Then open a command prompt and navigate to %windir%\Microsoft.NET\Framework\v2.xxxxxxx

 

Next run aspnet_regsql – S servername -A all -d dbShortername

 

<
system.web
>

              <
trace


enabled
=


true



requestLimit
=

25



pageOutput
=

false



traceMode
=

SortByTime



localOnly
=

false

/>

              <
healthMonitoring


enabled
=


false

>

                     <
bufferModes
>

                           <
add


name
=


Critical Notification



maxBufferSize
=

100



maxFlushSize
=

20



urgentFlushThreshold
=

1



regularFlushInterval
=

Infinite



urgentFlushInterval
=

00:01:00



maxBufferThreads
=

1

/>

                           <
add


name
=


Constant Monitoring



maxBufferSize
=

1000



maxFlushSize
=

100



urgentFlushThreshold
=

100



regularFlushInterval
=

00:05:00



urgentFlushInterval
=

00:01:00



maxBufferThreads
=

1

/>

                    
bufferModes
>

                     <
providers
>

                           <
add


name
=


MySqlWebEventProvider



type
=

System.Web.Management.SqlWebEventProvider



connectionStringName
=

connectionStringName

                                 
maxEventDetailsLength
=


1073741823



buffer
=

true



bufferMode
=

Constant Monitoring

/>

                           <
add


name
=


CriticalErrorMailProvider



type
=

System.Web.Management.SimpleMailWebEventProvider



from
=


monitoring@sitedomain.com




to
=
“tryit@nospam.com



priority
=

High

                                 
bodyHeader
=


ERROR !!!



bodyFooter
=

Please investigate ASAP



subjectPrefix
=

Problem at [sitename].



maxEventLength
=

4096



maxSize
=

4096



maxMessagesPerNotification
=

1

                                 
buffer
=


true



bufferMode
=

Critical Notification

/>

                    
providers
>

                     <
profiles
>

                           <
add


name
=


siteDefault



minInstances
=

1



maxLimit
=

Infinite



minInterval
=

00:10:00

/>

                    
profiles
>

                     <
rules
>

                           <
add


name
=


All Events Default



eventName
=

All Events



provider
=

MySqlWebEventProvider



profile
=


siteDefault




minInstances
=

1



maxLimit
=

Infinite



minInterval
=

00:01:00



custom
=
“”
/>

                           <
add


name
=


Request Processing Errors



eventName
=

Request Processing Errors



provider
=

CriticalErrorMailProvider



profile
=


siteDefault


/>

                    
rules
>

             
healthMonitoring
>




system.web
>

The same type of functionality exists for asp.net 1.1 and is called elmah. Elmah lives on gotdotnet.



http://www.gotdotnet.com/workspaces/workspace.aspx?id=f18bab11-162c-4267-a46e-72438c38df6f



17JulI opened a workspace for NBlogr on gotdotnet

Today I opened a workspace on gotdotnet for an open source blog engine I started writing.

Everybody is welcome to join in. The space I have on gotdotnet is not so big which means that you’ll have to email me for now to get the complete and current source database.

A little bit later this week I will have a demo site/blog running on http://www.nblogr.com

The characteristics of the blog are :

1. It’s Atlas :)

2. It’s free for everybody to use

3. It’s open source so please if you change something then let me know.

4. Will be focussing on integrating the whole web 2.0 (the real web 2.0) experience i.e. direct integration of flickr etc.

5. The conversion from your current blog software should run without glitches.

I am definitely in need of somebody that knows how to create good templates/xhtml/css designs because that is not my strongest side.

The workspace is located @ http://workspaces.gotdotnet.com/nblogr

 

03JulAjaxPatterns.org

For those of you that are concerned with design patterns for ajax check out this site :

http://ajaxpatterns.org/ 

I have to say that that site is a real gem.  I for one am concerned with usability and am not discriminating so I think the leap to accessibility is only very small.  We are planning an application that is ajaxed and should still be completely usable by blind users which will be intresting to build.

In preparation for this i stumbled upon http://www.maxkiesler.com/index.php/weblog/comments/how_to_make_your_ajax_applications_accessible/

That page has got about 40 links to sites that discuss accesibility in an ajaxed world.

The last issue I’m facing is the fact that because asp.NET renders webresource urls that are incredibly long. The w3 xhtml validator won’t validate my pages and only because of this url.  I want to render valid xhtml 1.1 pages. So that’s something I will be looking at in the next few weeks when I’ve got some spare time.

30JunJavascript obfuscation

I’ve been getting much better along with atlas lately. Almost up to the point that it takes me almost the same time to create page in asp.net than it does me to create a page in atlas. Notice the word almost :) And that’s optimism talking

Anyway it does take a wee while longer to create an atlas page than it would to create an asp.net page. But the result is about 10x as usable and than a normal page.

That being said. All that atlas goodnes comes at a cost : A lot of javascript being pushed down to the browser. When I was in wellington on wednesday there was somebody talking about atlas in the user group.  Seen as I will go talk to the regional groups I was quite keen what Tatham had to say on the subject.

It was interesting but at a certain point he talked about the “obfuscated” javascript files. Those are just packed. That made me think that I also want to have packed javascript that is slightly less readable. I remember I have some open source library that I downloaded a year or so ago.

Well the guy has a nice library that you can download here :

http://dean.edwards.name/packer/

It’s nice but his HttpHandler doesn’t work for me. But there’s a simple work-around. Make your own handler that reads the javascript file and uses his Pack function.

If somebody is interested in the code just drop me an email and i’ll send it to you.


Recent Flickrs

    Blogroll

    Recent Listening

    Scrobbler