Contest: What have you done with .NET?

Do you develop applications using .NET?  If so, head on over to this new contest at http://www.mydotnetstory.com and entry your story for a chance to win some really great prizes.  What can you win?  Well, if you are chosen by the judges, you could win a trip the the Galapagos Islands or a Smart Car or just cash!  If you are one of the top 3 vote getters on the site, you will win an Internet Media Tablet.  For more information on the prizes, check out the Contest site.

If you want to read about some of the powerful and “unexpected” .NET stories by REAL developers, please check out the campaign site. 

Also, if you are planning on attending the PDC, check out the PDC Party at 8:00 pm in the  VS / .NET Lounge Theater.  You have a chance to win a Zune HD 32 GB by answering questions correctly there.

I hope to see a lot of really great applications discussed on there.

Good luck!



Posted 05 November 09 12:48 by Tom | 0 Comments   
Filed under
Impersonation, WCF, and making updates to a database

I was troubleshooting a problem with WCF where the updates to a remote database were failing.  The reason for the failure was found pretty quickly to be delegation.

For general impersonation questions in regards to WCF, there is lots of great information found here.

For my situation, the problem was that the ASP.NET application that was calling the WCF service was impersonating and I couldn’t enable delegation in my environment.  So the connection to SQL failed.  There are a number of ways to solve this problem, but some have more problems then others.

Fix #1

The easiest way is the add a User ID and Password to the web.config file.  But then you have to worry about updating that if the password expires and also the security of having the password in the config file.

Note: You can add the password to the registry following KB329290

Fix #2

Another option would be to impersonate a given user on the network that has permission and use that when you are making the calls to the database.  You can follow the “Impersonate a Specific User in Code” section of KB306158 for that.  This also has the problem of passwords expiring and that the password is stored in code, but it isn’t in a config file anymore.

Fix #3

The one I ended up using was this one.  In my case, the IIS Worker Process was already running under a network account that could assess the database.  So I just needed a way to get rid of the impersonation that the process was running under, do the database work, and then impersonate again.  The key was to do the following:

WindowsImpersonationContext wic = null;
 
try
{
    wic = WindowsIdentity.Impersonate(IntPtr.Zero); // revert to self
 
    // Do database work here
}
finally
{
    if (wic != null)
        wic.Undo(); // resume impersonating
}

This will revert to self, let the database code run and then continue impersonating after that is done.

With this code, I don’t have to store any passwords in my code or config files.  And everything will work correctly.  The only drawback is that all database work is going through a single account and so on the database side, you can’t do auditing by users to see what they are doing.  But in my application, I am already logging information into the database so there would be no need to have that kind of information.



Posted 17 September 09 03:14 by Tom | 5 Comments   
Filed under ,
Debugging .NET apps for .NET 4.0

With Visual Studio 2010 and .NET 4.0 getting ready to be shipped sometime in the next year, I wanted to see what were peoples ideas for how to debug applications that were written with them.  Are you happy in production with what you are currently doing?  Do you use SOS.dll to troubleshoot problems?

SOS

The main place I am really interested in is production debugging.  Is SOS a sufficient tool to get the data that you need?  If you had another version of SOS for .NET 4.0, would you be happy with the features it has or would you want something more?

Debugger

I understand that using a typical debugger can be very difficult for people.  If you don’t know what you are looking at, it can be very difficult to understand what is a problem and what is normal.  It is also very difficult to see typical problems.  For example, if you know your program is crashing due to running out of memory, what do you do to see what is taking up memory?  How do you tell if it is fragmentation?  What types of fragmentation are there that you would need to look for?

I wanted to see what the interest is in a different way of looking at the data, something more along the lines of DebugDiag.

Opinions

I’d love to hear your thoughts.  Let me know!



Posted 02 September 09 12:45 by Tom | 11 Comments   
Filed under , , ,
Discounts on Microsoft Certification Exams

In case anyone is interested in taking some Microsoft Exams, we have some discounts on them.  Here is the announcement talking about the discounts:

clip_image001

Get up to 25 percent off select Microsoft Certification exams

In this tough economy, are you looking to get ahead? Do you want to stand out? Microsoft Certification can help you pursue a new career in IT, move from one job role to another, or become indispensible in your existing role. Microsoft Certifications are continually evaluated and updated to ensure their relevance in the marketplace. As a result, earning a certification not only helps you stay current on the latest developments in Microsoft technologies and platforms; it also enables you to demonstrate to employers your job skills.

To make it easier for you to get started, you can now take advantage of a new set of discounts that Microsoft is providing on select Microsoft Certification exams. Visit the website below to find out how to begin and to see whether the exam you’re interested in is 15%, 20% or 25% off. This offer is available worldwide while supplies last, and you have to register, schedule and purchase your discounted exam by December 31, 2009.  

http://www.microsoft.com/learning/careeroffers



Posted 01 September 09 02:41 by Tom | 0 Comments   
Filed under ,
WCF, Silverlight, and SharePoint… Oh my!

I was recently working on a project and needed to have Silverlight make a WCF call.  That is pretty straight forward until you place the Silverlight code inside SharePoint and want it to call a WCF that is also inside SharePoint.

The first problem that I had to solve was getting Silverlight to be able to call the WCF correctly.  Since in Visual Studio when you make the connection, it will have the local server for the path.  Like http://localhost:95559/MyService.svc and for SharePoint I wanted it to point to the local server’s name and in the _layouts directory.  Luckily I came across the following blog that helped with getting that to work: Silverlight ServiceReferences.ClientConfig Alternatives

The only change I had to make was to the BasicHttpBinding:

   1: BasicHttpBinding binding = new BasicHttpBinding(
   2:             Application.Current.Host.Source.Scheme.Equals("https", StringComparison.InvariantCultureIgnoreCase) 
   3:             ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.TransportCredentialOnly);

Then I had to figure out how to get WCF hosted in SharePoint correctly.  For that, I turned to this post: Hosting a WCF service in Windows Sharepoint Services v3.0

So I now had a httpModule that would handle the *.svc requests that start with a ~.  That is important to make sure because you will get called again without the ~ so make sure you check for that before removing the first character.  I also had Silverlight setup where it could call the SharePoint machine regardless of what Visual Studio wanted to do.  I followed the “Dynamic Configuration” setup.

When I had this setup, I then got problems still.  The only way I could see the problem was running something like Network Monitor or Web Development Helper.  In there I saw a 500 error being returned from the server.  I attached a debugger and saw that it was giving me this message:

Security settings for this service require ‘Anonymous’ Authentication but it is not enabled for the IIS application that hosts this service.

From this error, I realized that WCF uses anonymous by default.  So I went into my web.config file and changed the binding to support Windows:

   1: <bindings>
   2:     <basicHttpBinding>
   3:         <binding name="MyBinding">
   4:             <security mode="TransportCredentialOnly">
   5:                 <transport clientCredentialType="Windows"/>
   6:             </security>
   7:         </binding>
   8:     </basicHttpBinding>
   9: </bindings>

Then you just add a bindingConfiguration=”MyBinding” on your service endpoint.

After I made that change, I ran it again and this time I got the following error:

Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service.

So I changed my binding to:

   1: <bindings>
   2:     <basicHttpBinding>
   3:         <binding name="basicHttpBinding">
   4:             <security mode="TransportCredentialOnly">
   5:                 <transport clientCredentialType="Ntlm"/>
   6:             </security>
   7:         </binding>
   8:     </basicHttpBinding>
   9: </bindings>

Note: If you have a ”mex” endpoint you may get another error about ‘anonymous’ because that uses anonymous by default.  If you do, you can delete the mex endpoint unless you need discoverability.  Then you will need to remove anonymous from that as well.

After making these changes, Silverlight was able to call back into the ASP.NET project that it was loaded from and call a WCF service that was running inside SharePoint.



Developing for the Clouds

I wanted to start a conversation with everyone on the thoughts around Cloud Computing.  I have been using Azure for a while now and I have found some interesting things out about it.

Before I start talking about those things though, I wanted to see who was planning on using this technology or who is already using it.  This would include other Cloud solutions as well.

If you are, what are you planning to do in the Cloud?  How are you going about setting up testing, development, maintaining, monitoring in the Cloud?

I think that Cloud Computing is the future in a lot of ways and feel like things are going to change in a fundamental way in the not to distant future because of Cloud Computing.  Do you agree?

Please keep in mind that I am not saying that Cloud Computing is a whole new way methodology, but I do think it will enable scenarios that weren’t possible before and will allow us to push the envelope of what we are capable of doing with a computer.

I look forward to hearing back from you and talking more about Azure and Cloud Computing.



Posted 18 June 09 11:33 by Tom | 21 Comments   
Filed under , ,
Adventures with Silverlight 3.0 and SharePoint – Part 2

Just a quick update on this.  I had to make a few changes to my site and I now have it working!

To fix the master page problem, I needed to load it from code behind.  Once I did that, I was able to have that show up.  But then I had a problem of the Silverlight application didn’t show up at all.

To get around that I needed to get rid of the width and height settings from the Silverlight object.  So I needed to change from using width=100% height=100% to style=”width: 700px; height: 700px”

After making that change, the only thing left was to move my connection string settings into the web.config file for SharePoint.  After that was done, my Silverlight Navigation project loaded just fine in SharePoint and was able to use RIA Data Services.

 

I hope these two posts help anyone else looking to do this.  Let me know if you run into any other problems or have any suggestions.



Posted 15 June 09 01:02 by Tom | 1 Comments   
Filed under , , ,
Adventures with Silverlight 3.0 and SharePoint – Part 1

I have been working on getting Silverlight 3.0 to work with SharePoint 2007 and I wanted to share with you the progress I have made and some of the challenges I have remaining.

Project

This project uses Silverlight 3.0, the Silverlight Toolkit for 3.0, and RIA Data Services.  So it is basically using as much as it can that is new.  This means we have a Entity Model and a ASP.NET web application that the Silverlight application will use.  It also uses authentication using the new Domain Service for authentication.

What I did

So the first thing I did was to follow the steps in this blog post about Silverlight 2.  I just changed it to be the System.Web.Silverlight from 3.0.  The suggestion for upgrading the web.config for Silverlight worked great for bringing most of the stuff I needed.

I then did the following steps:

  1. Copied my project under the _layouts folder
  2. Copied the bin folder for my project to the VirtualDirectories\80\bin folder of SharePoint
  3. Ran gacutil on system.web.silverlight
  4. Ran gacutil on system.web.ria
  5. Ran gacutil on system.web.domainservices.webcontrols

I then made some changes to the web.config of my project, namely removing everything that was already in the web.config for SharePoint.  The last change I did was to make the bin folder have FullTrust.  I did this by adding the following to the wss_minimaltrust.config file:

   1: <CodeGroup class="UnionCodeGroup" version="1"
   2:     PermissionSetName="FullTrust">
   3:     <IMembershipCondition
   4:         class="UrlMembershipCondition"
   5:         version="1" Url="$AppDirUrl$/bin/*"
   6:     />
   7: </CodeGroup>

After making these changes, the next problem I ran into was around RIA.  It makes calls using a DataService.axd.  So that needed to be added to the web.config file.  In <system.web>:

   1: <httpHandlers>
   2:     ...
   3:     <add path="DataService.axd" verb="GET,POST" type="System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
   4:       validate="false" />
   5: </httpHandlers>

And <system.Webservers>:

   1: <handlers>
   2:     ...
   3:     <add name="DataService" verb="GET,POST" path="DataService.axd"
   4:             type="System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
   5: </handlers>

That information is talked about in the Silverlight forum for getting it to work with Azure here.

I then tried to get my application to load the SharePoint master page but I ran into a problem where it tells me:

   1: The referenced file '<path to master>' is not allowed on this page.

I am currently investigating that error and will post more as I progress.  If anyone else is trying to get this to work with SharePoint or has any suggestions, I’d love to hear them.



Posted 02 June 09 12:33 by Tom | 6 Comments   
Filed under , , ,
CannonPI teaser video

There is a new video up on youtube that is the beginning of many more videos.  You should check it out and look for for more coming soon.

Also, see if you recognize any of the people in this, feel free to post here who you think they are.



Silverlight RIA calling Stored Procedures that don’t return tables

There are times where you want to use a stored procedure that doesn’t return just normal rows out of a database.  One classic example is if you are doing Full-Text Searching and want to return the Rank.

The first step to doing this is the get your stored procedures exposed in the ADO.NET Entity Data Model.  Instead of going through the steps for doing that here, I’ll just point you to a great post by Julie Lerman on her blog: Implement SELECT Stored Procedures that return miscellaneous data in CTP2 of EF Designer.

After following those steps, you will have the stored procedures all ready to be called from the Entity Data Model.  You can then use these stored procedures from ASP.NET, ASP.NET MVC, or anything else that can consume the Entity Data Model.

One side note, if you use the “Update Model from Database…” feature on your Entity Model, it will destroy the store layer tables that you created from Julie’s post.  If that happens, just recreate them again.

Now to get this to work from Silverlight using RIA, there is another step that needs to be done.  You need to get these stored procedures exposed in your Domain Service.  One way to handle doing that is to create functions in the Domain Service like the following for each of them.  Assume you have a stored procedure called SearchData and it takes a string as input to seach for in the database.  You can create a function in the Domain Service like:

   1: public IQueryable<SearchDataTable> GetSearchData(String SearchString)
   2: {
   3:     return Context.SearchData(SearchString).AsQueryable();
   4: }

When you compile this, it will create a client side function called LoadSearchData that takes a string as input.  Then you can call this just like you load any other data in Silverlight RIA:

   1: public void Searching(String search)
   2: {
   3:     if (String.IsNullOrEmpty(search))
   4:     {
   5:         return;
   6:     }
   7:  
   8:     context.LoadSearchData(search);
   9:     context.Loaded += new EventHandler<System.Windows.Ria.Data.LoadedDataEventArgs>(context_Loaded);
  10: }
  11:  
  12: void context_Loaded(object sender, System.Windows.Ria.Data.LoadedDataEventArgs e)
  13: {
  14:     var context = sender as MyDomainContext;
  15:     foreach (SearchDataTable searchData in context.SearchDataTable)
  16:     {
  17:         ... do stuff with the data ...
  18:     }
  19: }

Notice that I am hooking up to when the context is finished being loaded so that I know the data has been populated.



How are production ASP.NET site problems applied in the future?

There are a lot of different things you can use to monitor a production ASP.NET web site for problems.  Some of the most common are logging, perfmon counters and the like.  There is also the method of getting feedback from people using the site when they relay that there is a problem.

The question I would like to talk about is how do you use this information for future projects.

Best Practices

I think the most obvious way is the create a type of best practices document from the learning that you have had in the past.  For example, using StringBuilder if you are going to be dynamically building up strings.

Code Re-use

Another useful method is sharing code that is already in production so that other future projects can use it.  This not only has the added benefit of less development time, you know this code has been running in production and will work correctly and not cause issues.

Analysis

Sometimes you can notice things in production that you are unable to fix.  For example something that would take an entire redesign of the web site to fix.  But these types of things can be passed on to the next project where some of the design decisions haven’t been made yet.  One such decision could be how many servers should handle each layer of your site.  And how many database servers you should have.

Other ideas?

What other things do you do with your learnings from previous web sites?  Do you look at places where you over-analyzed a problem and spent too much time solving something that didn’t need such a complicated solution?  I’d love to hear what else people do.  Does the technology play a role in future sites?  Like would you consider changing to Silverlight or MVC because of something that happened on a previous site?

Posted 27 April 09 01:38 by Tom | 3 Comments   
Filed under
Creating interesting Silverlight chart datapoints

I was reading this great post by Jeff Wilcox and quickly found out that some of the needed code to get this to work was missing from his post.

So I went about recreating the missing parts and getting this to work.  Here is what mind looks like now that it is functional:

image

To get to this work, I followed the same steps that Jeff mentioned so I will not go through them here.  But what I will do is give you the source code that I used.

Test.xaml

   1: <navigation:Page x:Class="TestProject.Views.Test" 
   2:            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:            xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
   5:            xmlns:datavis="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit"
   6:            xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
   7:            Title="Test Page">
   8:     <navigation:Page.Resources>
   9:         <ControlTemplate x:Key="CustomLineDataPointTemplate" TargetType="chartingToolkit:LineDataPoint">
  10:             <Grid x:Name="Root" Opacity="0" ToolTipService.ToolTip="{Binding DataPointTooltipText}">
  11:                 <VisualStateManager.VisualStateGroups>
  12:                     <VisualStateGroup x:Name="CommonStates">
  13:                         <VisualStateGroup.Transitions>
  14:                             <VisualTransition GeneratedDuration="0:0:0.1"/>
  15:                         </VisualStateGroup.Transitions>
  16:                         <VisualState x:Name="Normal"/>
  17:                         <VisualState x:Name="MouseOver">
  18:                             <Storyboard>
  19:                                 <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="MouseOverHighlight" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
  20:                                     <SplineColorKeyFrame KeyTime="00:00:00" Value="#FFFFDF00"/>
  21:                                 </ColorAnimationUsingKeyFrames>
  22:                                 <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="MouseOverHighlight" Storyboard.TargetProperty="(UIElement.Opacity)">
  23:                                     <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.24"/>
  24:                                 </DoubleAnimationUsingKeyFrames>
  25:                             </Storyboard>
  26:                         </VisualState>
  27:                     </VisualStateGroup>
  28:                     <VisualStateGroup x:Name="SelectionStates">
  29:                         <VisualStateGroup.Transitions>
  30:                             <VisualTransition GeneratedDuration="0:0:0.1"/>
  31:                         </VisualStateGroup.Transitions>
  32:                         <VisualState x:Name="Unselected"/>
  33:                         <VisualState x:Name="Selected">
  34:                             <Storyboard>
  35:                                 <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="SelectionHighlight" Storyboard.TargetProperty="(UIElement.Opacity)">
  36:                                     <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.18"/>
  37:                                 </DoubleAnimationUsingKeyFrames>
  38:                             </Storyboard>
  39:                         </VisualState>
  40:                     </VisualStateGroup>
  41:                     <VisualStateGroup x:Name="RevealStates">
  42:                         <VisualStateGroup.Transitions>
  43:                             <VisualTransition GeneratedDuration="0:0:0.5"/>
  44:                         </VisualStateGroup.Transitions>
  45:                         <VisualState x:Name="Shown">
  46:                             <Storyboard>
  47:                                 <DoubleAnimation Duration="0" Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="1"/>
  48:                             </Storyboard>
  49:                         </VisualState>
  50:                         <VisualState x:Name="Hidden">
  51:                             <Storyboard>
  52:                                 <DoubleAnimation Duration="0" Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0"/>
  53:                             </Storyboard>
  54:                         </VisualState>
  55:                     </VisualStateGroup>
  56:                 </VisualStateManager.VisualStateGroups>
  57:                 <Ellipse Stroke="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}"/>
  58:                 <Ellipse RenderTransformOrigin="0.661,0.321">
  59:                     <Ellipse.Fill>
  60:                         <RadialGradientBrush GradientOrigin="0.681,0.308">
  61:                             <GradientStop Color="#00FFFFFF"/>
  62:                             <GradientStop Color="#FF3D3A3A" Offset="1"/>
  63:                         </RadialGradientBrush>
  64:                     </Ellipse.Fill>
  65:                 </Ellipse>
  66:                 <Ellipse x:Name="SelectionHighlight" Opacity="0" Fill="Red"/>
  67:                 <Ellipse x:Name="MouseOverHighlight" Opacity="0" Fill="White"/>
  68:             </Grid>
  69:         </ControlTemplate>
  70:  
  71:         <datavis:StylePalette x:Key="MyCustomStylePalette">
  72:             <!--Blue-->
  73:             <Style TargetType="Control">
  74:                 <Setter Property="Background">
  75:                     <Setter.Value>
  76:                         <RadialGradientBrush>
  77:                             <RadialGradientBrush.RelativeTransform>
  78:                                 <TransformGroup>
  79:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
  80:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
  81:                                 </TransformGroup>
  82:                             </RadialGradientBrush.RelativeTransform>
  83:                             <GradientStop Color="#FFB9D6F7"/>
  84:                             <GradientStop Color="#FF284B70" Offset="1"/>
  85:                         </RadialGradientBrush>
  86:                     </Setter.Value>
  87:                 </Setter>
  88:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
  89:             </Style>
  90:             <!--Red-->
  91:             <Style TargetType="Control">
  92:                 <Setter Property="Background">
  93:                     <Setter.Value>
  94:                         <RadialGradientBrush>
  95:                             <RadialGradientBrush.RelativeTransform>
  96:                                 <TransformGroup>
  97:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
  98:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
  99:                                 </TransformGroup>
 100:                             </RadialGradientBrush.RelativeTransform>
 101:                             <GradientStop Color="#FFFBB7B5"/>
 102:                             <GradientStop Color="#FF702828" Offset="1"/>
 103:                         </RadialGradientBrush>
 104:                     </Setter.Value>
 105:                 </Setter>
 106:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 107:             </Style>
 108:             <!-- Light Green -->
 109:             <Style TargetType="Control">
 110:                 <Setter Property="Background">
 111:                     <Setter.Value>
 112:                         <RadialGradientBrush>
 113:                             <RadialGradientBrush.RelativeTransform>
 114:                                 <TransformGroup>
 115:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 116:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 117:                                 </TransformGroup>
 118:                             </RadialGradientBrush.RelativeTransform>
 119:                             <GradientStop Color="#FFB8C0AC"/>
 120:                             <GradientStop Color="#FF5F7143" Offset="1"/>
 121:                         </RadialGradientBrush>
 122:                     </Setter.Value>
 123:                 </Setter>
 124:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 125:             </Style>
 126:             <!-- Yellow -->
 127:             <Style TargetType="Control">
 128:                 <Setter Property="Background">
 129:                     <Setter.Value>
 130:                         <RadialGradientBrush>
 131:                             <RadialGradientBrush.RelativeTransform>
 132:                                 <TransformGroup>
 133:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 134:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 135:                                 </TransformGroup>
 136:                             </RadialGradientBrush.RelativeTransform>
 137:                             <GradientStop Color="#FFFDE79C"/>
 138:                             <GradientStop Color="#FFF6BC0C" Offset="1"/>
 139:                         </RadialGradientBrush>
 140:                     </Setter.Value>
 141:                 </Setter>
 142:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 143:             </Style>
 144:             <!-- Indigo -->
 145:             <Style TargetType="Control">
 146:                 <Setter Property="Background">
 147:                     <Setter.Value>
 148:                         <RadialGradientBrush>
 149:                             <RadialGradientBrush.RelativeTransform>
 150:                                 <TransformGroup>
 151:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 152:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 153:                                 </TransformGroup>
 154:                             </RadialGradientBrush.RelativeTransform>
 155:                             <GradientStop Color="#FFA9A3BD"/>
 156:                             <GradientStop Color="#FF382C6C" Offset="1"/>
 157:                         </RadialGradientBrush>
 158:                     </Setter.Value>
 159:                 </Setter>
 160:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 161:             </Style>
 162:             <!-- Magenta -->
 163:             <Style TargetType="Control">
 164:                 <Setter Property="Background">
 165:                     <Setter.Value>
 166:                         <RadialGradientBrush>
 167:                             <RadialGradientBrush.RelativeTransform>
 168:                                 <TransformGroup>
 169:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 170:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 171:                                 </TransformGroup>
 172:                             </RadialGradientBrush.RelativeTransform>
 173:                             <GradientStop Color="#FFB1A1B1"/>
 174:                             <GradientStop Color="#FF50224F" Offset="1"/>
 175:                         </RadialGradientBrush>
 176:                     </Setter.Value>
 177:                 </Setter>
 178:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 179:             </Style>
 180:             <!-- Dark Green -->
 181:             <Style TargetType="Control">
 182:                 <Setter Property="Background">
 183:                     <Setter.Value>
 184:                         <RadialGradientBrush>
 185:                             <RadialGradientBrush.RelativeTransform>
 186:                                 <TransformGroup>
 187:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 188:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 189:                                 </TransformGroup>
 190:                             </RadialGradientBrush.RelativeTransform>
 191:                             <GradientStop Color="#FF9DC2B3"/>
 192:                             <GradientStop Color="#FF1D7554" Offset="1"/>
 193:                         </RadialGradientBrush>
 194:                     </Setter.Value>
 195:                 </Setter>
 196:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 197:             </Style>
 198:             <!--Gray Shade-->
 199:             <Style TargetType="Control">
 200:                 <Setter Property="Background">
 201:                     <Setter.Value>
 202:                         <RadialGradientBrush>
 203:                             <RadialGradientBrush.RelativeTransform>
 204:                                 <TransformGroup>
 205:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 206:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 207:                                 </TransformGroup>
 208:                             </RadialGradientBrush.RelativeTransform>
 209:                             <GradientStop Color="#FFB5B5B5"/>
 210:                             <GradientStop Color="#FF4C4C4C" Offset="1"/>
 211:                         </RadialGradientBrush>
 212:                     </Setter.Value>
 213:                 </Setter>
 214:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 215:             </Style>
 216:             <!--Blue-->
 217:             <Style TargetType="Control">
 218:                 <Setter Property="Background">
 219:                     <Setter.Value>
 220:                         <RadialGradientBrush>
 221:                             <RadialGradientBrush.RelativeTransform>
 222:                                 <TransformGroup>
 223:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 224:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 225:                                 </TransformGroup>
 226:                             </RadialGradientBrush.RelativeTransform>
 227:                             <GradientStop Color="#FF98C1DC"/>
 228:                             <GradientStop Color="#FF0271AE" Offset="1"/>
 229:                         </RadialGradientBrush>
 230:                     </Setter.Value>
 231:                 </Setter>
 232:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 233:             </Style>
 234:             <!-- Brown -->
 235:             <Style TargetType="Control">
 236:                 <Setter Property="Background">
 237:                     <Setter.Value>
 238:                         <RadialGradientBrush>
 239:                             <RadialGradientBrush.RelativeTransform>
 240:                                 <TransformGroup>
 241:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 242:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 243:                                 </TransformGroup>
 244:                             </RadialGradientBrush.RelativeTransform>
 245:                             <GradientStop Color="#FFC1C0AE"/>
 246:                             <GradientStop Color="#FF706E41" Offset="1"/>
 247:                         </RadialGradientBrush>
 248:                     </Setter.Value>
 249:                 </Setter>
 250:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 251:             </Style>
 252:             <!--Cyan-->
 253:             <Style TargetType="Control">
 254:                 <Setter Property="Background">
 255:                     <Setter.Value>
 256:                         <RadialGradientBrush>
 257:                             <RadialGradientBrush.RelativeTransform>
 258:                                 <TransformGroup>
 259:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 260:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 261:                                 </TransformGroup>
 262:                             </RadialGradientBrush.RelativeTransform>
 263:                             <GradientStop Color="#FFADBDC0"/>
 264:                             <GradientStop Color="#FF446A73" Offset="1"/>
 265:                         </RadialGradientBrush>
 266:                     </Setter.Value>
 267:                 </Setter>
 268:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 269:             </Style>
 270:             <!-- Special Blue -->
 271:             <Style TargetType="Control">
 272:                 <Setter Property="Background">
 273:                     <Setter.Value>
 274:                         <RadialGradientBrush>
 275:                             <RadialGradientBrush.RelativeTransform>
 276:                                 <TransformGroup>
 277:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 278:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 279:                                 </TransformGroup>
 280:                             </RadialGradientBrush.RelativeTransform>
 281:                             <GradientStop Color="#FF2F8CE2"/>
 282:                             <GradientStop Color="#FF0C3E69" Offset="1"/>
 283:                         </RadialGradientBrush>
 284:                     </Setter.Value>
 285:                 </Setter>
 286:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 287:             </Style>
 288:             <!--Gray Shade 2-->
 289:             <Style TargetType="Control">
 290:                 <Setter Property="Background">
 291:                     <Setter.Value>
 292:                         <RadialGradientBrush>
 293:                             <RadialGradientBrush.RelativeTransform>
 294:                                 <TransformGroup>
 295:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 296:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 297:                                 </TransformGroup>
 298:                             </RadialGradientBrush.RelativeTransform>
 299:                             <GradientStop Color="#FFDCDCDC"/>
 300:                             <GradientStop Color="#FF757575" Offset="1"/>
 301:                         </RadialGradientBrush>
 302:                     </Setter.Value>
 303:                 </Setter>
 304:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 305:             </Style>
 306:             <!--Gray Shade 3-->
 307:             <Style TargetType="Control">
 308:                 <Setter Property="Background">
 309:                     <Setter.Value>
 310:                         <RadialGradientBrush>
 311:                             <RadialGradientBrush.RelativeTransform>
 312:                                 <TransformGroup>
 313:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 314:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 315:                                 </TransformGroup>
 316:                             </RadialGradientBrush.RelativeTransform>
 317:                             <GradientStop Color="#FFF4F4F4"/>
 318:                             <GradientStop Color="#FFB7B7B7" Offset="1"/>
 319:                         </RadialGradientBrush>
 320:                     </Setter.Value>
 321:                 </Setter>
 322:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 323:             </Style>
 324:             <!--Gray Shade 4-->
 325:             <Style TargetType="Control">
 326:                 <Setter Property="Background">
 327:                     <Setter.Value>
 328:                         <RadialGradientBrush>
 329:                             <RadialGradientBrush.RelativeTransform>
 330:                                 <TransformGroup>
 331:                                     <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="2.09" ScaleY="1.819"/>
 332:                                     <TranslateTransform X="-0.425" Y="-0.486"/>
 333:                                 </TransformGroup>
 334:                             </RadialGradientBrush.RelativeTransform>
 335:                             <GradientStop Color="#FFF4F4F4"/>
 336:                             <GradientStop Color="#FFA3A3A3" Offset="1"/>
 337:                         </RadialGradientBrush>
 338:                     </Setter.Value>
 339:                 </Setter>
 340:                 <Setter Property="Template" Value="{StaticResource CustomLineDataPointTemplate}" />
 341:             </Style>
 342:         </datavis:StylePalette>
 343:     </navigation:Page.Resources>
 344:     <Grid x:Name="LayoutRoot" Background="White">
 345:         <chartingToolkit:Chart x:Name="Chart1" Title="Overall History"
 346:                                                Width="500" Height="500" StylePalette="{StaticResource MyCustomStylePalette}">
 347:             <chartingToolkit:Chart.Series>
 348:                 <chartingToolkit:LineSeries
 349:                             Title="First Line"
 350:                             IndependentValueBinding="{Binding EntryDate}"
 351:                             DependentValueBinding="{Binding Count}" />
 352:                 <chartingToolkit:LineSeries
 353:                             Title="Second Line"
 354:                             IndependentValueBinding="{Binding EntryDate}"
 355:                             DependentValueBinding="{Binding Count}" />
 356:                 <chartingToolkit:LineSeries
 357:                             Title="Third Line"
 358:                             IndependentValueBinding="{Binding EntryDate}"
 359:                             DependentValueBinding="{Binding Count}" />
 360:             </chartingToolkit:Chart.Series>
 361:         </chartingToolkit:Chart>
 362:     </Grid>
 363: </navigation:Page>

Text.xaml.cs

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Net;
   5: using System.Windows;
   6: using System.Windows.Controls;
   7: using System.Windows.Documents;
   8: using System.Windows.Input;
   9: using System.Windows.Media;
  10: using System.Windows.Media.Animation;
  11: using System.Windows.Shapes;
  12: using System.Windows.Navigation;
  13: using System.Windows.Controls.DataVisualization.Charting;
  14:  
  15: namespace TestProject.Views
  16: {
  17:     public class MyData
  18:     {
  19:         public MyData(int count, DateTime entryDate, string dataTitle, int growth)
  20:         {
  21:             Count = count;
  22:             EntryDate = entryDate;
  23:             DataTitle = dataTitle;
  24:             Growth = growth;
  25:         }
  26:  
  27:         public int Count { get; set; }
  28:         public DateTime EntryDate { get; set; }
  29:  
  30:         public string DataTitle { get; set; }
  31:         public int Growth { get; set; }
  32:  
  33:         public object DataPointTooltipText
  34:         {
  35:             get
  36:             {
  37:                 TextBlock tb = new TextBlock();
  38:                 tb.Inlines.Add(new Run { Text = "Title: " + DataTitle, FontWeight = FontWeights.Bold });
  39:                 tb.Inlines.Add(new LineBreak());
  40:                 tb.Inlines.Add(new Run { Text = "Updated: " + EntryDate.ToShortDateString() });
  41:                 tb.Inlines.Add(new LineBreak());
  42:                 if (Growth >= 0)
  43:                     tb.Inlines.Add(new Run { Text = "Growth: " + Growth.ToString(), Foreground = new SolidColorBrush(Colors.Green) });
  44:                 else
  45:                     tb.Inlines.Add(new Run { Text = "Neg Growth: " + Growth.ToString(), Foreground = new SolidColorBrush(Colors.Red) });
  46:  
  47:                 return tb;
  48:             }
  49:         }
  50:     }
  51:  
  52:     public partial class Test : Page
  53:     {
  54:         public Test()
  55:         {
  56:             InitializeComponent();
  57:         }
  58:  
  59:         // Executes when the user navigates to this page.
  60:         protected override void OnNavigatedTo(NavigationEventArgs e)
  61:         {
  62:             LoadData();
  63:         }
  64:  
  65:         public void LoadData()
  66:         {
  67:             List<MyData> line1 = new List<MyData>();
  68:             List<MyData> line2 = new List<MyData>();
  69:             List<MyData> line3 = new List<MyData>();
  70:  
  71:             line1.Add(new MyData(4, new DateTime(2008, 11, 10), "Test 1", 4));
  72:             line1.Add(new MyData(9, new DateTime(2008, 11, 12), "Test 2", 5));
  73:             line1.Add(new MyData(20, new DateTime(2009, 2, 13), "Test 3", 11));
  74:  
  75:             line2.Add(new MyData(1, new DateTime(2008, 12, 14), "Test A", 1));
  76:             line2.Add(new MyData(15, new DateTime(2008, 12, 20), "Test B", 14));
  77:             line2.Add(new MyData(10, new DateTime(2009, 1, 12), "Test C", -5));
  78:  
  79:             line3.Add(new MyData(7, new DateTime(2008, 12, 1), "Test 1.1", 7));
  80:             line3.Add(new MyData(13, new DateTime(2009, 1, 12), "Test 1.2", 6));
  81:             line3.Add(new MyData(16, new DateTime(2009, 2, 10), "Test 1.3", 3));
  82:  
  83:             LineSeries ls = Chart1.Series[0] as LineSeries;
  84:             ls.ItemsSource = line1;
  85:  
  86:             LineSeries ls2 = Chart1.Series[1] as LineSeries;
  87:             ls2.ItemsSource = line2;
  88:  
  89:             LineSeries ls3 = Chart1.Series[2] as LineSeries;
  90:             ls3.ItemsSource = line3;
  91:         }
  92:     }
  93: }

Let me know if you have any questions.  And please note that this is using Silverlight 3.0 and the latest toolkit.

Posted 24 April 09 10:55 by Tom | 2 Comments   
Filed under
Logging modules for ASP.NET (MVC) and also for Windows Azure

I was just reading through Scott Hanselman’s post about ELMAH and this sounds like a great idea.  Getting a easy to consume report of all of your exceptions is a wonderful thing, especially when you add in that you can get it as an RSS feed, an email or a web site.  You can check out ELMAH or read through his post to get a lot of details on it.

The web site looks like this:

This also got me thinking about Windows Azure and some of the logging that has been done already for that.  So I wanted to highlight one of the projects here and talk about what it does.  It is called Azure Application Monitor

This allows you to see how much time and memory your instance is using.  After you integrate this into your application, you will get a report like:

AzureMonitor.jpg

It is easy to add this to your application.

  1. Download the application
  2. Add the following line to your code.  If you are adding it to a WebRole, add it in the Page_PreRender() function.  Or in the Start() of a WorkerRole, changing it to WorkerRole below:
    Neudesic.Azure.AzureMonitor.Start("AppName", "WebRole");
  3. Be sure you have the TableStorageEndpoint configuration setting configured.
  4. Create a PerfCounterUpdateInterval configuration setting and set the value (the value is in ticks (1000 ticks = 1 second)
  5. Test and deploy your application

To view the data, you need to configure the AzureMonitor so that it points to your TableStorageEndpoint

As for what all it tracks, here is the list:

  • Application Name (you supply this in your code)
  • Role Name (you supply this in your code)
  • Machine Name
  • Process ID
  • Thread count
  • Handle count
  • Total processor time
  • User processor time
  • Private memory size
  • Non-paged memory size
  • Paged memory size
  • Paged system memory size
  • Peak paged memory size
  • Peak virtual memory size
  • Peak working set
  • Page file usage
  • Peak page file usage
  • Non-paged Pool Usage
  • Local machine time
  • Process local start time
  • It is rather easy to add more stuff to this as the code is available from the projects location.

    One a side-note, if you want to see what data you have in your Blobs, Queues and Tables, there is an updated version of Azure Storage Explorer available now.  From that site:

    The most current release of Azure Storage Explorer, version 2.0, has several improvements over the original version:

    1. The UI is WPF-based and has Outlook-style navigation.
    2. Multiple storage accounts are supported, and you can change your storage account details directly in the tool.
    3. In addition to text and byte views of items, blob items that are pictures can be viewed as images.

    Azure Storage Explorer 2.0 does not presently allow you to act on storage items. This capability is being considered for a future update.

    Let me know what you think or if you use any other tools for ASP.NET or Windows Azure.

    Any ASP.NET Debugging requests?

    With us starting to look forward to .NET 4.0, I started to think about the debugging story for ASP.NET and wondered if you had any requests for what you would like to see.

    Some of the things that are on my mind are ideas like:

    • Giving some kind of visual debugging experience to help people to troubleshoot ASP.NET problems more quickly.
    • Coming up with a better story for x64 dumps
    • Having some more automated commands to give information to users.

    I am not saying that any of these will be coming, but they are all things that I am interested in seeing and will be investigating.

    So what would you like to see for the future of the debugging experience?

    Posted 22 April 09 06:00 by Tom | 11 Comments   
    Filed under , ,
    MSDN updates

    Scott Hanselman did a great post about some of the new and upcoming features of MSDN that everyone should check out if you haven’t already.  You can read all his great details here.

    This got me thinking about MSDN and some of the new things that I have noticed.

    I think my favorite thing that is on MSDN is the ability for the community to add content to any page.  You can see this at the bottom of any page:

    image

    Clicking on that allows you to add a comment to the page.  You can also see just above that where you can add your own tags to the page.  These things can really help people get involved in the content on MSDN and help to change how things look on the site.

    And if you want to really add to the documentation, you can always check out the ASP.NET Wiki.

    So have you found any hidden gems?  Used any of the ones that Scott or myself have pointed out yet?

    Tell me what you think.

    Posted 20 April 09 08:52 by Tom | 2 Comments   
    Filed under , , ,
    More Posts Next page »

    Search

    This Blog

    Syndication

    Page view tracker