Contents tagged with ASP.NET

  • NSession is quietly marching towards 1.0 release

    My open source project NSession has be around for several years. It allows ASP classic pages to access ASP.NET out-of-process session states the same way that ASP.NET pages access them. Recently, there are a large number of users migrating from Windows 2003 to Windows Server 2008/2012 and encountered an incompatibility with ASP.NET 4.5. I was contacted by users daily publicly or privately. I decided to make additional effort to put finishing touch on it to make it a 1.0 product.

    In 0.9.0.1 release, I had:

    • Fixed the compatibility issues with asp.net 4.5.
    • Improved the documents.
    • Reduced hacking to make it less likely to encounter compatibility problem with future versions of ASP.NET.

    In 0.9.1.2 release, I had:

    • Added support for SQL Server session state so that it supports all the built-in out-of-proc session states in ASP.NET and is feature complete for 1.0 release.
    • Added a diagnostic check list and a diagnostic tool.

    Before 1.0 release, I will continue improving installation experience, fixing bugs reported and will do some performance testing.

    Beyond 1.0, I will start designing adapter interface to support custom session states. Please visit the project site to propose custom session state providers to support in the work items area.

  • ASP Classic Compiler is now available in NuGet

    I know this is very, very late, but I hope it is better than never. To make it easy to experiment with ASP Classic Compiler, I made the .net 4.x binaries available in NuGet. So it is now extremely easy to try it:

    1. From the package console of any .NET 4.x web project, run “Install-Package Dlrsoft.Asp”.
    2. To switch from AspClassic to Asp Classic Compiler in the project, add the following section to the system.webServer handlers section:
        <system.webServer>
          <handlers>
            <remove name="ASPClassic"/>
            <add name="ASPClassic" verb="*" path="*.asp" type="Dlrsoft.Asp.AspHandler, Dlrsoft.Asp"/>
          </handlers>
        </system.webServer>
      Comment out the section to switch back.
    3. Add a test page StringBuilder.asp:
      <%
          imports system
          dim s = new system.text.stringbuilder()
          dim i
          
          s = s + "<table>"
          for i = 1 to 12
              s = s + "<tr>"
              s = s + "<td>" + i + "</td>"
              s = s + "<td>" + MonthName(i) + "</td>"
              s = s + "</tr>"
          next
          s = s + "</table>"
          response.Write(s)
       
      %>
      This code uses the .net extension so it will only work with Asp Classic Compiler.

    Happy experimenting!

  • Sky LINQPad, a minimum viable clone of LINQPad in the cloud

    A while ago, I blogged about a simple LINQPad query host. It is fairly easy to put a web face on it. The only change that I had to make is to set the ApplicationBase for the AppDomains that I create as asp.net is quite different to an .exe app. A playground is now running at http://skylinq.azurewebsites.net/SkyLINQPad. One can upload an existing .linq files designed in LINQPad or type some queries directly into the page:

     

    image

  • Converted ASP Classic Compiler project from Mercurial to Git

    Like some other open source project developers, I picked the Mercurial as my version control system. Unfortunately, Git is winning in the Visual Studio echo systems. Fortunately, it is possible to contact Codeplex admin for manual conversion from Mercurial to Git. I have done exactly that for my open source ASP Classic Compiler project. Now I can add new examples in response to forum questions and check them in using my Visual Studio 2013. Now I am all happy.

  • Video review: RESTful Services with ASP.NET Web API from PACKT Publishing

    Disclaimer: I was provided this video for free by PACKT Publishing. However, that does not affect my opinion about this video.

    Upon request by PACKT Publishing, I agreed to watch and review the video “RESTful Service with ASP.NET Web API” by Fanie Reynders. Prior to the review, I have a EBook called “Designing Evolvable Web APIs with ASP.NET - Harnessing the power of the web” by Glenn Block, Pablo Cibraro, Pedro Felix, Howard Dierking and Darrel Miller from O’Reilly. I also have access to several videos on the Pluralsight.com on the same subject. So I would put my review in perspective with those other materials.

    The video from Packt has the length of 2 hours 4 minutes. It gave a nice overview over the ASP.NET Web API. The video is available for watch online or for downloading to watch offline. The video has 8 chapters. It covers the ASP.NET Web API in a clear and accurate way and is surprisingly complete for this short length.

    In comparison with other resources, I would recommend you get this video if you have never worked with ASP.NET Web API before and want to get a complete overview in a short time possible.

    If you love video, Pluralsight is offering the equally good and slightly longer (3h 15m)  “Introduction to the ASP.NET Web API” by Jon Flanders. You would need subscription to access the exercise materials thought. If you do subscribe, Pluralsight also has a couple of intermediate level videos by Shawn Wildermuth.

    Lastly, if you want an in depth book that you can use for a extended period of time, it is hard to beat Glenn Block, etc.’s book from O’Reilly.

  • SkyLog: My first end-to-end example on programming by composition

    I have completed my first end-to-end example as I am exploring the idea of programming by composition. SkyLog is an example on querying IIS Log files like what LogParser do, except:

    1. It is built on LINQ and thus can use the entire .net framework, not just the built-in functions of LogParser.
    2. It can use Parallel LINQ and thus uses multiple cores effectively.
    3. Any part of a query can be refactored into a function and thus reused.
    4. We just need to write the queries once and the queries can be used against one log file, a whole directory of log files, several servers, and in any storage, such as Azure Blog Storage.

    The running example are available at http://skylinq.azurewebsites.net/skylog. The example runs the query against some log files stored in Azure Blog Storage.

    image

    The queries in the example are from http://blogs.msdn.com/b/carlosag/archive/2010/03/25/analyze-your-iis-log-files-favorite-log-parser-queries.aspx.

    The queries look even simpler than what you normally write against LogParser or SQL Server:

    image

    That is because part of the queries were refactored into two reusable functions below. We cannot reuse part of query with LogParser. With SQL Server, we can create reusable units with View. With LINQ, we can reuse any part of the LINQ query.

    image

    Note that I used the memory efficient version of GroupBy written by me previously. The equivalent code using the GroupBy in LINQ is commented out.

    To run these reports, we just need records from the log files as IEnumerable<string>. To get them from a directory, the code would look like:

    image

    To get records from Windows Azure Blob Storage, the could would look like:

    image

    Lastly, we need to convert IEnumberable<string> to strongly-typed wrapper, IEnumerable<W3SVCLogRecord>, to be consumed by the reports:

    image

    I touched upon the idea of strongly-typed wrapper previously. The purpose of strongly-typed wrapper is to allow intelligence while minimize the garbage collection. The wrapper provides access to underlying data, but does not convert the data to a data-transfer-object.

    The front-end is a simple ASP.NET MVC page. Reports are exposed through ASP.NET Web API using the CSV formatter that I built previously. The visualization was built using D3.js. The code is so simple that we could think each line of the code as Javascript based widgets. If we desire more sophisticated UI, we could compose the UI with a different widget. We could even introduce a client-side template engine such as Mustache.js.

    image

    Even with simple example, there are enough benefits in it so that I probably would never need to use LogParser again. The example is fully built on LINQ to IEnumerable. I have not used any cool feature from IQueryable and Rx yet. As usually, the latest code is in http://skylinq.codeplex.com. Stay tuned for more fun stuff.

  • Custom Web API Message Formatter

    ASP.NET Web API supports multiple message formats. The framework uses the “Accept” request header from the client to determine the message format. If you visit a Web API URL with internet explorer, you will get a JSON message by default; if you use Chrome, which sends “application/xml;” in the accept header, you will get a XML message.

    Message format is an extensivity point in Web API. There is a pretty good example on ASP.NET web site. Recently, when I worked on my SkyLinq open source cloud analytic project, I needed a way to expose data to the client in a very lean manner. I would like it to leaner than both XML and JSON, so I used csv. The example provided on the ASP.NET website is actually a CSV example. The article was lastly updated on March 8, 2012. Since ASP.NET is rapidly advancing, I found that I need to make the following modifications to make the example working correctly with Web API 2.0.

    1. CanReadType is now a public function instead of a proetected function.
    2. The signature of WriteToStream has changed. The current signature is

      image

    3. When addition the Media Formatter to the Configuration, I have to insert my custom formatter into the formatters collection as the first. This is because the JSON Formatter actually recognizes the “application/csv” header and send JSON back instead. Example below:

      image

  • Is it time for cloud-based ASP.NET IDE? (round 2)

    8 months ago, I asked whether it is time for cloud-based ASP.NET IDE. I have long been dreaming of being able to create web application on the spot while talking to users. I was able to do that 20 years ago with VB3. Today, the closest thing I can do with web application is with a CMS like Orchard. To work on a live website, we need an editor that is accessing the live site. We also need a tool to indicate the link between the html in the browser and the code that generate the html.

    A lot has happened in the past 8 months. For the cloud based editor, first I saw Scott Hanselman’s blog about Microsoft’s own cloud editor. Then we found this editor to appear in Visual Studio Online.

    For the tools that link html with source code, I first saw the very impressive shape tracing tool in Orchard. Then we saw the browser link and remote debugging feature in Visual Studio 2013.

    So whether the IDE itself is in the cloud or not, the new VS2013 features together with the Azure feature of deploying directly from a repository brings up ever close to being able to work on a live web application in front of a customer.

  • Gave 3 presentations at SoCal Code Camp (UCSD) today

    I gave 3 presentations at SoCal Code Camp today at University of California, San Diego.

    The first two presentations are co-presented with our summer intern Christopher Chen. Clicks the links below to download the power point.

    Creating an Orchard website on Azure in 60 minutes

    Customizing Orchard Websites without limit

    My source code can be found on github: https://github.com/aspcompiler/sdcodecamp

    Lastly, several people asked whether we can create mailing list to keep in touch. I created a Linkedin group called SoCal Orchard SIG. Welcome to join!

    My last talk was:

    Machine learning made simple

  • Asp.NET ReportViewer “report execution has expired or cannot be found” error when using session state service or SQL Server session state

    We encountered an error like:

    ReportServerException: The report execution x5pl2245iwvvq055khsxzlj5 has expired or cannot be found. (rsExecutionNotFound)]
       Microsoft.Reporting.WebForms.ServerReportSoapProxy.OnSoapException(SoapException e) +72
       Microsoft.Reporting.WebForms.Internal.Soap.ReportingServices2005.Execution.ProxyMethodInvocation.Execute(RSExecutionConnection connection, ProxyMethod`1 initialMethod, ProxyMethod`1 retryMethod) +428
       Microsoft.Reporting.WebForms.Internal.Soap.ReportingServices2005.Execution.RSExecutionConnection.GetExecutionInfo() +133
       Microsoft.Reporting.WebForms.ServerReport.EnsureExecutionSession() +197
       Microsoft.Reporting.WebForms.ServerReport.LoadViewState(Object viewStateObj) +256
       Microsoft.Reporting.WebForms.ServerReport..ctor(SerializationInfo info, StreamingContext context) +355

    [TargetInvocationException: Exception has been thrown by the target of an invocation.]
       System.RuntimeMethodHandle._SerializationInvoke(Object target, SignatureStruct&amp; declaringTypeSig, SerializationInfo info, StreamingContext context) +0
       System.Reflection.RuntimeConstructorInfo.SerializationInvoke(Object target, SerializationInfo info, StreamingContext context) +108
       System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context) +273
       System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder) +49
       System.Runtime.Serialization.ObjectManager.DoFixups() +223
       System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) +188
       System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) +203
       System.Web.Util.AltSerialization.ReadValueFromStream(BinaryReader reader) +788
       System.Web.SessionState.SessionStateItemCollection.ReadValueFromStreamWithAssert() +55
       System.Web.SessionState.SessionStateItemCollection.DeserializeItem(String name, Boolean check) +281
       System.Web.SessionState.SessionStateItemCollection.DeserializeItem(Int32 index) +110
       System.Web.SessionState.SessionStateItemCollection.get_Item(Int32 index) +17
       System.Web.SessionState.HttpSessionStateContainer.get_Item(Int32 index) +13
       System.Web.Util.AspCompatApplicationStep.OnPageStartSessionObjects() +71
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2065

    This error occurs long after the report viewer page has closed. It occurs to any asp.net page in the application, rendering the entire application unusable until the user gets a new session.

    The cause of the problem is that the ReportViewer uses session state. When a page retrieves session from any out-of-state session, the session variable of type Microsoft.Reporting.WebForms.ReportHierarchy is deserialized from the session storage. The deserialization could cause the object to connect to the report server when the report is no longer available.

    The solution is simple but not pretty. We need to clean up the session variable when the report viewer page is closed. One way is to add some Javascript to the page to handle the window.onunload event. In the event handler, call a web service to clean up the session variable. The name of the session variable appears to be randomly generated. So we need to loop through the session variable to find a variable of the type Microsoft.Reporting.WebForms.ReportHierarchy. Microsoft has implemented pinging between the report viewer and the report server to keep the report alive on the server when the report viewer is up; I hope they will go one step further to take care of this problem.