Welcome on
SoftLion.com
 
Softlion's web development tools
Show my IP: shows your real IP
Verify & validate XML and XHTML: verify, validate and locate errors in your XML and XHTML against XSD schemas
XML Pretty Print: pretty print your XML online
Online regular expression tester: build and validate your regular expression online
 
Currently interested in (among lots of other things) : Chumby

Sometimes you don’t have time to write javascript code, and if like me you don’t want to use microsoft ajax, you’ll end up creating a basic form.

 

It would be nice to have the equivalent of Ajax.BeginForm( ) but using the jQuery library.

Well now you have it.

 

 

Usage

 

Add the jquery ajaxform plugin to your site

See http://jquery.malsup.com/form/

 

In a partial control (called DemoAjaxForm here), add your form

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DemoFormModel>" %> <%@ Import Namespace="Mvc.Extensions" %> <% using(Html.UpdatePanel( "demoFormPost","home" ) ) { %> first name : <%: Html.EditorFor(m => m.FirstName) %> <%: Html.ValidationMessageFor(m => m.FirstName) %><br /> friend first name : <%: Html.EditorFor(m => m.FirstNameOfFriend) %> <%: Html.ValidationMessageFor(m => m.FirstNameOfFriend)%><br /> <br /> <% if(Model.PercentMatch.HasValue) { %> <div style="font-weight: bold; text-align: center; font-size: x-large">LOVE MATCH <%: Model.PercentMatch %>%</div> <br /> <% } %> <div><%: Html.ValidationSummary(true) %></div> <input type="submit" style="border: 1px solid #333" /> <% } %>

 

 

 

 

 

On your home controller, add this demoFormPost action

you can mark this action with [HttpPost] (you should)

 

 

        public ActionResult DemoFormPost(DemoFormModel model)
        {
            if (ModelState.IsValid)
            {
                model.FirstName.Trim();
                model.FirstNameOfFriend.Trim();
                model.CalcLoveMatch();
            }
            else
                ModelState.AddModelError("", "Fill all fields mark with a star");

            return PartialView("DemoAjaxForm", model);
        }

 

The model

    public class DemoFormModel
    {
        [Required(ErrorMessage="*")]
        [StringLength(20, ErrorMessage = "Max 20 caractères")]
        public string FirstName { get; set; }

        [Required(ErrorMessage = "*")]
        [StringLength(20, ErrorMessage = "Max 20 caractères")]
        public string FirstNameOfFriend { get; set; }

        public int? PercentMatch;


        public void CalcLoveMatch()
        {
            PercentMatch = new Random().Next(0,100);
        }

    }

 

Full code of the UpdatePanel Html helper

 

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

namespace Mvc.Extensions {

public static partial class HtmlExtensions { public static MvcUpdatePanel UpdatePanel(this HtmlHelper html, string action, string controller,

object routeValues = null, object htmlAttributes = null) { return new MvcUpdatePanel(html, action, controller, routeValues, htmlAttributes); } } public class MvcUpdatePanel : IDisposable { readonly MvcForm _form; readonly TextWriter _writer; bool _disposed; public MvcUpdatePanel(HtmlHelper html, string action, string controller, object routeValues,

object htmlAttributes) { _writer = html.ViewContext.Writer; RouteValueDictionary dicRouteValues = new RouteValueDictionary(routeValues); IDictionary<string,object> dicHtmlAttributes = new RouteValueDictionary(htmlAttributes); string formId; object oFormId; if (dicHtmlAttributes.TryGetValue("id", out oFormId)) formId = oFormId as string; else { formId = GenerateFormId(); dicHtmlAttributes.Add("id", formId); } //Render scripts RenderScripts(formId); //Render form _form = html.BeginForm(action, controller, dicRouteValues, FormMethod.Post, dicHtmlAttributes); } #region private private static string GenerateFormId() { return "mup" + new Random().Next(0, 1000000); } private void RenderScripts(string formId) { var tagBuilder = new TagBuilder("div"); tagBuilder.MergeAttribute("id", formId+"div"); _writer.Write(tagBuilder.ToString(TagRenderMode.StartTag)); tagBuilder = new TagBuilder("script"); tagBuilder.MergeAttribute("type", "text/javascript"); _writer.Write(tagBuilder.ToString(TagRenderMode.StartTag)); const string script = @" $(function(){{ $('#{0}').ajaxForm({{ target: '#{1}' }}); }});"; _writer.Write(String.Format(CultureInfo.InvariantCulture, script, formId, formId + "div")); _writer.Write(tagBuilder.ToString(TagRenderMode.EndTag)); } #endregion #region IDisposable Members /// <summary> /// Render end of form /// </summary> public void Dispose() { Dispose(true /* disposing */); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!_disposed) { _disposed = true; _form.Dispose(); _writer.Write("</div>"); } } #endregion }

}

...

Imagine you have this View, Model and this Action:

 

<% using (Html.BeginForm("MyActionPost")) { %›
         <%= Html.TextBoxFor(m => m.Price)%> <input type="submit" value="Save" />
 ‹% } %›
 

 

[HttpPost]
public ActionResult ProductEditSave(ProductModel product)
{
    product.PublicPrice += 5m;
    return View("ProductEditForm", product);
}

 

public class ProductModel { public int Price { get; set; } }

  

After a fist submit You'll expect to see "5" in the box, after a second you'll expect to see "10". Instead you'll always see "0".

 

Why ? This is by "design" in ASP.NET MVC ! The "ModelState" collection content, which contains originally posted values, takes precedence over the values passed in the Model object (product).

 

Reference and possible workarounds :
http://stackoverflow.com/questions/594600/possible-bug-in-asp-net-mvc-with-form-values-being-replaced/2498155#2498155

 

...

 

 

When you want to run a program as a service on Windows, the program have to be created specifically for this by implementing the Windows service interface.

 

When you don’t want to waste your time, or for any reason you could think of, there is a solution to run an exe as service. You can use the well known solution combining instsrv+srvany which works only on 32 bit windows, or NSSM which now works both on Win32 and x64.

 

Usage: type NSSM without argument:

 

image

 

Practical usage

 

For use in a single install.bat batch file without any user interaction:

 

rem stop and uninstall the service. Useful if the .bat is run twice.
sc stop YourServiceName
nssm remove YourServiceName confirm


rem install and configure the service
nssm install YourServiceName “%CD%\Your Service Name.exe” 
sc config YourServiceName start= auto depend= tcpip/LmHosts/Eventlog
sc description YourServiceName "Description of your service for display in service manager"
sc start YourServiceName 

 

In .bat files, %CD% is replaced with the current path.

 

Our service is configured to start at boot (start= auto), so we need to specify which service should be up before this service can start (depend= …)

 

Replace nssm by nssm-x64 if you run on 64 bits Windows.

 

Download

 

Download File - NSSM-2.1

 

References

 

Original NSSM (2006)

 

 

___

...

 

Simply modify the file “Create Stored Procedure (New Menu).sql” in:

 

C:\Program Files\Microsoft SQL Server\(version: 90, 100, …)\Tools\Binn\VSShell\Common7\IDE\SqlWorkbenchProjectItems\Sql\Stored Procedure

...

Recently a customer wanted me to evaluate the cost and fix all XSS holes in their website. Their security specialist found some holes using an obscure software only security specialists have and gave me his report and a list of webpage where it occurs.

After some digging I found there was one main hole - the same and on every page of their website. The hole was coming from the code of an UI component, a four years old version of the Telerik UI library for ASP.NET where XSS was not in the light.

 

My first report was to replace this component everywhere. As it would cost too much to the company, I was aimed to propose another solution : decompile the faulty assembly, find and fix the bug, and recompile it. It seemed easy. Helas ! This commercial library is obfuscated by Xenocode (a commercial obfuscator) which removes a lot of code unused by the CLR but necessary to the recompilation. So it was not an option.

 

THE SOLUTION

 

Then I came with an idea from my childhood where I was playing with raw asm and modified a tetris software because the blocs were not rotating in the correct direction …

Why not replace the faulting method pointer with the pointer of a fixed method dynamically in memory ? A lot of things run against this idea.One of them is that the code memory area is protected since Windows XP. And code injection does not work on 64 bit platforms at all.

Then I googled and found the graal… A post by Ziad Elmalki called “CLR Injection: Runtime Method Replacer”.

 

With a few lines of code I make it work with the web project.

I created a class “Demo.Fix” with a method InjectFix to be called in global.axax’s Application_Start event.

The first thing this method does is to check wether the assembly containing the code to fix is already loaded. If it is not it handles the AppDomain’s AssemblyLoad event.

 

using System; using System.Reflection; using System.Web; using System.Linq; using NativeAssemblerInjection; namespace Demo { public class Fix { /// <summary> /// Dynamically replace the failing method with our /// </summary> /// <remarks> /// First search if the assembly containing the class and method to replace is already /// loaded. If it is not already loaded, handle the AssemblyLoad event on the /// application domain. /// </remarks> public static void InjectFix() { var assembly = (from a in AppDomain.CurrentDomain.GetAssemblies() where a.FullName.Contains("FaultingAssemblyName") select a).FirstOrDefault(); if (assembly != null) DoReplace(assembly); else AppDomain.CurrentDomain.AssemblyLoad += CurrentDomain_AssemblyLoad; } /// <summary> /// Wait for the assembly containing the class and method to replace to be loaded. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> static void CurrentDomain_AssemblyLoad(object sender, System.AssemblyLoadEventArgs args) { if (args.LoadedAssembly.FullName.Contains("FaultingAssemblyName")) { DoReplace(args.LoadedAssembly); AppDomain.CurrentDomain.AssemblyLoad -= CurrentDomain_AssemblyLoad; } } /// <summary> /// Dynamically replace the failing method in <paramref name="assembly"/> by our /// own method. /// </summary> /// <param name="assembly">assembly containing the failing method</param> private static void DoReplace(Assembly assembly) { MethodBase oldMethod = assembly.GetType("FullNamespace.WebControls.x7fbe3d3b15648174")

.GetMethod("xe07c485b9dc80480", BindingFlags.NonPublic | BindingFlags.Instance); MethodBase newMethod = typeof(Fix).GetMethod("ReplacementMethod", BindingFlags.NonPublic | BindingFlags.Instance); MethodUtil.ReplaceMethod(newMethod, oldMethod); } /// <summary> /// Replacement method which corrects the behaviour of the original method /// </summary> /// <remarks> /// The signature must be the exact same as the original method. When called, the context /// (this) is the one from the original object, not the one from this class. /// </remarks> private string ReplacementMethod() { ... } } }

And it works both in 32 and 64 bits … amazing.

 

References

CLR Injection: Runtime Method Replacer

...

 

       public static string GetEmbeddedTextResource(string fullyQualifiedNameOfResource)
        {
            var assembly = Assembly.GetCallingAssembly();

            using (var reader = new StreamReader(assembly.GetManifestResourceStream(fullyQualifiedNameOfResource)))
            {
                //Automatic close/dispose
                return reader.ReadToEnd();
            }
        }

        public static byte[] GetEmbeddedBinaryResource(string fullyQualifiedNameOfResource)
        {
            var assembly = Assembly.GetCallingAssembly();
            byte[] result;

            using (var stream = assembly.GetManifestResourceStream(fullyQualifiedNameOfResource))
            {
                var reader = new BinaryReader(stream);
                result = reader.ReadBytes((int)stream.Length);
                reader.Close();
            }

            return result;
        }

 

...

 

In his blog, Pedro wrote a post showing how to bind a property to a static resource where the resource name is given by the binded property. But his solution needs WPF libraries and does not work in Silverlight.

This is the first way to write it which comes to mind. But it doesn’t work as StaticResource does not support Binding (it is static by nature).

<Image Source="{StaticResource {Binding AvailabilityStateResourceName}}" />

 

The solution I came with is elegant. It uses a custom converter to find the resource in the application resource dictionary. The binding source must be a string containing the name of the static resource.

 

<Image Source="{Binding AvailabilityStateResourceName, Converter={StaticResource StaticResourceConverter}}" />

 

To use it, declare a static resource refering to the converter like this:

<Application ...
             xmlns:shc="clr-namespace:Softlion.Silverlight.Shared.Converters;assembly=Softlion.Silverlight.Shared" 
             >
    <Application.Resources>
        <shc:StaticResourceConverter x:Key="StaticResourceConverter" />
        ...
    </Application.Resources>
</Application>

 

And the source code of the StaticResourceConverter which is simple and straightforward:

using System;
using System.Windows.Data;
using System.Windows;

namespace Softlion.Silverlight.Shared.Converters
{
    /// <summary>
    /// Enables a binding on a static resource in the application resource dictionary.
    /// Convert from a static resource name to a resource instance in the application resource dictionary.
    /// </summary>
    public class StaticResourceConverter : IValueConverter
    {
        #region IValueConverter Members
        /// <summary>
        /// Convert from a static resource name to a resource instance in the application resource dictionary.
        /// </summary>
        /// <param name="value">must be a reference to an existing resource in the application resource dictionary</param>
        /// <param name="targetType">defined by the resource</param>
        /// <param name="parameter">not used</param>
        /// <param name="culture">not used</param>
        /// <returns>A resource in the Application.Current.Resources dictionary</returns>
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (!(value is string))
                throw new ArgumentException("value");

            return Application.Current.Resources[value];
        }

        /// <summary>
        /// Not implemented, no use
        /// </summary>
        /// <param name="value"></param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
        #endregion
    }
}
...

Bryant Likes wrote a good post about choosing how to add a functionality to an existing control : behaviour, subclassing or attached property along with an example for each.

Behaviors vs Subclassing in Silverlight

 

Timmy Kokke wrote a detailed post about how to style a treeview.

http://geekswithblogs.net/tkokke/archive/2009/06/29/styling-a-treeview-in-silverlight-and-blend-3.aspx

...

In XAML you can not bind a property of type Color directly. I’m not sure why. Maybe because it is a structure (ie: value type).

You can bind a Brush instead :

 

[DataMember]
internal Color color;
public Brush DisplayColorBrush { get { return new SolidColorBrush(color); } }

 

Binding to a static color resource is working though:

<TextBlock.Foreground>
    <SolidColorBrush Color="{StaticResource UserOffersInfoColor}"/>
</TextBlock.Foreground>

 

<Application.Resources>
    <Color x:Key="UserOffersInfoColor">#FFE97F26</Color>
</Application.Resources>

 

Binding a Text property in a Run tag of a TextBlock tag doesn’t work either. You must bind to the Text property of the TextBlock tag instead.

<TextBlock Margin="6,3" FontWeight="Bold" FontSize="12">
    <Run Text="Chips: "/>
    <Run Text="{Binding ChipsRemaining}"/>
</TextBlock>

...

Or how the hell windows selects a network interface and an ip address from that interface (if it has more than one) for outbound packets ?

This excellent and easy to understand post from the Microsoft Network Team explain it all, along with differences between Win3K/XP and Win2K8/Vista.

Read it there: http://blogs.technet.com/networking/archive/2009/04/24/source-ip-address-selection-on-a-multi-homed-windows-computer.aspx

 

I repro it here:

Source IP address selection on a Multi-Homed Windows Computer

There is often confusion about how a computer chooses which adapter to use when sending traffic.

This blog describes the process by which a network adapter is chosen for an outbound connection on a multiple-homed computer, and how a local source IP address is chosen for that connection.

What is Source IP address selection

Source IP address selection is the process by which the stack chooses an IP address.

Windows XP and Windows Server 2003 are based on the weak host model.

When a Windows Sockets program binds to a socket, one of the parameters that is passed in the bind() call is the local (source) IP address that should be used for outbound packets. Most programs do not have any knowledge of network topology, so they specify IPADDR_ANY instead of a specific IP address in their bind() call. IPADDR_ANY tells the stack that the program is going to let the stack choose the best local IP address to use;

Windows XP behavior

KB175396 - Windows Socket Connection from a Multiple-Homed Computer

The TCP/IP component of all Microsoft Windows operating systems prior to Windows Vista is based on a Weak Host model. This model gives program developers the greatest amount of leeway when they design programs that use the network and are compatible with Microsoft products. This model also puts the responsibility of the behavior of the networking program on the developers, because the developers specify how the program accesses the TCP/IP stack and responds to incoming and outgoing frames.

On a computer that has one network adapter, the IP address that is chosen is the Primary IP address of the network adaptor in the computer. However, on a multiple-homed computer, the stack must first make a choice. The stack cannot make an intelligent choice until it knows the target IP address for the connection.

When the program sends a connect() call to a target IP address, or sends a send() call to a UDP datagram, the stack references the target IP address, and then examines the IP route table so that it can choose the best network adapter over which to send the packet. After this network adapter has been chosen, the stack reads the Primary IP address associated with that network adapter and uses that IP address as the source IP address for the outbound packets.

Example:
Source supplied in the call: IPADDR_ANY
Target IP:192.168.1.5
Route Table:
Nic 1 - 192.168.1.10/32
Nic 1 - 192.168.1.11/32
Nic 2 - 10.0.0.10/32
Nic 2 - 10.0.0.11/32
The chosen source IP:192.168.1.10
The chosen source NIC: Nic 1

If the program specifies a source IP address to use in the bind() call, that IP address is used as the source IP address for connections sourced from that socket. However, the route table is still used to route the outbound IP datagrams, based on the target IP address. As a result of this behavior, the source IP address may not be the one associated with the network adapter that is chosen to send the packets.

Example:
Source supplied in the call:10.0.0.10
Target IP:192.168.1.5
Route Table:
Nic 1 - 192.168.1.10/32
Nic 1 - 192.168.1.11/32
Nic 2 - 10.0.0.10/32
Nic 2 - 10.0.0.11/32
The chosen source IP:10.0.0.10
The chosen source Nic: Nic 1 <- Note this is not the Nic the source IP is on.

Summary

If a source IP is not given the Primary IP address of the adapter with a route that most closely matches the target IP address is used to source the packet and the adapter that the Primary IP is associated with is used as the source adapter.

If the source IP is specified the adapter that is used to send the packet is the one with a route that most closely matches the target IP address and this may not be the adapter that is associated with the source IP.

Windows Vista/Windows Server 2008 behavior

Windows Vista and later are based on the strong host model. In the strong host model, the host can only send packets on an interface if the interface is assigned the source IP address of the packet being sent. Also the concept of a primary IP address does not exist.

Similar to XP when if a program doesn't specify a source IP, the stack references the target IP address, and then examines the entire IP route table so that it can choose the best network adapter over which to send the packet. After the network adapter has been chosen, the stack uses the address selection process defined in RFC 3484 and uses that IP address as the source IP address for the outbound packets.

Example:

Source supplied in the call: IPADDR_ANY
Target IP:192.168.1.5
Route Table:
Nic 1 - 192.168.2.10/32
Nic 1 - 192.168.1.11/32
Nic 2 - 10.0.0.10/32
Nic 2 - 10.0.0.11/32
The chosen source IP:192.168.1.11
The chosen source NIC: Nic 1

If the program specifies a source IP address, that IP address is used as the source IP address for connections sourced from that socket and the adapter associated with that source IP is used as the source interface. The route table is searched but only for routes that can be reached from that source interface.

Example:
Source supplied in the call:10.0.0.10
Target IP:192.168.1.5
Route Table:
Nic 1 - 192.168.1.10/32
Nic 1 - 192.168.1.11/32
Nic 2 - 10.0.0.10/32
Nic 2 - 10.0.0.11/32
The chosen source IP:10.0.0.10
The chosen source Nic: Nic 2 <- Note this is the Nic the source IP is on.
Note: the packet would be sent to the default gateway associated with Nic 2.

RFC 3484 and Source IP address selection

The last thing I want to talk about is RFC 3484.

Even though RFC 3484 says it only applies to IPV6 in Windows implementations IPV4 does follow the same rules when possible.

Windows Source IP V4 address selection:
Rule 1 Prefer same address (applies)
Rule 2 Prefer appropriate scope (applies)
Rule 3 Avoid deprecated addresses (applies)
Rule 4 - Prefer home addresses - does not apply to IP v4
Rule 5 Prefer outgoing Interfaces (applies)
Rule 6 Prefer matching label - does not apply to IP v4
Rule 7 Prefer public addresses - does not apply to IP v4
Rule 8a: Use longest matching prefix with the next hop IP address. (not in RFC!)
"If CommonPrefixLen(SA, D) > CommonPrefixLen(SB, D), then prefer SA. Similarly, if
CommonPrefixLen(SB, D) > CommonPrefixLen(SA, D), then prefer SB. "
This says that the IP with the most high order bits that match the destination of
the next hop will be used.
Note: Rule 8 - Use longest matching Prefix is similar to rule 8a except the match
is with the destination IP address rather than the next hop IP address.

For example, consider the following addresses:

Client machine
IP Address
192.168.1.14 /24
192.168.1.68 /24
Default Gateway
192.168.1.127

The server will use the 192.168.1.68 address because it has the longest matching prefix.

To see this more clearly, consider the IP addresses in binary:

 

11000000 10101000 00000001 00001110 = 192.168.1.14 (Bits matching the gateway = 25)11000000 10101000 00000001 01000100 = 192.168.1.68 (Bits matching the gateway = 26)11000000 10101000 00000001 01111111 = 192.168.1.127
The 192.168.1.68 address has more matching high order bits with the gateway address 192.168.1.127. Therefore, it is used for off-link communication.
...

The Silverlight installation in all browsers is confusing, unsettling, and scary.

 

Update 09/2009 : you can get Microsoft's white paper and sample code about Silverlight installation.

Because of the numerous security warnings and lack of options other than to abort installation, you unfortunately get the false impression that Silverlight is a Trojan horse of sorts that "could infect and harm your computer with viruses and malicious code" with no apparent way to protect your computer other than agreeing to install it and hope for the best.

In addition you have to download a file then go find it then execute it.

It is a step that many people finds frustrating.

It will likely be a reason why they never get Silverlight installed on their machine.

And a reason I will lost them as customers.

 

Silverlight installation experience in FIREFOX 3:

  • see: the graphic button to "Install Microsoft Silverlight" (which I put in my object tag)
  • click the button
  • see: "you have chosen to install Silverlight 3.0" [save file] [cancel]
  • click [save file]
  • click [save]
  • (sit there wondering what happened)
  • ...eventually ask someone what to do or get lucky and right click download message and choose "open"
  • see: "silverlight 3.0.exe" is an executable file...may contain viruses...malicious code...harm your computer...use caution...are you sure?... [OK] [Cancel]
  • in spite of the fear that I am infecting my computer with "viruses and malicious code", I click [OK]
  • see: "Security warning...may potentionally harm your computer..." [Run] [Cancel]
  • fearfully click "Run"
  • says: "extracting files...Install Silverlight 3" one button: [Install Now]
  • click [Install Now]
  • says: "Silverlight is being installed on your computer", then shows checkbox "enable microsoft update (recommended) ... privacy statement..." [Next]
  • click [Next]
  • says: "Installation Successful, you may have to refresh the web page..." [Close]
  • click [Close]
  • go back to web page and click the refresh button on browser
  • I see the silverlight application, success.

Silverlight installation experience in INTERNET EXPLORER 6/7/8:

  • see: the graphic button to "Install Microsoft Silverlight" (which I put in my object tag)
  • click the button
  • see: "To help protect your security...blocked this site from downloading files to your computer" and "did you notice the information bar" [OK]
  • click [OK]
  • (sit there wondering what to do)
  • finally click the bar on top, see "what's the risk?" click "download file" anyway
  • see: "Security warning...may potentionally harm your computer..." [Run] [Cancel]
  • click [Run]
  • watch it download, 15 seconds
  • see: "Security warning...can potentially harm your computer" [Run] [Don't Run]
  • click [Run]
  • says "Install Silverlight 3" one button: [Install Now]
  • click [Install Now]
  • says: "Silverlight is being installed on your computer", then shows checkbox "enable microsoft update (recommended) ... privacy statement..." [Next]
  • click [Next]
  • says: "Installation Successful, you may have to refresh the web page..." [Close]
  • click [Close]

Someone answered:

Well, considering you now know what steps the user is going to have to do you could create a help page for the user. Granted, it isn't the best thing (a simplified install experience would be better, obviously) but at least the user would be able to easily find steps on what is going on.

Source: http://stackoverflow.com/questions/523596/how-to-improve-the-much-to-be-desired-silverlight-installation-experience

...

 

This has been fixed in RTM version : in the "build action" property of all files which are in the SampleData folder a "DesignTimeOnly" value is set so sample data is no compiled in your release project (if you unticked the "Enable when running Application" choice in the datasource property in Blend 3).

 

Update: it is not fixed at all ! The .cs file is still set to "compile" (as the referenced sample data is still in app.xaml this makes sense). This workaround is still needed.

 

In Blend 3 there is a userful feature called sample data which helps design UIs binded to data not currently existing.

 

When using this feature, blend adds a “SampleData” folder in your silverlight project, and new XAML files with their associated codebehind (.xaml.cs). It also modifies your App.xaml to reference the sample data class and creates a new global instance of this xaml.

 

When switching to release mode, your xap file will grow bigger than needed. So in the xaml.cs file there is a conditional compilation symbol which can be define in ‘project/properties/build’ tab to minimize the content of the cs file: DISABLE_SAMPLE_DATA

 

The default .xaml.cs generated by blend 3 contains :

 

#if DISABLE_SAMPLE_DATA
    internal class BoardInfosDataSource { }
#else

 

But when in release mode, the compiler removes all non public unused objects. And your silverlight application will throw an errror (if you use asp:Silverlight you won’t see the error just a blank screen. Use the object tag with onerror set to your javascript instead. See MSDN for more infos.).

 

To correct this set the class public:

 

#if DISABLE_SAMPLE_DATA
    public class BoardInfosDataSource { }
#else

 

...

I’ve upgraded the Syntax Highlighter plugin from Tim Bellette to work with ScrewTurn wiki v3 RC1.

 

Download the

Download the

 

See Tim Bellette blog doc for how to use it.

 

Cheat Sheet

 

<code {language}>…</code>

 

{language}: C# xml … + 23 other languages

 

eg: <code C#>…</code>

...

LINQ is an intuitive and powerful extension to .NET. But it misses a useful method to be able to write code as compact as possible. Look at this code:

   1: var list = from xitem in (XDocument.Parse(xmlText).Root.FirstNode as XElement).Elements()
   2:            select new { keyText = xitem.Name.LocalName, keyValue = xitem.Value };
   3:  
   4: foreach( var keyPair in list )
   5: {
   6:     ... do some action ...
   7: }

 

What if you could write a single line instead of the foreach loop:

   1: list.Action( keyPair => s.Append(keyPair.keyText + "=" + keyPair.keyValue) );

 

Well this is now possible if having this extension method in your project:

   1: public static class LINQExtension
   2: {
   3:         public static void Action<T>(this IEnumerable<T> list, Action<T> action)
   4:         {
   5:             foreach (var t in list)
   6:                 action(t);
   7:         }
   8:  
   9:         public static string Append(this IEnumerable<string> list)
  10:         {
  11:             StringBuilder sb = new StringBuilder();
  12:             list.Action(s => sb.Append(s));
  13:             return sb.ToString();
  14:         }
  15: } 

 

Next is an example usage of these methods to compute the MD5 hash of any string:

   1: // Compute the MD5 hash of a string
   2: public string ComputeMD5Hash( string signatureContent )
   3: {
   4:       StringBuilder signature = new StringBuilder();
   5:       MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(signatureContent)).Action(b => signature.AppendFormat("{0:x2}", b));
   6:       return signature.ToString();
   7: }

Of course it is a bad example, as there is a much more efficient way to do it:

 

return BitConverter.ToString(SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(signatureContent)));

 

 

...

The standard ASP.NET 2/3/3.5 SP locks the ASPStateTempSessions table for a long time, which in turns locks running applications. This becomes very useful when SQL Server Agent jobs (especially xxx_Job_DeleteExpiredSessions) were disabled for some time for some reason.

A better SP looks like this:

   1: SET ANSI_NULLS ON
   2: GO
   3: SET QUOTED_IDENTIFIER ON
   4: GO
   5:  
   6: ALTER PROCEDURE [dbo].[DeleteExpiredSessions]
   7: AS
   8:  
   9: DECLARE @now datetime
  10: SET @now = GETUTCDATE()
  11: declare @count int
  12: set @count = 1
  13:  
  14: set ROWCOUNT 1000
  15: while @count != 0
  16: begin
  17:     begin tran
  18:     DELETE [Softlion].dbo.ASPStateTempSessions
  19:         WHERE Expires < @now
  20:     set @count = @@ROWCOUNT
  21:     commit
  22: end
  23: set ROWCOUNT 0
  24:  
  25: RETURN 0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    

You may also add the hint WITH (ROWLOCK) on the delete statement to be sure no lock are set on a range which may contains rows currently used by the application.

...
...

Yesterday I found what can easily be named THE bug of the year. Even I can named it the biggest bug in the last 4 years. It affects nearly all of our past projects with different degrees of impact.

It is documented in MSDN as a feature in a small note in the description of the SqlConnection.BeginTransaction .NET method (see references below).

Let me explain the context first so you really understand the bug and how to fix it.

 

Imagine you have a web application created using ASP.NET, and a SQL Server data storage.

To construct a web page, your ASP.NET code will query 3 times data on the SQL server.

The 1st and 2nd queries are executed inside a transaction which runs under a non default isolation level  READ UNCOMMITTED.

The last query is executed alone, completely separated from the previous ones. This query is using the with(READPAST) option in one of its statement.

If you run  your application, you'll see a nice .NET error page telling you that READPAST can not be used in this transaction isolation level (it does not tell you which).

 

So first you debug your application and you check in which isolation level you are. This is easily done using this query:

 

select
      transaction_isolation_level,
      last_request_start_time,
      *
from sys.dm_exec_sessions

 

And you'll find what ? That instead of being the default READ COMMITED isolation level, the query is executed under READ UNCOMMITTED !

Have you guessed why already ? Well it is because of the "feature" of the transaction handling combined with the feature of the SQL connections pooling implemented in ADO.NET.

Connection pooling makes .NET reuse existing SQL connections which is an efficient way to use this network resource.

In our case,  a connection is created by the first query and is used by the whole transaction. When closed by code, the connection is not closed but moved to the connections pool (with a TTL so it won't last forever if not used).

For the third query the code creates a new connection, which the library converts to a 'get the opened connection from my connections pool'.

 

Now read the note from MSDN :

After a transaction is committed or rolled back, the isolation level of the transaction persists for all subsequent commands that are in autocommit mode (the SQL Server default). This can produce unexpected results, such as an isolation level of REPEATABLE READ persisting and locking other users out of a row. To reset the isolation level to the default (READ COMMITTED), execute the Transact-SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED statement, or call SqlConnection..::.BeginTransaction followed immediately by SqlTransaction..::.Commit. For more information on SQL Server isolation levels, see "Isolation Levels in the Database Engine" in SQL Server 2005 Books Online.

 

What happens here is that the first connection is returned to the pool but the transaction isolation level is not reset to its default value. So our 3rd query will execute and fail unexpectedly because the with(READPAST) option is not compatible with an isolation level equals to read uncommited.

 

How to fix this ?

Before closing your connection, after a transaction where you know you change the default isolation level, just execute this code wich resets it to the default READ COMMITED or wathever you set to be the default:

myConnection.BeginTransaction().Commit();

 

 

References:

SqlConnection.BeginTransaction .NET method and the note explaining the "feature".

.NET SQL connection pooling (ADO.NET 2.0)

 

...

A modern way to put a list of IDs in a stored procedure parameter is to type the parameter as xml (instead of the conventional CSV like varchar). With the nodes() method you can inner join directly the xml 'table' with one of your database table without first filling a temporary table. And building the xml fragment with LINQ TO XML (ie: XDocument class) is a piece of cake.

 

If these ids are C# Guids (or tsql uniqueidentifier) and you optimize your query (like msdn tells you), you may fall in the uppercase/lowercase trap.

 

-- Optimized query (working)
select * from MyGames a
left join MyUsers b on a.Winners.exist('//winner[upper-case(@userId)=sql:column("b.UserId")]')=1

 

In this XQuery optimized comparison, T-SQL converts a uniqueidentifier to an upper case string. The Winners xml column has been filled using C# XDocument, which uses by default the C# method Guid.ToString() to convert a guid ... to lowercase.

 

So we have SQL converting by default uniqueidentifier to uppercase, and C# converting by default Guid to lowercase.
If you rely on defaults any comparison done between uniqueidentifier in this cutting edge xml/sql technology then it will not work.



Notes:
The xml type is a new native type available since SQL Server 2005. I use it essentially to simplify the model for 1-N relations by storing ids of the N table in a field of the 1 table instead of creating this dummy relationship table I always hated. This without giving up performance, as long as you setup the new special xml indexes for the xml typed field and provide the XSD schema to SQL. See references below for the full documentation.


A uniqueidentifier is a 16 bytes (128 bits) value which is used by the default implementation of User/Membership provider of the ASP.NET framework for all unique IDs.



With the xml data type, SQL 2005 introduced "methods" that can be used to efficiently query the xml data and use it as if it was a normal table : exists(..), value(..), ...
A common parameter for these methods is an XQuery string, where XQuery is a SQL Server specific language based on XPath, with at least 2 useful efficients extensions in the sql namespace:
sql:variable(..) which is replaced by the value of an existing variable
sql:column(..) which is replaced by the value of any table row available in the t-sql query




References:
SQL Server xml data type

XML indexes
XML type query methods
XQuery language reference

 

...

Today I created my first Silverlight 2 application and my first control : a simple ball. The aim was to evaluate how easy it is to create a Silverlight 2 application and a control, and to test SL display smoothness and speed.

The ball has an update method which is called for each ball instance at most every 25ms through the application's CompositionTarget.Rendering event. I don't know if it is the best way to do procedural animation, but it sure is a way.

This event fires before each frame is rendered, like the well known frame technics in Flash. But unlike Flash, the frame rate is not constant and depends on the running machine and the silverlight application load.

I may try later using a worker thread and the InvalidateArrange() call combination. 

 

This application displays the framerate computed over the last second, creates a new ball object each time the mouse is moved over its window, and displays the total number of balls created and animated.

 

If you take a look at the result, you'll immediatly see that frame displays are not synchronized with the graphic card's vertical sync, which results in ugly breaks in the animation.

The animation slows when the mouse is moved over it : that confirms what the documentation says about the CompositionTarget.Rendering event, so we can not complain Sealed

 

 

 

Please post your FPS, ball count, and OS in the comment section.Try to get exactly 1000 or 2000 balls.

 

References

How to declare a Custom User Control from a XAML page

This app uses a fixed version of PathTextBlock silverlight control to display a text with a stroke (in fact this control converts text to glyphs which does support stroke and fill).

Configure IIS for hosting Silverlight 2 applications (don't forget to stop/start your IIS server after)

Silverlight 2 control lifecycle

 

 

...

La conférence pour développeurs professionnels de Microsoft s'est terminée le 30 octobre dernier, avec des informations sur le C#4 qui va bentôt sortir et même la version suivante (session de Anders Hejlsberg).

Résumé:

 

C#1 a été initié en 1998, avec la création du MSIL et de la gestion de la mémoire automatique. La version 1.1 a apporté des modifications majeures pour rendre le language utilisable.

 

C#2 a corrigé toutes les erreurs du C#1 et du MSIL1 en apportant le plus qui existait encore dans le C++ à savoir les generics (templates en C++).

 

C#3 (et 3.5) a amélioré le compilateur pour supporter LINQ, une syntaxe ressemblant au SQL pour manipuler facilement des listes. C'est la première fois qu'un langage réussit cette prouesse et je crois pour ma part que ca a été une avancée majeure dans les languages de développements qui met à la traine Java et C++. LINQ intervient également dans une stratégie d'optimisation automatique du logiciel pour le multicore. Le 3.5 intègre également les fonctions anonymes qui ont fait la force du javascript et du PHP, et le type delegate qui représente une fonction typée (très utilisé en C++ sous forme de pointeur typé).

 

C#4, avec Visual Studo 2010, pompe encore quelques goodies à Javascript avec le nouveau type "dynamic" (pratique pour COM) qui représente un objet non typé (eh oui ca peux faire rire !) sur lequel on peux appeler des propriétés ou méthodes non connues à la compilation. Ecrire des macros Excel ou Word en C# ou .NET va peux être devenir une réalité et enfin remplacer le très vieux VBA. Dommage que cela arrive si tard ! C#4 ajoute également les paramètres de fonction optionnels (merci C++) et nommés (extension pratique qui manque à C++), ainsi qu'une amélioration des generics et des delegates utile au compilateur.

 

Enfin la version suivante (C# 4.5 ?) devrait intégrer le "Compiler as a Service" - une API pour utiliser le compilateur dans le code. Ca permet d'exécuter des bouts de code dynamiquement comme pour la fonction Eval du javascript. Ca va aussi permettre de poubelliser/remplacer le language bizarre de PowerShell. Bon ok c'était déjà possible avec la version 1.1, mais la ca devrait être encore plus facile.

 

Ex d'objet dynamic:
dynamic monObjet1 = { Code=1, Name="Parapluie" };
dynamic monObjet2 = { Code=2, Name="Casquette" };
DisplayObject( monObjet1 );
DisplayObject( monObjet2 );
...
void DisplayObject( dynamic o )
{
  Console.WriteLine( String.Format( "Code: {0}, Name: {1}", o.Code, o.Name ) );
}

 

Ex de fonction avec paramètres optionnels : (existe depuis ... 15ans dans C++ ?)

public void SaveAs( string fileName, Encoding encoding = Encoding.UTF8 ) { ... }

 

Ex de fonctions avec paramètres nommés: (n'existe pas dans C++)

SaveAs( fileName: "monFichier.xml", encoding: Encoding.ASCII );

 

Référence:

La vidéo de la session sur C#4

Visual Studio 2010 et .NET Framework 4 CTP

Un résumé des sessions du PDC par Thomas Lebrun

...