Jquery with mvc3

JQuery has been always an interesting topic, but I didn’t find time to try it… looking into MVC3 finally I get in touch with it.

I succeded in using asp.net engine together with MVC3 in the same web app.

For some reason global.asax events didn’t fire up, but I found that deleting the file and adding back fixes this problem.PaceSpeedCalculatorModel

I tried to reuse asp.net master pages, without success. I gave up when I got an error saying that System.Web.Mvc.ViewMasterPage doesn’t derive from the correct class. I‘ll wait when this will be natively supported (MVC4?) or when someone else will discover a workaround.

The solution proposed works fine for reusing aspx master pages in a razor view (extensions methods does the magic!!!)

The goal I want to achieve is a simple conversion between pace and speed (pace is how much minutes and seconds I takes to cross 1km, speed is in km/h).

So 3 textbox minutes, seconds, speed.

I created a model for this, with appropriate annotations.

PaceSpeedCalculatorModel.cs
  1. namespace FitCalc.Models
  2. {
  3.     public class PaceSpeedCalculatorModel
  4.     {
  5.         [Required]
  6.         [StringLength(2, MinimumLength = 1)]
  7.         [Display(Name = "paceMinutes")]
  8.         [RegularExpression(@"[0-9]{1,2}", ErrorMessage = "Minutes must be in the range 00-99")]
  9.         [ScaffoldColumn(false)]
  10.         [DataType(DataType.Text)]
  11.        
  12.         [Range(0,99)]
  13.         public string paceMinutes { get; set; }
  14.  
  15.         [Required]
  16.         [StringLength(2, MinimumLength = 1)]
  17.         [Display(Name = "paceSeconds")]
  18.         [RegularExpression(@"[0-9]{1,2}", ErrorMessage = "Seconds must be in the range 00-59")]
  19.         [ScaffoldColumn(false)]
  20.         [DataType(DataType.Text)]
  21.         [Range(0, 59)]
  22.         public string paceSeconds { get; set; }
  23.  
  24.         [Required]
  25.         [StringLength(2, MinimumLength = 1)]
  26.         [Display(Name = "speed")]
  27.         [ScaffoldColumn(false)]
  28.         [DataType(DataType.Text)]
  29.         [Range(0,99)]
  30.         public string speed { get; set; }
  31.  
  32.  
  33.     }
  34. }

Well, not really appropriate… It would be better if the DataType was an integer value for minutes and seconds, but I didn’t find the corresponding value (maybe custom, but for now Text is enough).

Created the controller. I wanted to calculate values either by posting the form data and by doing calculation as you type.

CalculatorController.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using FitCalc.Models;
  7.  
  8. namespace FitCalc.Controllers
  9. {
  10.     public class CalculatorController : Controller
  11.     {
  12.         //
  13.         // GET: /Calculator/
  14.         private static PaceSpeedCalculatorModel _paceSpeed = new PaceSpeedCalculatorModel();
  15.  
  16.  
  17.         public ActionResult Index()
  18.         {
  19.             //_paceSpeed.paceMinutes = "1";
  20.             //_paceSpeed.paceSeconds = "0";
  21.  
  22.             return this.RazorView(_paceSpeed);
  23.         }
  24.         [HttpPost]
  25.         public ActionResult Index(PaceSpeedCalculatorModel pscm)
  26.         {
  27.             _paceSpeed = pscm;
  28.  
  29.  
  30.             return RedirectToAction("Index");
  31.         }
  32.  
  33.         [HttpPost]
  34.         public ActionResult PaceToSpeed(PaceSpeedCalculatorModel pscm)
  35.         {
  36.             if (pscm.speed == null)
  37.                 pscm.speed = RunningCalc.PaceToSpeed(new RunningTime(pscm.paceMinutes, pscm.paceSeconds)).ToString();
  38.             else
  39.             {
  40.                 double speed = 0;
  41.                 RunningTime rt = null;
  42.                 if (double.TryParse(pscm.speed, out speed))
  43.                     rt = RunningCalc.SpeedToPace(speed);
  44.                 pscm.paceMinutes = rt.Minutes.ToString();
  45.                 pscm.paceSeconds = rt.Seconds.ToString();
  46.             }
  47.             return this.View(pscm);
  48.  
  49.         }
  50.     }
  51. }
For the first the Action is “Index”. Being an asp, asp.net folk it takes a moment to understand how the data posted by the form is handled. Normally there will be an Index.asp with the form that post to a Calculate.asp. With MVC the action is the same, differentiated by the “HttpPost” attribute. The first time (Index.asp) the browser uses a GET and calls “public ActionResult Index()”. When you submit the form (Calculate.asp) the browser uses a POST activating the “public ActionResult Index(PaceSpeedCalculatorModel pscm)” method. MVC runtime fills automagically the PaceSpeedCalculatorModel parameter, matching POST payload names with class ones.

Creating the view based on the annotated model class is really easy and everything went smooth.

Index.cshtml
  1. @model FitCalc.Models.PaceSpeedCalculatorModel
  2. <script src="../../Scripts/jquery-1.4.4-vsdoc.js" type="text/javascript"></script>
  3. <script src="../../Scripts/json2.js" type="text/javascript"></script>
  4. @{
  5.     ViewBag.Title = "Index";
  6.     Layout = "~/Views/Shared/_Layout.cshtml";
  7. }
  8. <script type="text/javascript">
  9.    
  10.     $(InitPage);
  11.     function InitPage()
  12.     {
  13.     
  14.  
  15.           var paceSpeed = { paceMinutes: $("#paceMinutes").val(),
  16.                         paceSeconds: $("#paceSeconds").val(),
  17.                         speed: $("#speed").val()
  18.                     };
  19.  
  20.         $(function ()
  21.         {   setTimeout(checkSearchChanged, 0.1);
  22.         });
  23.  
  24.         function checkSearchChanged()
  25.         {   var currentPaceSpeed = { paceMinutes: $("#paceMinutes").val(),
  26.                 paceSeconds: $("#paceSeconds").val(),
  27.                 speed: $("#speed").val()
  28.             };
  29.             if (true &&
  30.                 ((currentPaceSpeed.paceMinutes)
  31.                 && (paceSpeed.paceMinutes)
  32.                 && currentPaceSpeed.paceMinutes != paceSpeed.paceMinutes
  33.                  && currentPaceSpeed.paceMinutes != ''
  34.                   && currentPaceSpeed.paceMinutes > 0
  35.                   )
  36.                 || ((currentPaceSpeed.paceSeconds) && currentPaceSpeed.paceSeconds != paceSpeed.paceSeconds && currentPaceSpeed.paceSeconds != '' && currentPaceSpeed.paceSeconds > -1)
  37.                 || ((currentPaceSpeed.speed) &&  currentPaceSpeed.speed != paceSpeed.speed && currentPaceSpeed.speed != '' && currentPaceSpeed.speed.replace(',','.') > 0)
  38.  
  39.                 )
  40.             {
  41.                 //alert("ok inizioe");
  42.                 if ((currentPaceSpeed.speed) && (paceSpeed.speed != null) && currentPaceSpeed.speed != paceSpeed.speed)
  43.                 {
  44.                     // if speed changed
  45.                     paceSpeed =
  46.                     { paceMinutes: null,
  47.                         paceSeconds: null,
  48.                         speed: $("#speed").val()
  49.                     };
  50.                 }
  51.                 else
  52.                 {
  53.                     paceSpeed =
  54.                     { paceMinutes: $("#paceMinutes").val(),
  55.                         paceSeconds: $("#paceSeconds").val(),
  56.                         speed: null
  57.                     }
  58.                 }
  59.  
  60.                 var jsonString = JSON.stringify(paceSpeed);
  61.                 $.ajax(
  62.                 {
  63.                     url: '/Calculator/PaceToSpeed',
  64.                     type: "POST",
  65.                     data: jsonString,
  66.                     dataType: "json",
  67.                     contentType: "application/json; charset=utf-8",
  68.                     dataFilter: function(data, dataType) {
  69.                     if (data.indexOf("<!-") > 0)
  70.                         {
  71.                             //alert(data.indexOf("<!-"));
  72.                             //alert(data.substring(0, data.indexOf("<!-")));
  73.                             return data.substring(0, data.indexOf("<!-"));
  74.                         }
  75.                         else
  76.                             return data;
  77.                     },
  78.                     success: function (objResult)
  79.                     {
  80.                         var paceSpeedResult = objResult;
  81.                         
  82.                         $("#speed").val(objResult.speed);
  83.                         $("#paceSeconds").val(objResult.paceSeconds);
  84.                         $("#paceMinutes").val(objResult.paceMinutes);
  85.                         paceSpeed = { paceMinutes: $("#paceMinutes").val(),
  86.                             paceSeconds: $("#paceSeconds").val(),
  87.                             speed: $("#speed").val()
  88.                         };
  89.                         setTimeout(checkSearchChanged, 0.1);
  90.                     },
  91.                     error: function (objResult)
  92.                     {
  93.                         alert("errore" + objResult);
  94.                         setTimeout(checkSearchChanged, 0.1);
  95.                     }
  96.                 });   
  97.             }
  98.             else
  99.             {
  100.                 setTimeout(checkSearchChanged, 0.1);
  101.             }
  102.         }
  103.  
  104.     }
  105. </script>
  106. <h2>
  107.     Index</h2>
  108. @using (Html.BeginForm())
  109. {
  110.     @Html.ValidationSummary(true)
  111.     <fieldset>
  112.         <legend>PaceSpeedCalculatorModel</legend>
  113.         <div class="editor-label">
  114.             @Html.LabelFor(model => model.paceMinutes)
  115.         </div>
  116.         <div class="editor-field">
  117.             @Html.EditorFor(model => model.paceMinutes)
  118.             @Html.ValidationMessageFor(model => model.paceMinutes)
  119.         </div>
  120.         <div class="editor-label">
  121.             @Html.LabelFor(model => model.paceSeconds)
  122.         </div>
  123.         <div class="editor-field">
  124.             @Html.EditorFor(model => model.paceSeconds)
  125.             @Html.ValidationMessageFor(model => model.paceSeconds)
  126.         </div>
  127.         <div class="editor-label">
  128.             @Html.LabelFor(model => model.speed)
  129.         </div>
  130.         <div class="editor-field">
  131.             @Html.EditorFor(model => model.speed)
  132.             @Html.ValidationMessageFor(model => model.speed)
  133.         </div>
  134.         <p>
  135.             <input type="submit" value="Save" />
  136.         </p>
  137.     </fieldset>
  138. }
  139. <div>
  140.     @Html.ActionLink("Back to List", "Index")
  141. </div>

Doing calculation as you type it’s a little bit tricky. I found Scott Allen “jQuery for the .NET Developer” video very interesting. Then followed Scott post when he talks about using jquery and JSON to post data to the server. In the sample it wasn’t clear where the JSON.stringify method comes from. To make it work I downloaded Json2.js from www.json.org (well, from github because Json.org wasn’t available). Here the solution found in comments.

With keypress event you didn’t catch all modification to the textbox (say mouse paste), so I switched to this solution.

With the previous view, I got what I was looking for. I send and receive JSON data to the PaceToSpeed Action. In the view I send the model JSON encoded with raw HTML.

@Html.Raw(@Json.Encode(@Model))

My hoster append some ad to the HTML stream, so I have to filter it when received by the ajax call using the dataFilter method.

Upgrading to asp.net 4.0 & MVC 3

Time to get my hand dirty with some new web app.

I setup a new account on somee, that hosts asp.net 4 apps for free.

Uploaded a fresh new “hello world” app created by Visual studio 2010.

Wanting to make something with asp.net and MVC I configured the web app to also support MVC 3 following instruction foun here. Nothing fancy, only few steps to get things done.

To ease this process I created another web app configured as MVC 3 and compared the two.

So I added references to appropriate assembly (some assembly not found directly, but for System.Web.Mvc.dll under C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC 3\Assemblies\System.Web.Mvc.dll).

Then modified web.config adding relevant tags.

Same thing for global.asax.cs, registering filters into the app.

Also modify the .csproj file and especially add proper ProjectTypeGuids i.e.

<ProjectTypeGuids>{E53F8FEA-EAE0-44A6-8774-FFD645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

To start quickly I followed the pluralsight training video as suggested by Scott Guthrie.

In the /Controllers dir there’s (guess what..) the controllers. Named with the name we choose terminating with a “Controller” string.

Views are stored under the /Views dir, grouped in a dir named as the controller.

So if we want to create a “Hello” controller the directory structure will be:

/Controllers/HelloControlles

/Views/Hello/Index.cshtml

HelloController.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6.  
  7. namespace FitCalc.Controllers
  8. {
  9.     public class HelloController : Controller
  10.     {
  11.         //
  12.         // GET: /Hello/
  13.  
  14.         public ActionResult Index()
  15.         {
  16.             ViewBag.Message = "Welcome to ASP.NET MVC!";
  17.             return View();
  18.         }
  19.  
  20.     }
  21. }

.cshtml is the razor file implementing the view.

The URL for this view is /Hello/Index.

Install a dictionary in Windows Live Writer Beta 3

Many source for this problem around…

http://veroblog.wordpress.com/2007/08/28/using-british-english-spelling-in-windows-live-writer/

I found a way easier to solve the problem (it works for italian dictionary).
I have WLW 14.0.5025.904 under Vista.
In C:\Users\<my user>\AppData\Local\Microsoft\Windows Live Mail\Proof\prf0010\7 (the last two directories may change for different locale) copy the 3 files (.lex .dll .ini).
For italian the name is mssp7it .
Maybe not all are necessary... I didn't investigate!
Paste into C:\Program Files\Windows Live\Writer\Dictionaries.
Restart WLW ...now in Tools->Options->Spelling you should see a new entry (Italian in my case).

Hope this helps

Custom drop target

The automatically generated designer in DSL assumes that you have to put the shape on the surface and then eventually connect to others.

Statements, in microbasic, are executed sequentially so I want the designer to attach my shapes to one previously placed, dropping it in the link between two shapes.

To drive the shapes drop behaviour I have to modify where the shapes are allowed to be dropped.

Setting the attribute UsesCustomAccept does this (or at least I hope!!!).

<?xml version="1.0" encoding="utf-8"?>
<Dsl dslVersion="1.0.0.0" Id="bd36672a-93b9-4dce-82f8-2551432eb244" Description="Description for myns.Language1.Language1" ...>
  <Classes>
    <DomainClass Id="3a3a6bfd-90ef-4418-91a7-3792d2201167" Description="The root in which all other elements are embedded. Appears as a diagram." ....>
      <ElementMergeDirectives>
        <ElementMergeDirective UsesCustomAccept="true">
          <Notes>Creates an embedding link when an element is dropped onto a model. </Notes>
          <Index>
            <DomainClassMoniker Name="ExampleElement" />
          </Index>
          <LinkCreationPaths>
            <DomainPath>ExampleModelHasElements.Elements</DomainPath>
          </LinkCreationPaths>
        </ElementMergeDirective>
      </ElementMergeDirectives>
    </DomainClass>

As usual regenerate the templates and recompile.

An error appears...

Error    1    'myns.Language1.ExampleModel' does not contain a definition for 'CanMergeExampleElement' and no extension method 'CanMergeExampleElement' accepting a first argument of type 'myns.Language1.ExampleModel' could be found

Clicking on the error you are taken to the  call to the method that you have to implement. Using vs is easy to do this..hover your mouse to the little rectangle at the beginning of the method name.

 

CanMerge

Copy the generated method stub to your partial class and implement it.

How? I don't know...Stay tuned...

Double derived pattern in DSL

Customizing a DSL needs different expertise based on the amount of customization that you want to apply.

A 'basic' concept that you need to understand is the double derived pattern.

The DSL engine generates classes based on the dsl definition. Those classes are partial class so, like in asp.net or winform, you can create your code for the same class in another file separating it from the automatically generated.

Those classes are split in two separate files, but is essentially the same class so you can't replace a method automatically generated.

To address this problem the DSL framework introduce the double derived pattern. For each class (with the "Generates Double Derived" attribute set) the generated code is set on the base class so you are free to override the automatically generated code in the derived class.

If you have a class named ExampleElement (the one automatically generated if you create a new MinimalLanguage project) and you mark it with "Generates Double Derived" you'll get the following class structure

DoubleDerive

 

The framework generates an ExampleElementBase class that contains all the generated code, in the derived class (ExampleElement) you are free to override everything (except the constructor see below).

In case of the Sources property you'll write

public partial class ExampleElement
{
    public override Microsoft.VisualStudio.Modeling.LinkedElementCollection<ExampleElement> Sources
    {
        get
        {
            return base.Sources;
        }
    }
}          

The case of constructor it's a little bit different....the problem is that DSL tools must generate the constructor for the derived class (if not the framework couldn't instantiate the class). So if you need to override also the constructor you can set the "Has custom constructor".

(Remember to select "Transform all templates" and rebuild!)

In this case a compilation error is generated stating that you have to implement the constructor. Something like

Error    1    "...ExampleElement' does not contain a constructor that takes '0' arguments 

del.icio.us Tags:

Visual programming language using visual studio DSL

I found a very interesting firmware for my Canon A550. This new firmware adds tons of new feature. One of those, is the scripting support using a language similar to basic.

As a programmer it's easy to program with it...well...too easy!

So I decided to throw some of my spare time to play with DSL.

The basic idea is to create a DSL that let's you visually program the canon scripting.

What I want to achieve is a tool having a toolbar with all the language (if, do, variable declaration...) and camera (shoot, zoom...) statements that you can drag on the programming surface to construct a script.

The first look at DSL give me the idea that the learning curve is very steep...so it's perfect to save me from the current time waster.

Stay tuned for future posts about it...

Cross thread call in a winform

In a winform you have to make all modification from the thread where the winform is created.
If you manage async operations you'll step into the problem of modifying the form from another thread.
You can use delegate to do this.
Say you want to change the textbox text.
First declare the delegate that accepts a string as a parameter:


public delegate void SetLogTextDelegate(String myString);


Then declare a variable with the previous delegate as hits type.


public SetLogTextDelegate myDelegate;

Implement the method that will be called:


public void SetLogTextMethod(string myString)
{
   System.Diagnostics.Trace.WriteLine(myString);
   this.txtLog.Text += myString + Environment.NewLine;
}


Actually I use this method to log some messages either in the OutputDebugString (I take the default listener) and in the textbox.
Then assign the delegate (the form constructor is a good place).


myDelegate = new SetLogTextDelegate(SetLogTextMethod);

You can now call the delegate wherever you want:


this.Invoke(this.myDelegate, new object[] { myString });

You can embed this call in a method of his own for clarity sake:


public void SetLogText(string myString)
{
   this.Invoke(this.myDelegate, new object[] { myString });
}


A sample winform app:

 

using System;
using System.Windows.Forms;
using System.Threading;
namespace CrossThreadCallDemo
{
   public partial class Form1 : Form
   {
       public delegate void SetLogTextDelegate(String myString);
       public SetLogTextDelegate myDelegate;
       public void SetLogText(string myString)
       {
           this.Invoke(this.myDelegate, new object[] { myString });
       }
       public void SetLogTextMethod(string myString)
       {
           System.Diagnostics.Trace.WriteLine(myString);
           this.txtLog.Text += myString + Environment.NewLine;
       }
       public Form1()
       {
           InitializeComponent();
           SetLogTextMethod("Form started threadId=" + Thread.CurrentThread.ManagedThreadId);
           myDelegate = new SetLogTextDelegate(SetLogTextMethod);
       }
       private void btnStart_Click(object sender, EventArgs e)
       {
           new System.Threading.Thread(new ParameterizedThreadStart(Process)).Start();
       }
       void Process(object state)
       {
           //txtLog.Text = "Hello";
           if (this.InvokeRequired)
               SetLogText("Hello threadId=" + Thread.CurrentThread.ManagedThreadId);
           else
               txtLog.Text = "Hello";
       }
   }
}


That's it

Deleting specific lines in visual studio editor

Sometimes in visual studio editor you want to delete all the lines containing a specified text.

This is possible using regular expression.

As you may know regular expression in vs editor are a little bit wierd...

Suppose you want to delete all the lines containing "System.Net Verbose" from the following source...

   1: [3636] [4472] 00000000 : 3C 3F 78 6D 6C 20 76 65-72 73 69 6F 6E 3D 22 31 : <?xml version="1 
   2: [3636] System.Net Verbose: 0 : 
   3: [3636] [4472] 00000010 : 2E 30 22 20 65 6E 63 6F-64 69 6E 67 3D 22 55 54 : .0" encoding="UT 
   4: [3636] System.Net Verbose: 0 : 
   5: [3636] [4472] 00000020 : 46 2D 38 22 20 73 74 61-6E 64 61 6C 6F 6E 65 3D : F-8" standalone= 
   6: [3636] System.Net Verbose: 0 : 
   7: [3636] [4472] 00000030 : 22 6E 6F 22 3F 3E 3C 53-4F 41 50 2D 45 4E 56 3A : "no"?><SOAP-ENV: 

 

Open the find and replace dialog (ctrl+H), select "regular expression" in the Find options.

Enter the string ".*System.Net Verbose.*\n" and click on replace all.

That's it.

".*" matches all characters.

\n matches the end of line

Parameter passing playground

Getting used to how parameter passing works isn't really simple. Especially if you didn't program so often, every now and then you have to check back how things works. If you really want to understand how things work I recommend you CLR via C# by Jeffrey Richter.

First thing to remember is the difference between value and reference types. The first lives in the stack(int, short, struct), the second on the heap (string, your class types).

   1: class Program
   2: {
   3:     static void Main(string[] args)
   4:     {
   5:         string callerString1 = "CallerValue1";
   6:         string callerString2 = "CallerValue2";
   7:         string callerString3 = callerString1;
   8:         string callerString4 = callerString2;
   9:  
  10:         string stringBefore = "callerString1=" + callerString1 + " callerString2=" + callerString2 + " callerString3=" + callerString3 + " callerString4=" + callerString4;
  11:  
  12:         int int1 = 8;
  13:         int int2 = 9;
  14:         int int3 = int1;
  15:         int int4 = int2;
  16:         string intBefore = "int1=" + int1 + " int2=" + int2 + " int3=" + int3 + " int4=" + int4;
  17:  
  18:         MyType objTest1 = new MyType();
  19:         MyType objTestTemp1 = new MyType();
  20:         objTest1.X = 10;
  21:         objTestTemp1 = objTest1;
  22:  
  23:         string objectBefore1 = "objTest1.X=" + objTest1.X + " objTestTemp1.X=" + objTestTemp1.X;
  24:  
  25:         MyType objTest2 = new MyType();
  26:         MyType objTestTemp2 = new MyType();
  27:         objTest2.X = 11;
  28:         objTestTemp2 = objTest2;
  29:  
  30:         string objectBefore2 = "objTest2.X=" + objTest2.X + " objTestTemp2.X=" + objTestTemp2.X;
  31:  
  32:         prova(callerString1, ref callerString2, int1, ref int2, objTest1, ref objTest2);
  33:  
  34:         string stringAfter = "callerString1=" + callerString1 + " callerString2=" + callerString2 + " callerString3=" + callerString3 + " callerString4=" + callerString4;
  35:         string intAfter = "int1=" + int1 + " int2=" + int2 + " int3=" + int3 + " int4=" + int4;
  36:         string objectAfter1 = "objTest1.X=" + objTest1.X + " objTestTemp1.X=" + objTestTemp1.X;
  37:         string objectAfter2 = "objTest2.X=" + objTest2.X + " objTestTemp2.X=" + objTestTemp2.X;
  38:  
  39:         Console.Out.WriteLine(stringBefore);
  40:         Console.Out.WriteLine(stringAfter);
  41:         Console.Out.WriteLine(intBefore);
  42:         Console.Out.WriteLine(intAfter);
  43:         Console.Out.WriteLine();
  44:         Console.Out.WriteLine(objectBefore1);
  45:         Console.Out.WriteLine(objectAfter1);
  46:         Console.Out.WriteLine();
  47:         Console.Out.WriteLine(objectBefore2);
  48:         Console.Out.WriteLine(objectAfter2);
  49:  
  50:     }
  51:  
  52:     private static void prova(string string1, ref string string2, int methodInt1, ref int methodInt2, MyType methodObjProva1, ref MyType methodObjProva2)
  53:     {
  54:         string string3 = "MethodValue5";
  55:         string1 = "MethodValue1";
  56:         string1 = string3;
  57:         string1 = "MethodValue2";
  58:  
  59:         string string4 = "MethodValue6";
  60:         string2 = "MethodValue3";
  61:         string2 = string4;
  62:         string2 = "MethodValue4";
  63:  
  64:         methodInt1 = 1;
  65:         int internalInt = 10;
  66:         methodInt1 = internalInt;
  67:  
  68:         methodInt2 = 1;
  69:         methodInt2 = internalInt;
  70:  
  71:         MyType internalMyType1 = new MyType();
  72:         internalMyType1.X = -3;
  73:  
  74:         methodObjProva1.X = -4;
  75:  
  76:         methodObjProva1 = internalMyType1;
  77:         methodObjProva1.X = -5;
  78:  
  79:         MyType internalMyType2 = new MyType();
  80:         methodObjProva2.X = -6;
  81:         methodObjProva2 = internalMyType2;
  82:         methodObjProva2.X = -7;
  83:  
  84:     }
  85: }
  86: public class MyType
  87: {
  88:     int x = 0;
  89:  
  90:     public int X
  91:     {
  92:         get { return x; }
  93:         set { x = value; }
  94:     }
  95: }

 

tbc

Strange xml parsing behavior (at least to me!!!)

If you load an xml document with the dom (I tried it with MSXML and System.Xml.XmlDocument) that has the node content set to > (greater than) the value is escaped by the parser.

If you specify an xml (containing the greater than sign) as the node content it isn't escaped.

So if you have

<root>></root> you'll get <root>&gt;</root>

if you have

 <root>><foo /></root> you'll get (the same) <root><foo /></root>

Strange!

«dicembre»
domlunmarmergiovensab
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910