To dynamically inject the detail links from the task content to the keyword detail content I decided to inject the links using Regex.Replace, just prior to displaying the task content. So I wrote a helper that the razor page could call to make the replacements.
For this to work, I needed each task to have a property that contained a list of keywords that were applicable to the content, so I could pass these into the helper method. I didn't want to store these keywords with the task, as then I'd need a housekeeping task to keep these lists up to date with the detail content.
So, I used LINQ to SQL to dynamically look up keywords that were found in the content, which I then added to my new property. To prevent the new property from being automatically added to the task table, Entity Framework allows you to annotate properties on your entity classes as NotMapped. This is basically saying I'm going to calculate the values for this property myself in code.
To verify that EF was making the queries that I was expecting, I used a SQL profiler. I could see that the correct queries were being made and that SQL Server was correctly caching queries that had already been run.
Note about XSS: I've been reading up about cross site scripting (xss) and how pages can be vulnerable to such an attack if content containing html elements are not html encoded prior to display.
In this solution, I'm injecting links into content and for the links to be displayed correctly in the browser, I'm bypassing html encoding of the content using @Html.Raw. So to prevent a vulnerability, my helper method pre html encodes the content before injecting the links. This way, only the links that are injected by my managed code will reach the browser as html.
The other thing that I will need to do, before deployment, is ensure that the assembly containing the helper is signed with a strong name to prevent switching of a malicious version.
Showing posts with label web application architecture. Show all posts
Showing posts with label web application architecture. Show all posts
Wednesday, 28 March 2012
Tuesday, 27 March 2012
Back-end
To get the back end in place, I introduced two new technologies.
Firstly, I introduced Unity as my dependency injection (IoC) container. This means that I can couple the controller, service and data access layers of the application at run time through dependency injection. As the controller instance is created by the MVC 3 framework, I needed a way of telling MVC to use my unity container. After some internet digging I found that the MVC framework provides an interface that can be used as an adapter for the Unity container. All I had to to was wrap the Unity container exposing the IDependencyResolver interface and then set the resolver in MVC using DependencyResolver.SetResolver. Quite a neat solution I thought.
Secondly, I introduced an entity framework code-first context. I had already used code-first on another project and was very impressed. Using the plain old CLR object (POCO) classes that I had created when designing the front end, I could generate a database, seed it with data and read back data using a LINQ to SQL statement. This all seems like quite a lot of work, but it was remarkably straightforward. The only thing that I needed to do to the POCO class was add a property to represent the primary key (public int id { get; set; }).
The data seeding is done by creating a class that inherits from DropCreateDatabaseIfModelChanges. So each time the application starts, this will check for changes and rebuild and reseed the database if required.
Well, we are almost done for the core of this application. The next piece of work will be adding detail links to keywords in the maintenance task content. I'm going to need to have a little think about how I'm going to achieve this. All I know is that it will involve dynamically adding in links to the content at some point.
Firstly, I introduced Unity as my dependency injection (IoC) container. This means that I can couple the controller, service and data access layers of the application at run time through dependency injection. As the controller instance is created by the MVC 3 framework, I needed a way of telling MVC to use my unity container. After some internet digging I found that the MVC framework provides an interface that can be used as an adapter for the Unity container. All I had to to was wrap the Unity container exposing the IDependencyResolver interface and then set the resolver in MVC using DependencyResolver.SetResolver. Quite a neat solution I thought.
Secondly, I introduced an entity framework code-first context. I had already used code-first on another project and was very impressed. Using the plain old CLR object (POCO) classes that I had created when designing the front end, I could generate a database, seed it with data and read back data using a LINQ to SQL statement. This all seems like quite a lot of work, but it was remarkably straightforward. The only thing that I needed to do to the POCO class was add a property to represent the primary key (public int id { get; set; }).
The data seeding is done by creating a class that inherits from DropCreateDatabaseIfModelChanges
Well, we are almost done for the core of this application. The next piece of work will be adding detail links to keywords in the maintenance task content. I'm going to need to have a little think about how I'm going to achieve this. All I know is that it will involve dynamically adding in links to the content at some point.
Sunday, 25 March 2012
Date Picker
To replace the Telerik calendar control with the jquery-ui inline date picker, I've had to get familiar with jquery and AJAX. When selecting a date, I wanted to make a post-back to the server so that I could fetch the maintenance tasks to display on the right hand side.
With the Telerik calendar, this was easy, as the control has an action method that allowed me to invoke the controller. The only difficulty I had was with a bug in the control which prevented me from changing the date format to a non localised format. I found this solution: http://www.telerik.com/community/forums/aspnet-mvc/calendar/calendar-date-format.aspx
Anyway, back to the jquery-ui inline datepicker. To do the callback to the controller, I needed to hook up a client side event handler (onSelect) and get it to make an AJAX call. I then had to modify my controller action so that it returned either a full view when called outside AJAX (i.e. for when the whole view is loaded on initial routing) and a partial view for when it's called from AJAX. Another handler receives the partial view and inserts the partial view into the relevant div.
This approach is great for 2 reasons: Firstly, the whole page doesn't get refreshed each time the date is changed, just the contents part of the page that needs changing. This also means that I don't have to send the date back to the view to keep the state on the date picker.
Now I'm reasonably happy with the UI, I'm going to start building out the back end of the application. I want to be able see maintenance tasks from the database. Whilst I was working with the UI, I was happy to use some 'canned' data from in-memory entity objects.
NB: I found quite a good site that explains the basic web concepts with lots of examples. This has been very useful to me when delving into javascript, html dom and jquery:
http://www.w3schools.com/default.asp
With the Telerik calendar, this was easy, as the control has an action method that allowed me to invoke the controller. The only difficulty I had was with a bug in the control which prevented me from changing the date format to a non localised format. I found this solution: http://www.telerik.com/community/forums/aspnet-mvc/calendar/calendar-date-format.aspx
Anyway, back to the jquery-ui inline datepicker. To do the callback to the controller, I needed to hook up a client side event handler (onSelect) and get it to make an AJAX call. I then had to modify my controller action so that it returned either a full view when called outside AJAX (i.e. for when the whole view is loaded on initial routing) and a partial view for when it's called from AJAX. Another handler receives the partial view and inserts the partial view into the relevant div.
This approach is great for 2 reasons: Firstly, the whole page doesn't get refreshed each time the date is changed, just the contents part of the page that needs changing. This also means that I don't have to send the date back to the view to keep the state on the date picker.
Now I'm reasonably happy with the UI, I'm going to start building out the back end of the application. I want to be able see maintenance tasks from the database. Whilst I was working with the UI, I was happy to use some 'canned' data from in-memory entity objects.
NB: I found quite a good site that explains the basic web concepts with lots of examples. This has been very useful to me when delving into javascript, html dom and jquery:
http://www.w3schools.com/default.asp
Friday, 23 March 2012
Accordion
Today I've been dipping my toes into the world of jquery-ui. I wanted a collapsible panel, but found that the Telerik one needed to be bound to a collection-master-detail type model setup. What I was after was a collapsible panel that would bind to collection-title-content type model. I found that the jquery-ui accordion offered such a feature.
It took me a while to get the accordion up an running, mostly because the jquery scripts used by the Telerik calendar component was interfering with the jquery-ui scripts.
I'm now looking into using the jquery-ui date-picker to replace the telerik calendar component. This will offer an unified look and feel with the accordion. I need to work out what client side scripting is needed to invoke the action method on the controller and then read back the selected date.
It took me a while to get the accordion up an running, mostly because the jquery scripts used by the Telerik calendar component was interfering with the jquery-ui scripts.
I'm now looking into using the jquery-ui date-picker to replace the telerik calendar component. This will offer an unified look and feel with the accordion. I need to work out what client side scripting is needed to invoke the action method on the controller and then read back the selected date.
Subscribe to:
Posts (Atom)