ASP.NET pages that use AJAX components make usually many requests to server per one page to load all required JavaScript and CSS files. Connections, like all other real time resources, are most expensive to create and keep. If we can somehow decrease the number of requests per page load then we need less server resources for same amount of users. For ASP.NET forms we can use script combining, for ASP.NET MVC applications we can use ASP.NET MVC Client-side Resource Combine.
MVC Resource Combine is open-source project you can find in CodePlex. ASP.NET official ScriptManager needs server-side form as a container. This means that all scripts are loaded in the body of page. I have found no way how to make ScriptManager to create script and other references to page header. MVC Resource Combine is free of this problem.
MVC Resource Combine is easy to use. Just follow these steps.
- Download the latest release and add references to DLL-s of MVC Resource Combine.
- Add the following line to web.config file, under <configSections> element:
<section name="resourceCombine" type="Mvc.ResourceCombine.ConfigSectionSetting,
Mvc.ResourceCombine" />
- Add the following line to web.config file, under <configuration> section:
<resourceCombine definitionUrl="~/App_Data/combine.xml" />
- Now open Global.asax and add the following line before all the other route definitions:
routes.AddResourceCombineRoute("Resource Combine");
- To App_Data folder add new XML-file combine.xml. By example, for jqGrid you may have JavaScript resource set like this:
<?xml version="1.0" encoding="utf-8" ?>
<resourceCombine url="~/combine.axd" defaultDuration="15"
defaultVersion="1" >
<resourceSet name="jqGrid" type="js" duration="30"
version="a">
<resource path="~/Scripts/jquery-1.3.2.js"
mode="LocalStatic" />
<resource path="~/Scripts/jquery.jqGrid.js"
mode="LocalStatic" />
<resource path="~/Scripts/js/jqModal.js"
mode="LocalStatic" />
<resource path="~/Scripts/js/jqDnR.js"
mode="LocalStatic" />
<resource path="~/Scripts/jquery.ajaxQueue.js"
mode="LocalStatic" />
<resource path="~/Scripts/jquery.bgiframe.min.js"
mode="LocalStatic" />
<resource path="~/Scripts/thickbox-compressed.js"
mode="LocalStatic" />
<resource path="~/Scripts/jquery.autocomplete.js"
mode="LocalStatic" />
</resourceSet>
</resourceCombine>
- Now open Site.Master and add call for MVC Resource Combine and specify resource set by its name (jqGrid):
<%= Html.CombinerLink("jqGrid")%>
- Now run your application and view page source. You should see something like this:
<script type="text/javascript" src="/combine.axd/jqGrid/a">
</script>
NB! Don’t forget to add reference to Mvc.ResourceCombine namespace in your Global.asax and Site.Master files. Well, if you have Resharper, then it is almost possible to forget these references. :)
Now, let’s see results. It’s Saturday and I’m watching Estonian biggest song contest, so I’m too lazy to add Firebug screenshots here. I have a little bit different configuration but numbers in the following table should give you some idea about wins in performance.
| |
Before
combine
|
After
combine
|
Difference
(before/after)
|
| Requests |
21
|
4
|
5.25
|
| Size (kb) |
259
|
19
|
13.63
|
| Time (s) |
7.69
|
4.84
|
1.59
|
As you can see, using MVC Resource Combining it is possible to achieve better performance with pretty simple and time consuming efforts. Also you don’t have to mix ScriptManager and other ASP.NET forms elements to your ASP.NET MVC views. By the way, you can combine also all the other resources that can be downloaded as one file – by example, style sheets.
Microsoft has a lot forums in different (community) sites with a lot of topics. In this posting I listed up Microsoft forums, their locations and forum groups (categories under which forums belong). The purpose of this posting is to provide you with important information – where you get help when you have technical problems.
MSDN Forums
Location: http://social.msdn.microsoft.com/forums/en-US/categories/
MSDN forums site is Microsoft’s biggest forum site I think. It’s a huge pile of information about almost every topic you can imagine. For many technologies you can consider MSDN forums as main source of support and information.
Forum groups:
ASP.NET Forums
Location: http://forums.asp.net/
ASP.NET forums are focused on ASP.NET and data management technologies. This is the main source of ASP.NET related information and if you have problems with ASP.NET you should start with this forum. If you state your questions correctly then you get answers pretty quickly.
Forum groups:
Silverlight Forums
Location: http://silverlight.net/forums/
Silverlight forums are for you if you are serious Silverlight hacker. You can find information almost about every Silverlight topic. Although I am not Silverlight pro and don’t visit this forum often I can see that this forum is pretty active. If you have questions then feel free to ask there. You can see only few forum groups in the following list, but don’t throw this forum away – all these groups have good bunch of forums.
Forum groups:
Windows Forms / WPF Forums
Location: http://windowsclient.net/Forums/
Forums about building client environment on Windows platform. Windows Forms forums are moved away for today and they are part of MSDN forums. WPF forums are still there and don’t be afraid trying them out.
Forum groups:
- Windows Presentation Foundation
- Windows Forms
- Acropolis
IIS Forums
Location: http://forums.iis.net/
If you are IIS admin or developer or you are just interested in IIS and its features then check out IIS forums. Similarly to Silverlight forums you can see not very much forum groups here but almost all these groups contain a lot of forums. Just check out if these forums may help you.
Forum groups:
If I missed some Microsoft forums site here then please let me know.
I am at vacation from 23.06-01.07. This time I am Italy again and besides hanging around in different nice places I visit also their yearly heavy-metal pearl: Gods of Metal festival!
Meanwhile this blog – like a mystery – publishes new writing everyday to keep you happy and thumbs up. Like always, feel free to leave me comments here but don’t expect any answers before 01.07. I am not really sure if I have time (or will) to be in internet during vacation. :)
P.S.If somebody can suggest me cool places in Monza then I am more than happy :)
.Net Framework 4.0 introduces memory mapped files. Memory mapped files are useful when you need to do in-memory data manipulation and your data structures are large. For large in-memory data the performance of memory mapped file is the best. It is much faster than MemoryStream. And like files on hard disc, memory mapped files can be shared between different programs. MemoryMappedFile and other classes for memory mapped files can be found from System.IO.MemoryMappedFiles namespace.
Now let’s see the example that contains two applications: one of them is primitive server that creates and holds memory mapped file and the other is simple client that reads that file. In the end of the posting you can find download link for example Visual Studio 2010 solution.
MemoryMappedFile server
Our server, as I said before, is primitive. It creates memory mapped file and writes some bytes to our file. Then it starts waiting key press from user to release resources and exit. The code of server is here.
C#
static void Main(string[] args)
{
Console.WriteLine("Memory mapped file server started");
using (var file = MemoryMappedFile.CreateNew("myFile", int.MaxValue))
{
var bytes = new byte[24];
for (var i = 0; i < bytes.Length; i++)
bytes[i] = (byte)(65 + i);
using (var writer = file.CreateViewAccessor(0, bytes.Length))
{
writer.WriteArray<byte>(0, bytes, 0, bytes.Length);
}
Console.WriteLine("Run memory mapped file reader before exit");
Console.WriteLine("Press any key to exit ...");
Console.ReadLine();
}
}
VB.NET
Private Shared Sub Main(ByVal args As String())
Console.WriteLine("Memory mapped file server started")
Using file = MemoryMappedFile.CreateNew("myFile", Integer.MaxValue)
Dim bytes = New Byte(23) {}
For i = 0 To bytes.Length - 1
bytes(i) = CByte((65 + i))
Next
Using writer = file.CreateViewAccessor(0, bytes.Length)
writer.WriteArray(Of Byte)(0, bytes, 0, bytes.Length)
End Using
Console.WriteLine("Before exiting run memory mapped file reader")
Console.WriteLine("Press any key to exit ...")
Console.ReadLine()
End Using
End Sub
MemoryMappedFile reader
The client project opens memory mapped file and reads bytes that server wrote there. I hope you notice that I hard coded the count of bytes that reader reads from memory mapped file. The point is simple – we are accessing memory mapped file directly without any contracts for file structure. In reality there will be some API that you use to manager memory mapped file in your application.
C#
static void Main(string[] args)
{
Console.WriteLine("Memory mapped file reader started");
using (var file = MemoryMappedFile.OpenExisting("myFile"))
{
using (var reader = file.CreateViewAccessor(0, 24))
{
var bytes = new byte[24];
reader.ReadArray<byte>(0, bytes, 0, bytes.Length);
Console.WriteLine("Reading bytes");
for (var i = 0; i < bytes.Length; i++)
Console.Write((char)bytes[i] + " ");
Console.WriteLine(string.Empty);
}
}
Console.WriteLine("Press any key to exit ...");
Console.ReadLine();
}
VB.NET
Private Shared Sub Main(ByVal args As String())
Console.WriteLine("Memory mapped file reader started")
Using file = MemoryMappedFile.OpenExisting("myFile")
Using reader = file.CreateViewAccessor(0, 24)
Dim bytes = New Byte(23) {}
reader.ReadArray(Of Byte)(0, bytes, 0, bytes.Length)
Console.WriteLine("Reading bytes")
For i = 0 To bytes.Length - 1
Console.Write(CChar(bytes(i)) & " ")
Next
Console.WriteLine(String.Empty)
End Using
End Using
Console.WriteLine("Press any key to exit ...")
Console.ReadLine()
End Sub
Now run server (MemoryMappedFileCreate) and after that the client (MemoryMappedFileRead). Server creates new memory mapped file and writes there 24 bytes of characters. Client then reads these bytes and writes them to console.
To find out more about memory mapped files feel free to read MSDN Utopia blog entry Working with memory mapped files in .NET 4.
Visual Studio 2010 introduces also some new debugging features. One of them is debug history. Debug history enables you to track all the points on track of control flow and it also monitors activities that you cannot see otherwise. It makes debugging of hard to find problems much easier, I think. Of course, there are many other new and cool debugging features available.
Image on right shows how debug history windows looks like. You can click on image to see it at original size. As there are usually many steps of code execution shown it is very convenient if we are able to filter messages somehow.
You can filter debug history by step category and thread. The last filtering option is specially useful when building multithreaded applications. You can also switch some filters off when you are looking for debugger messages located at specific categories.
Screenshot on right shows one cool thing more – debug history contains also information about registry and file system access. I think it makes hunting of hard to find bugs more easier than before (why is SharePoint first thing that I remember when somebody mentions hard to find bugs…:) ).
When you click on debug history entry then history entry will be expanded. On the following screenshot fragment you can see what information is given when debugger hits breakpoint.
As you can see, debug history is very powerful feature. It makes it much easier to track you code flow and control steps that your code has executed. Debug history window is also able to show data hierarchically. You have to modify some settings to turn hierarchical debug data on. I will blog about it in near future. So, stay tuned!
Couple of years ago I brought two books for my company. Today I can say that I made a small investment that still works pretty well. These books are titled as The Data Model Reosurce Book and author of these books is Len Silverston.
First volume of Data Model Resource Book introduces common models that are used by almost all industries. Second volume offers us industry specific models.
These models are not something final and also they are not absolute truth. You can use these models to build your own models that fit best to your applications.
For me these models are very important. When I start modeling new object model I will check these books for sure. Most interesting parts of models represented in these books are abstractions. You can build many parts of your system on abstractions based on models of this book. You don’t need to change these abstractions significantly later. Also these abstractions keep you moving on right direction.
Both books can be used as manuals you keep on your desk. But you can also read these books from cover to cover – you will learn a lot of new stuff and you will look at your models not like before.
My company uses these books and this far we have had no disappointments – all the models and abstractions from these books have helped us a lot. I strongly recommend Data Model Resource Books for everybody how wants to build strong, extensible and flexible data models.
Review from Amazon
"Len Silverston has produced an enormously useful two-volume compendium of generic (but not too generic) data models for an extensive set of typical enterprise subject areas, and for various industries that any data modeler will likely encounter at some point in his or her career. The material is clearly written, well organized, and goes below the obvious to some of the more perverse and difficult information requirements in an enterprise. This is an invaluable resource for doing one's homework before diving into any modeling session; if you can't find it here, there is certainly a very similar template that you can use for just about any situation with which you might be faced."
--William G. Smith, President, William G. Smith & Associates
Table of Contents
| Volume 1 | Volume 2 |
| Foreword. Acknowledgments. About the Author. Introduction. People and Organizations. Products. Ordering Products. Shipments. Work Effort. Invoicing. Accounting and Budgeting. Human Resources. Creating the Data Warehouse Data Model from the Enterprise Data Model. A Sample Data Warehouse Data Model. Star Schema Designs for Sales Analysis. Star Schema Designs for Human Resources. Additional Star Schema Designs. Implementing the Universal Data Models. Appendix A: Logical Data Model Entities and Attributes. Appendix B: Data Warehouse Data Model Tables and Columns. Appendix C: Star Schema Design Tables and Columns. How to Use the CD-ROM Product. Other Reusable Data Model and Data Warehouse Design Resources. Index. | Foreword. Acknowledgments. About the Author. Introduction. Manufacturing. Telecommunications. Health Care. Insurance. Financial Services. Professional Services. Travel. E-Commerce Models. Using the Industry Models in the Real World. Appendix A: Entities and Attributes for Manufacturing Models. Appendix B: Entities and Attributes for Telecommunications Models. Appendix C: Entities and Attributes for Health Care Models. Appendix D: Entities and Attributes for Insurance Models. Appendix E: Entities and Attributes for Financial Services Models. Appendix F: Entities and Attributes for Professional Services Models. Appendix G: Entities and Attributes for Travel Models. Appendix H: Entities and Attributes for E-Commerce Models. Appendix I: List of Entities and Their Associated Figures. How to Use the Volume 2 Industry Electronic Products. Index. |
Visual Studio 2010 has very powerful web application packaging and deployment system. When deploying your web application you create the deployment package and then publish it to web server. After configuring it is one-click action to get current version of application up to target server. Let’s see how it works.
Packaging and publishing settings
As a first thing you may take a look at project properties. There is new tab called Package/Publish where you can find all packaging and publishing defaults. You don’t have to change these settings unless you really-really need it. For me default settings are working very well.
You can click on the image on right if you want to see those settings. It is also possible to deploy your database to target server but I will blog about this some other time. Let’s focus on application deployment in this posting.
Creating package
To create package you just have to right click on your project and select Package –> Create Package. Check out the following fragment of screenshot.
You can find package under obj folder of application. Screenshot (or windowshot?) on right shows you obj and Package folders and Package folder contents. Just click on it to see it at original size.
Package folder has same structure that is published to target server. You can see here all files and folders of your application that are to be published. These files and folders are under PackageTmp folder.
Package folder contains files that are used to deploy you web application. You can see there also zip-file. This is the package that is sent to target server to save you some bandwidth. Of course, it depends on packaging settings if zip file is used for deployment or not. I suggest you to use zip-file because in this case only one file will be uploaded and probability of network problems during upload is smaller.
Publishing
To publish your project right click on the project and select Publish. Because you may have more than one target environment where you may want your application to be deployed then publishing profile will be asked. In this window you can also manage publishing profiles.
Here you can set all options needed for application publishing. As test servers may use homemade certificates then it is also possible to accept them. The other settings here should be pretty obvious. To publish your web application immediately you can use Publish toolbar as show on the following image. Just click on the highlighted icon and publishing starts without any additional dialogs.

One-click publishing is one of the most powerful deployment features of Visual Studio 2010. Other testers have told and written that this is most stable and bullet-proof web application deployment system they have seen under Visual Studio.
Try it!
If you feel like trying out Visual Studio 2010 and new web features then feel free to read my blog entries Visual Studio 2010 and .Net Framework 4.0 downloads and Visual Studio 2010 and .Net Framework 4.0 to get started. To get free beta hosting for your ASP.NET 4.0 web application check out my blog entry Free ASP.NET 4.0 beta hosting available.
I am experimenting right now on ORCS Web beta hosting where I publish my ASP.NET 4.0 MVC application – picture gallery for my photos of my bunny. To get ASP.NET MVC applications running on ORCS Web beta hosting you must make ASP.NET MVC 1.1 reference as local reference in your web application project.
And last suggestion - try it out by yourself. :)
I am using workflow with association form in one of my current SharePoint projects. When workflow is added to list there are some parameters that user must insert. Workflow instances are able to persist association data and to be more flexible the association data is saved as XML string. But in the code it is more convenient to use object instead of XML strings. I will show you how I solved the situation.
This is the class I want to use to keep association data.
C#
public class WorkflowConfig
{
public List<string> UserFields = new List<string>();
public string DateField = string.Empty;
public int NotifyBefore;
}
VB.NET
Public Class WorkflowConfig
Public UserFields As New List(Of String)()
Public DateField As String = String.Empty
Public NotifyBefore As Integer
End Class
Now I need something to convert objects based on this class to XML. I need also something to restore objects from XML. Luckily .Net Framework has XmlSerializer class in System.Xml.Serialization namespace. Lazy as I am I really don’t want to write factory classes and other fancy infrastructure that will be overkill when thinking about our requirements.
We need to write two methods – one that serializes the object and the other that takes XML and returns object of type WorkflowConfig. I add these two methods to my workflow configuration class as static methods.
C#
public class WorkflowConfig
{
[XmlArray("Fields")]
[XmlArrayItem("Field")]
public List<string> UserFields = new List<string>();
public string DateField = string.Empty;
public int NotifyBefore;
public static string Serialize(WorkflowConfig conf)
{
var confString = string.Empty;
using (var stream = new MemoryStream())
{
var serializer = new XmlSerializer(typeof(WorkflowConfig));
serializer.Serialize(stream, conf);
stream.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(stream))
{
confString = reader.ReadToEnd();
}
}
return confString;
}
public static WorkflowConfig Deserialize(string xml)
{
var serializer = new XmlSerializer(typeof(WorkflowConfig));
WorkflowConfig conf = null;
using (var stream = new MemoryStream(xml.Length))
{
var bytes = Encoding.UTF8.GetBytes(xml);
stream.Write(bytes, 0, bytes.Length);
stream.Seek(0, SeekOrigin.Begin);
conf = (WorkflowConfig)serializer.Deserialize(stream);
}
return conf;
}
}
VB.NET
Public Class WorkflowConfig
<XmlArray("Fields")> _
<XmlArrayItem("Field")> _
Public UserFields As New List(Of String)()
Public DateField As String = String.Empty
Public NotifyBefore As Integer
Public Shared Function Serialize(ByVal conf As WorkflowConfig) As String
Dim confString = String.Empty
Using stream = New MemoryStream()
Dim serializer = New XmlSerializer(GetType(WorkflowConfig))
serializer.Serialize(stream, conf)
stream.Seek(0, SeekOrigin.Begin)
Using reader = New StreamReader(stream)
confString = reader.ReadToEnd()
End Using
End Using
Return confString
End Function
Public Shared Function Deserialize(ByVal xml As String) As WorkflowConfig
Dim serializer = New XmlSerializer(GetType(WorkflowConfig))
Dim conf As WorkflowConfig = Nothing
Using stream = New MemoryStream(xml.Length)
Dim bytes = Encoding.UTF8.GetBytes(xml)
stream.Write(bytes, 0, bytes.Length)
stream.Seek(0, SeekOrigin.Begin)
conf = DirectCast(serializer.Deserialize(stream), WorkflowConfig)
End Using
Return conf
End Function
End Class
Now let’s try out this code using simple test program.
C#
class Program
{
static void Main(string[] args)
{
var cfg = new WorkflowConfig();
cfg.UserFields.Add("Author");
cfg.UserFields.Add("Invited");
cfg.DateField = "MeetingDate";
cfg.NotifyBefore = 2;
Debug.WriteLine(WorkflowConfig.Serialize(cfg));
}
}
VB.NET
Class Program
Private Shared Sub Main(ByVal args As String())
Dim cfg = New WorkflowConfig()
cfg.UserFields.Add("Author")
cfg.UserFields.Add("Invited")
cfg.DateField = "MeetingDate"
cfg.NotifyBefore = 2
Debug.WriteLine(WorkflowConfig.Serialize(cfg))
End Sub
End Class
Our little test program produces XML output shown below. We can save this XML to workflow association data. Later we can use WorkflowConfig.Deserialize() method to get our object back from XML.
<?xml version="1.0"?>
<WorkflowConfig
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Fields>
<Field>Author</Field>
<Field>Invited</Field>
</Fields>
<DateField>MeetingDate</DateField>
<NotifyBefore>2</NotifyBefore>
</WorkflowConfig>
That’s it. Simple and clear. If you plan to use this code then make the modifications you need and don’t forget adding your error handling code to static methods.
Recently I wrote about Visual Studio 2010 and multiple web.config files support. Let’s see now how to play with web.config transformation so we can use one configuration on development environment and the other for production environment.
Adding config transformations
When we create web application project the web.config file is created automatically. web.config contains some section definitions and assembly, caching, pages, handlers and other configuration settings.
Besides them we can add our own settings to appSettings block and connection strings to connectionStrings block. These two blocks are the main sources of differences between development, test and production environments. appSettings may include settings for paths that are different in different environments. I think there is no need to mention connectionStrings.
Web.config versions are bound to solution configurations. By default, solutions have two configurations: Debug and Release. If you want you can define more configurations. By example you may want to add special configuration for test environment.
Adding config transforms is simple. Just right click on Web.config file and select Add Config Transforms. Visual Studio 2010 will add transforms automatically. You can read in this point my blog entry Visual Studio 2010: Multiple web.config versions.
Understanding transformations
Web.config transforms are not separate versions of main Web.config file. Web.config file that was created by default contains all configuration options. Transform files contain only transforms – that is, modifications that one or another configuration needs in Web.config file to be made.
You can find more information about transforms from Visual Web Developer Team Blog posting Web Deployment: Web.Config Transformation.
Changing connection string for release configuration
By default, new transform for release configuration looks like this.
<?xml version="1.0"?>
<!-- For more information on using web.config transformation
visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration
xmlns:xdt=http://schemas.microsoft.com/XML-Document-Transform>
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
</system.web>
</configuration>
As we can see there is only one transformation rule defined – remove debug attribute. We can also change values of attributes. Let’s add new connection string to Web.Config file.
<connectionStrings>
<add name="MyGallery"
connectionString="Default connection string"
providerName="System.Data.SqlClient" />
</connectionStrings>
This is default connection string that is used by all configurations that has no transform for this connection string. We wanted to use different connection string for product system where we use release configuration. Let’s add the following block to Web.Release.Config file.
<connectionStrings>
<add
name="MyGallery"
connectionString="Production connection string"
providerName="System.Data.SqlClient"
xdt:Transform="Replace" xdt:Locator="Match(name)"
/>
</connectionStrings>
Basically the connection string is like usual connection string in Web.config file. But there are two new attributes: Transform and Locator. These attributes tell to Visual Studio 2010 packaging system how to modify Web.config so it works with current solution configuration.
- Transform. Tells to Visual Studio that we want to replace original connection string.
- Locator. Tells to Visual Studio how to find the configuration option that needs transformation.
There are many other transforms you can use to make modifications to Web.config. You can find more information about transforms from Visual Web Developer Team Blog posting Web Deployment: Web.Config Transformation.
To get transformed Web.config file you have to create package of you application.
Deployment packages is one of the new and cool features of Visual Studio 2010. I will write about them a little bit later this week.
Visual Studio 2010, .Net Framework 4.0 and Team Foundation Server 2010
Additional software
Learning
Try out at live
Last thing...
More Posts
Next page »