Web Design, Programming, Tutorials
Posts tagged ASP.NET MVC
Setting up Structure Map
May 14th
StructureMap
If you haven’t heard about dependency injection, it is something you should definitely look into. It can save tons of time when coding.
StructureMap is a dependency injection framework that makes it easy to create new instances of objects and even cache an instance of an object so various references to the object use the same instance. This is very useful with objects such as database connections.
You can download the library from the StructureMap Home Page. The example used in this post is using StructureMap 2.6.1. I’m also using Visual Basic. I had a tough time finding information on how to use StructureMap with Visual Basic, so hopefully, this will help someone else.
Setting Up MVC
When using StructureMap with ASP.NET MVC 1.0, I’ve found it works best if a folder is created in each project; Main, Data, and Service; where the StructureMap files are stored. This keeps them organized and makes them easy to find as you need to update them. A reference to the StructureMap DLL will need to be added to each project as well.
In the main project’s StructureMap folder, the following files are needed:
StructureMapControllerFactory
Imports System.Web.Mvc
Imports StructureMap
Public Class StructureMapControllerFactory
Inherits DefaultControllerFactory
Protected Overrides Function GetControllerInstance(ByVal controllerType As System.Type) As System.Web.Mvc.IController
Return ObjectFactory.GetInstance(controllerType)
End Function
End Class
This class sets up a factory class to get an instance of the StructureMap factory. It will be used to replace MVC’s default controller factory so that StructureMap will be in charge of creating our controllers.
BootStrapper
Imports StructureMap
Imports YourProject.Data
Imports YourProject.Services
Public Class BootStrapper
Public Shared Sub ConfigureStructureMap()
ObjectFactory.Initialize(AddressOf StructureMapRegistry)
End Sub
Private Shared Sub StructureMapRegistry(ByVal x As IInitializationExpression)
x.AddRegistry(New MainRegistry())
x.AddRegistry(New DataRegistry( _ ConfigurationManager.ConnectionStrings("iSeries").ConnectionString, _ ConfigurationManager.ConnectionStrings("Interbase").ConnectionString))
x.AddRegistry(New ServiceRegistry())
x.Scan(AddressOf StructureMapScanner)
End Sub
Private Shared Sub StructureMapScanner(ByVal scanner As StructureMap.Graph.IAssemblyScanner)
scanner.Assembly("YourProjectNamespace")
scanner.Assembly("YourProjectNamespace.Data")
scanner.Assembly("YourProjectNamespace.Services")
scanner.WithDefaultConventions()
End Sub
End Class
This class is where StructureMap is configured. Within the StructureMapRegistry method, each AddRegistry call is made to include each of our project’s registry files, which have yet to be created. We will get to that in a moment, but notice that the DataRegistry is accepting values for connection strings. This is how information can be passed into a class being created by StructureMap when you would like to keep the configuration settings within the Web.config file.
Also, within the StructureMapScanner method, an entry needs to be made to scan each project’s namespace.
MainRegistry
Imports DCS.Data
Imports StructureMap.Configuration.DSL
Public Class MainRegistry
Inherits Registry
Public Sub New()
[For](Of IWebContext)() _
.Use(Of WebContext)()
End Sub
End Class
Each project will have its own registry file where you can specify that Interface-A should create an instance of Class-A. In the example above, I want StructureMap to create an instance of WebContext (from the main project) when it comes across a reference to IWebContext.
In the Data project’s StructureMap folder you will need:
DataRegistry
Imports StructureMap.Configuration.DSL
Imports Spartan.DAO.Database
Public Class DataRegistry
Inherits Registry
Public Sub New(ByVal iSeriesConnectionString As String, ByVal interbaseConnectionString As String)
'Data Connections.
[For](Of YourDataContext)() _
.HybridHttpOrThreadLocalScoped _
.Use(Function() New YourDataContext())
[For](Of DB2Connection)() _
.HybridHttpOrThreadLocalScoped _
.Use(Function() New DB2Connection(iSeriesConnectionString))
[For](Of InterbaseConnection)() _
.HybridHttpOrThreadLocalScoped _
.Use(Function() New InterbaseConnection(interbaseConnectionString))
'Repositories.
[For](Of IShiftRepository)() _
.Use(Of ShiftRepository)()
End Sub
End Class
The DataRegistry is interesting because we are passing in two connection strings from the Web.config file. The first data connection is for Microsoft SQL, the second for DB2 and the third for Interbase. The second and third are using the DB2Connection and InterbaseConnection classes which are home grown database connection class that I wrote. All three of these database connections are being cached by using the .HybridHttpOrThreadLocalScoped property. Using this will make the database cached instance work for both your live program and your unit testing.
The entry under repositories is what all remaining entries would look like within the registry class. Since the data project contains our repositories, they would all be listed here.
And, in the Service project’s StructureMap folder you will need:
ServiceRegistry
Imports StructureMap.Configuration.DSL
Public Class ServiceRegistry
Inherits Registry
Public Sub New()
[For](Of IShiftService)() _
.Use(Of ShiftService)()
End Sub
End Class
The service registry is similar to that of the main project. All service classes found in the service project would be listed here.
Changes to the Global.asax
The last thing to do is setup the Global.asax file to load StructureMap. Make the following changes to the Application_Start method:
Sub Application_Start()
RegisterRoutes(RouteTable.Routes)
'StructureMap
BootStrapper.ConfigureStructureMap()
ControllerBuilder.Current.SetControllerFactory(New StructureMapControllerFactory())
End Sub
Now, the default controller factory used by MVC will be overridden by our StructureMapControllerFactory. When a controller is created, it will now use StructureMap.
So, how do you use this when creating a class? This is the easy part.
StructureMap will use the greediest constructor from your controller, meaning, if you have two constructors, the one with the most parameters will be used. Each parameter references an Interface and sets a class variable for the object. StructureMap uses the registry classes that we setup to map an interface to a real object.
Example Controller
Imports YourProject.Data
Imports YourProject.Services
Imports StructureMap
Public Class ExampleController
Inherits System.Web.Mvc.Controller
Private _shiftService As IShiftService
Private _webContext As IWebContext
Public Sub New( _
ByVal shiftService As IShiftService, _
ByVal webContext As IWebContext)
_shiftService = shiftService
_webContext = webContext
'Initialize service classes.
_shiftSummaryService.Initialize(New ModelStateWrapper(Me.ModelState))
End Sub
...
All that you need to do is create a constructor, pass in all the interface references you need for the controller, then store them in a class variable. If you need to use the ModelState for validation within your service class, the best way I’ve found to do this is use an Initialize function in your service class to pass in the ModelState. This is because the ModelState is not yet created by MVC when the service classes are created by StructureMap.
When StructureMap creates the instance of the ShiftService, it will look at the greediest constructor from that class to create instances for any required parameters. This continues for all classes that are referenced.
Once the solution has been configured to use StructureMap, the only thing you’ll need to maintain will be the registry files as you add new classes and interfaces to your project. Don’t forget to add a registry entry or you will recieve an exception.
ASP.NET MVC – Organizing your solution
Feb 4th
Keeping your project files organized will help you navigate through your projects and help you find what you are looking for to make changes faster.
Here are some tips that I use to help keep my ASP.NET MVC solutions organized:
- Use multiple projects to separate sections of the program.
- Use folders to group interfaces, classes, and factories that deal with an object.
- If objects can be used by other programs, put them in their own class library project.
Option 1
When beginning a new program, I usually start by creating an ASP.NET MVC solution with 4 projects:
- The main project – which contains the MVC components of the application such as Controllers, Views, CSS, and JavaScript files.
- The unit testing project – which contains all of the requirements for the application along with any fake repositories used for testing.
- The data project – which contains the repositories and domain objects used by the application.
- The services project – which contains the service objects that are the middle-man between the Controller and the Repository.
Option 2
Folders are used within the projects to further organize the code files within. The data project could have a domain object called Operation. Domain objects are placed in a folder with the same name as the object. Interfaces, Repositories, and Factories that deal with the object are also placed in the domain object folder.
The service project is organized similar to the data project.
The unit test project is slightly modified from the default to create a folder which contains all fake repository objects and another folder to contain requirement tests. Depending on the detail of unit testing you wish to utilize, you may have unit tests that verify application requirements and/or unit tests that further verify other parts your code.
In my opinion, you can write application requirements that detail exactly what the program should do and as long as you unit test these requirements, you don’t need to waste time trying to unit test 100% of your program. If a bug is found later, it will most likely be because it was not an application requirement. Then, add a new requirement, write a unit test, and make the application pass the new test.
Option 3
Where I work, we have various databases that we need to communicate with. We wanted a way to use these databases the same way every time without having to remember all of the different objects and names that needed to be used by each. So, I developed a parent wrapper class around the basic database functionality and then individual wrappers around each database object that inherited from the parent wrapper. Now, we can call up any of the database connections and work with them in exactly the same way, the only difference between them is the call to the factory when creating the instance.
These database wrappers were added to their own separate project so that in future applications, we could continue to reuse them.
Configuring IIS 6 and ASP.NET MVC
Jan 28th
By default, IIS 6 does not work with ASP.NET MVC and needs to be configured to use wild-card mapping to get MVC’s routing and clean URLs to work correctly. Unfortunately, IIS 6 does take a performance hit because all requests are processed by ASP.NET. Static files, such as images, CSS, and JavaScript are processed as a dynamic page instead of a static one.
Install ASP.NET MVC
Follow the first two steps of the instructions for installing ASP.NET MVC. The third step can be ignored since Visual Studio will not be installed on the server.
Configuring ASP.NET 2.0
First thing to do is open the IIS Manager ->expand your server ->Web Service Extensions folder. Right-click on the white space under the list of Web Service Extensions and select to Add a new Web service extension…
The New Web Service Extension window will pop open. Enter “ASP.NET v2.0.50727″ as the Extension Name and click the Add button. Browse to the C:\Windows\Microsoft.Net\Framework\v2.0.50727 folder and select the aspnet_isapi.dll file. Make sure to check the “Set extension status is Allowed” button before clicking OK.
This will allow your programs to run ASP.NET 2.0, 3.0, and 3.5 versions of the .NET framework.
Configuring Your Web Application
The next thing to do is open the properties of the Web Site where your web application is. Select the ASP.NET tab and select 2.0.50717 in the ASP.NET version drop down box.
Next, click on the Home Directory tab. Click on the Configuration button. Under the Wild-card application maps area, click the Insert button. Browse to the C:\Windows\Microsoft.Net\Framework\v2.0.50727 folder and select the aspnet_isapi.dll file. Uncheck the “Verify that file exists” before clicking OK. Save your changes and your site should now be able to run ASP.NET MVC and use the routes setup by your application.
Scheduling A Task In A Web Application On A Windows Server
Jan 19th
When writting web applications, there may be times when you would like to perform some task automatically at the same time or every X number of hours. Web applications only execute their code when a request is made from a client’s browser. Because of this, scheduled tasks within the web application will not work.
There are a few different options:
- Build a separate Windows Service application that can connect to the assemblies your web application uses to execute the scheduled task.
- Build a separate Windows application that communicates with a web service that your web application also uses to perform the scheduled task.
- Use the Windows Scheduler to call the URL of the action to perform the task.
The first option might sound good at first, but creating a separate program that talks to your web application’s library files is a bad idea. Maintenance will become a problem as you change your web application. Since the code is in two places, unit testing will not tell you that the class library you just changed has now broken your scheduled tasks in your windows service.
The second option is slightly better, but you still may have issues with changing your class library.
The third option is the one that I will show you how to configure. We will setup a VBS script that will perform a call to any web address we pass to it. Then, we’ll setup a batch file that calls the VBS script and passes in one or more URLs to execute. And finally, we’ll go through using the Windows Scheduler to create the scheduled task when the batch file should execute.
The primary advantage to this method is that you get to keep all of your code together in your web application. You simply setup an action that performs whatever task you wish to schedule and make sure that action is callable from an anonymous user.
WebRequest.vbs
You may copy the following code and paste into a text file. Then, rename the file to WebRequest.vbs. The script basically takes an argument that is passed into it as the URL. The HTTP object is setup and then the URL is called using a GET request. Then, the returned status is checked to see if the request was successful or not.
url = WScript.Arguments.Item(0)
'WScript.echo url
set WshShell = WScript.CreateObject("WScript.Shell")
set http = CreateObject("Microsoft.XmlHttp")
http.open "GET", url, FALSE
http.send ""
if (http.Status = 200) then
WScript.echo "Request successful."
else
WScript.echo "Error: " & http.Status
end if
set WshShell = nothing
set http = nothing
The Batch File
Calling the WebRequest.vbs file from a batch file is very easy. Simply create a new text file, calling it whatever you’d like, and paste in the following line of text. Rename the file to .BAT when finished.
cscript WebRequest.vbs "http://www.domain.com/controller/action"
Scheduling The Task
From your Windows server, open the Control Panel and then open the Scheduled Tasks item. Next, click on Add Scheduled Task. Choose any application to schedule. This will be changed later on. Configure how often you wish the schedule to run and enter a user name and password to run the schedule as. This users should have access to running the web browser from the server.
After your new scheduled task has been created, open it. In the Run text box, type in the full path to your batch file. Then, in the Start In text box, type in the full path without the batch file name. You can also adjust your scheduled time from within here. Click OK to save the changes and your scheduled task should be ready.
You can test the Windows Scheduler by setting the scheduled time to a minute or two in the future and then waiting for it to execute. If you just wish to test your action, or manually run it, you can simply run the batch file.
Installing ASP.NET MVC
Jan 15th
Here are the steps to install into Visual Studio 2008:
- Download ASP.NET MVC 1.0 from Microsoft’s website. Make sure to download the MSI file and the source code if you would like to see how it works.
- Install the AspNetMVC1.msi file.
- Open Visual Studio 2008 and go to:
- File -> New -> Project
- Under Project Types, select Web under either Visual Basic or C#
- Under Templates, select ASP.NET MVC Web Application
- Give your application a name and change its location if you wish
That’s it! Upon creating a new web application, the default MVC application will open.
Note:
ASP.NET MVC should also work using the free development tool from Microsoft, Visual Web Designer 2008.
Why you should use ASP.NET MVC
Jan 14th
If you’re like me, you like to have control over how your websites look and the HTML returned to the browser. ASP.NET MVC gives you that control by letting you keep your HTML separate from the core application code. If you learn to use tools like CSS and JavaScript, you can use them in the exact same way you would if you were working with a static web page. There are no generated IDs or missing/custom HTML attributes. While it does give you some helpers to generate HTML, you do not have to use them if you don’t want to.
ASP.NET MVC is very extensible and flexible. Nearly any component of the framework can be swapped out for your own version, if you so choose to delve into the inner workings.
ASP.NET MVC was built with Unit Testing in mind. If you’re not using Unit Testing, you should definitely start researching how it can improve your code reliability.
So, why should you use ASP.NET MVC?
- Based on the MVC pattern.
- Allows you to use Standards such as XHTML and CSS.
- Separation of concerns allows for more maintainable code.
- Gives you help when you need it and gets out of your way when you want control.
- Unit Testing is built in and easy to do.
- Fully supported by Microsoft.
- You can download the code for the ASP.NET MVC Framework and see how it works.
If you know HTML, CSS, or JavaScript and you are familiar with ASP, then you should definitely look into ASP.NET MVC.