OutDir vs OutputPath for Visual studio 2015 and Asp.Net Core

TL;DR

In MSBuild for Asp.Net Core use /p:OutputPath parameter, not /p:OutDir nor both.

Full story

We’ve used psake powershell build for ASP.Net 4.61 project and passed both parameters
msbuild  /p:OutDir=“$binariesDir\” /p:OutputPath=“$outPath\”
Actually /p:OutputPath was ignored(almost, see below) and build was saved to specified in /p:OutDir folder.
When I included Asp.Net Core project into solution, it’s failed because dll, referenced by the Core project, was saved to OutDir folder, but Asp.Net Core project tried to find it in OutputPath folder.
I’ve tried to remove /p:OutputPath  parameter (as suggested in OutputPath vs OutDir thread: “to keep the OutputPath that is generated by Visual Studio, then set the OutDir as a command argument”), Asp.Net Core project failed because dll was saved to OutDir folder, but Asp.Net Core project tried to find it in relative bin\Release\ folder.
When I removed OutDir parameter and specified /p:OutputPath=“$binariesDir\” build was successful,  but package for MSDeploy, specified in a custom MS Build step, was created in a relative path obj\Release\Package rather than specified $binariesDir folder, so I needed to adjust package path.
Current VS 2015 MSDN page  Common MSBuild Project Properties doesn’t document OutDir , but only OutputPath.
 
Note that previously MSDN recommended the opposite: “OutputPath has been deprecated and OutDir should be used instead whenever possible. ”
   

ScrollToControl helper method for ASP.Net web forms to move position to particular control

I’ve created a helper method for ASP.Net web forms to move position to particular control
            /// <summary>
            ///
            /// </summary>
            /// <param name=”page”></param>
            /// <param name=”clientId”></param>
            /// <param name=”alignToTop”></param>
            public static void ScrollToControl( Page page, string clientId, bool alignToTop)
            {
                //NOTE: if there are more than one call on the page, first one will take preference
                //If we want that last will take  preference, change key from MethodBase.GetCurrentMethod().Name to anchorName
                //recommended in http://gnidesign.blogspot.com.au/2011/06/how-to-maintain-page-scroll-on-postback.html               
                String script = ” window.scrollTo = function () { };” + Environment.NewLine;
                script += String.Format(“document.getElementById(‘{0}’).scrollIntoView({1});” , clientId, alignToTop.JSToString());
                page.ClientScript.RegisterStartupScript(TypeForClientScript(), MethodBase.GetCurrentMethod().Name, script, true );
                //return script;
            }
            public static string JSToString(this bool bValue)
            {
                return bValue.ToString().ToLower();
            }

Use getElementById(‘{0}’).scrollIntoView is simpler than location.hash , because you don’t need to add extra anchor element.
Parameter alignToTop is very convenient to specify do you want to show control at the top or bottom of the screen.

It’s posted as an answer http://stackoverflow.com/a/34823392/52277
There is more advance jQuery plug-in http://erraticdev.blogspot.com.au/2011/02/jquery-scroll-into-view-plugin-with.html

Tiny MCE editor in ASP.Net Web Form

I wanted to implement rich text editor in ASP.Net Web Form. I found that Tiny MCE editor is very popular and selected it.

Response for REST method was truncated because default MaxItemsInObjectGraph was not big enough.

We have a   REST service with attributes [WebGet(UriTemplate =“…”, BodyStyle =WebMessageBodyStyle.Bare, ResponseFormat =WebMessageFormat.Xml)]

Normally it worked fine. But for particular data it has a huge response that was truncated. 

The size returned in a few attempts in IE browser was 2196456, in Chrome slightly different 2195397.


After a search in google I found http://forums.asp.net/post/4948029.aspx, that has a number of suggestions.

 

For WCF service that will transfer large amount of data in operations, here are the configuration settings you need to check:

1) the maxReceivedMessageSize attribute of the certain <binding> element(in your case, that’s the webHttpbinding)

#<webHttpBinding> 
http://msdn.microsoft.com/en-us/library/bb412176.aspx

2) The <readerQuotas> settings (under the <binding> elements) which has control over the maxarrayLength, maxStringLength ,etc…

#<readerQuotas> 
http://msdn.microsoft.com/en-us/library/ms731325.aspx

3) The DataContractSerializer behavior which has a MaxItemsInObjectGraph property. You can configure it via ServiceBehavior of your WCF service

#DataContractSerializer.MaxItemsInObjectGraph Property 
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.maxitemsinobjectgraph.aspx

4) And if your WCF service is hosted in ASP.NET/IIS web application, you also need to enlarge the “maxRequestLength” attribute of the <httpRuntime> element (under <system.web> section).

#httpRuntime Element (ASP.NET Settings Schema) 
http://msdn.microsoft.com/en-us/library/e1f13641.aspx

 After a few attempts my collegue found that our problem was caused by

#DataContractSerializer.MaxItemsInObjectGraph Property 
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.maxitemsinobjectgraph.aspx

 

<behavior name=“MyOperationBehavior>
          < dataContractSerializer maxItemsInObjectGraph =2196456 />
</behavior>

Missing error handling in Streaming-AJAX-Proxy Log

on our web site, but started to notice errors accessing log.txt file.
I found that the file is created by Log class and doesn’t have ability to switch it off and error handling.
I’ve added reading file name from configuration and try/catch block
  public static class Log
    {
        private static StreamWriter logStream;
        private static object lockObject = new object ();
    public static void WriteLine(string msg)
        {
                      string logFileName = ConfigurationExtensions.GetAppSetting(“AjaxStreamingProxy.LogFile” ,“”);
                      if (logFileName.IsNullOrEmpty())
                            return;
                      try
                     {
                            if (logStream == null )
                           {
                                   lock (lockObject)
                                  {
                                          if (logStream == null )
                                         {
                           logStream = File.AppendText(Path .Combine(AppDomain.CurrentDomain.BaseDirectory, logFileName));
                                         }
                                  }
                           }
                           logStream.WriteLine(msg);
                     }
                      catch (Exception exc)
                     {
                            string ignoredMsg = String .Format(“The error occured while logging {0}, but processing will continue.n {1} , exc);
                            LoggerHelper.LogEvent(ignoredMsg, MyCategorySource, TraceEventType .Warning, true);
                     }
        }

Adding Async=true to the page- no side effects noticed.

Recently I needed to implement PageAsyncTask  in .Net 4 web forms application.

“A PageAsyncTask object must be registered to the page through the RegisterAsyncTask method. The page itself does not have to be processed asynchronously to execute asynchronous tasks. You can set the Async attribute to either true (as shown in the following code example) or false on the page directive and the asynchronous tasks will still be processed asynchronously:

<%@ Page Async=”true” %>

When the Async attribute is set to false, the thread that executes the page will be blocked until all asynchronous tasks are complete.”

I was worry about any site effects if I will set  Async=true on the existing page.
The only documented restrictions, that I found are that

@Async is not compatible with @AspCompat and Transaction attributes (from @ Page directive  MSDN article). In other words, 

Asynchronous pages do not work when the AspCompat attribute is set to true or the Transactionattribute is set to a value other than Disabled in the @ Page directive

From our tests we conclude, that adding Async=true to the page is quite safe, even if you don’t always call Async tasks from the page 

Configuration setting of HttpWebRequest.Timeout value

I wanted to set in configuration on client HttpWebRequest.Timeout.
I was surprised, that MS doesn’t provide it as a part of .Net configuration.
(Answer in http://forums.silverlight.net/post/77818.aspx thread: “Unfortunately specifying the timeout is not supported in current version. We may support it in the future release.”)
 
I added it to appSettings section of app.config and read it in the method of My HttpWebRequestHelper class

  //The Method property can be set to any of the HTTP 1.1 protocol verbs: GET, HEAD, POST, PUT, DELETE, TRACE, or OPTIONS.
       public static
HttpWebRequest PrepareWebRequest(string sUrl, string Method, CookieContainer cntnrCookies)
       {
           
HttpWebRequest webRequest = WebRequest.Create(sUrl) as HttpWebRequest;
           webRequest.Method = Method;
           webRequest.ContentType =
“application/x-www-form-urlencoded”;
           webRequest.CookieContainer = cntnrCookies;
webRequest.Timeout = ConfigurationExtensions.GetAppSetting(“HttpWebRequest.Timeout”, 100000);
//default 100sec-http://blogs.msdn.com/b/buckh/archive/2005/02/01/365127.aspx)
           /*                //try to change – from http://www.codeproject.com/csharp/ClientTicket_MSNP9.asp          
                       webRequest.AllowAutoRedirect = false;
                      webRequest.Pipelined = false;
                       webRequest.KeepAlive = false;
                       webRequest.ProtocolVersion = new Version(1,0);//protocol 1.0 works better that 1.1 ??
           */
           //MNF 26/5/2005 Some web servers expect UserAgent to be specified
           //so let’s say it’s IE6
           webRequest.UserAgent =
“Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)”;

           
DebugOutputHelper.PrintHttpWebRequest(webRequest, TraceOutputHelper.LineWithTrace(“”));
           return webRequest;
       }


Related link:
http://stackoverflow.com/questions/387247/i-need-help-setting-net-httpwebrequest-timeout

v

Log JavaScript errors to the server.

Some time ago I found debugging – Automatic feedback on JavaScript error – Stack Overflow.  
and the discussion has  links to
Logging JavaScript Errors To ASP.NET(Unfortunately the link to download in the post is broken).
and custom control to help log JavaScript errors by sending error information to the server –thecodepage.com/post/JavaScript-Error-Notifications.aspx.
I’ve downloaded solution from  JSErrorNotifier.zip. When I wanted to include dll into my solution dependencies,  I decided to rename WebControls.DLL to more descriptive JSErrorNotifier.DLL.
I also decided to rename default namespace to be the same as DLL name.
It wasn’t a good idea, because control stopped to work. It took me some time and I had to call  StreamHelper.EnsureWebResourceValid function from my old post Check that embedded resource exist before calling ClientScript.RegisterClientScriptResource or GetWebResourceUrl
to do all consistent changes for namespace renaming.

Finally when I made control working again, I found that it doesn’t work in IE 9. After another half an hour of debugging I found that for my IE9 onerror event is not fired even for example from MS documentation
http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/onerrorEX.htm.
It worked on other browsers and on IE8, but on IE9 you need to disable script debugging in Internet Explorer (Tools, Internet Options, Advanced). The  same happens if IE9 changed to IE7 or IE8 mode.(Actually I’ve noticed that Developer Tools Browser mode IE7 or IE8 do not emulate correctly native script engine of older IE versions)

However native IE8 on XP fires onerror regardless if debugging is enabled or disabled.

I hope that not too many IE9 users with enabled debugging will have  JS errors in our application.

Select tool to minimize JavaScript and CSS size

There are multiple ways and techniques how to combine and minify JS and CSS files.
The good number of links can be found in http://stackoverflow.com/questions/882937/asp-net-script-and-css-compression
and in http://www.hanselman.com/blog/TheImportanceAndEaseOfMinifyingYourCSSAndJavaScriptAndOptimizingPNGsForYourBlogOrWebsite.aspx

There are 2 major approaches- do it during build or at run-time.

In our application there are multiple user-controls, each of them required different JS or CSS files, and they loaded dynamically in the different combinations. We decided that loading all JS or CSS files for each page is not a good idea, but for each page we need to load different set of files.
Based on this combining files on the build stage does not looks feasible.
After Reviewing  different links I’ve decided that squishit should fit to our needs. http://www.codethinked.com/squishit-the-friendly-aspnet-javascript-and-css-squisher

Different limitations of using SquishIt.
We had some browser specific CSS files, that loaded conditionally depending of browser type(i.e IE and all other browsers). We had to put them in separate bundles,

For Resources and AXD files we decide to use HttpModule and HttpHandler created by Mads Kristensen

To GZIP html we are using wwWebUtils.GZipEncodePage() http://www.west-wind.com/weblog/posts/2007/Feb/05/More-on-GZip-compression-with-ASPNET-Content Just swap the order of which encoding you apply to start by asking for deflate support and then GZip afterwards.

Additional tips about SquishIt.

Use CDN: https://groups.google.com/group/squishit/browse_thread/thread/99f3b61444da9ad1
Support intellisense and generate bundle in codebehind http://tech.kipusoep.nl/2010/07/23/umbraco-45-visual-studio-2010-dotless-jquery-vsdoc-squishit-masterpages/

Links about other Libraries that were considered

A few links from http://stackoverflow.com/questions/5288656/which-one-has-better-minification-between-squishit-and-combres2

.Net 4.5 will have out-of-the-box tools for JS/CSS combining.
http://weblogs.asp.net/scottgu/archive/2011/11/27/new-bundling-and-minification-support-asp-net-4-5-series.aspx . It suggests default bundle of subfolder, but also seems supporting similar to squishit explicitly specified files.

http://www.codeproject.com/KB/aspnet/combres2.aspx  config XML file can specify expiry etc

https://github.com/andrewdavey/cassette
http://stackoverflow.com/questions/7026029/alternatives-to-cassette

Dynamically loaded JS files requireJS http://requirejs.org/docs/start.html  

http://www.west-wind.com/weblog/posts/2008/Jul/07/Inclusion-of-JavaScript-Files
Pack and minimize your JavaScript code size

YUI Compressor (from Yahoo)
JSMin (by Douglas Crockford)
ShrinkSafe (from Dojo library)
Packer (by Dean Edwards)

RadScriptManager  & RadStyleSheetManager -fromTeleric(not free)

Tools to optimize performance:

PageSpeed tools family http://code.google.com/intl/ru/speed/page-speed/download.html



v

Dump an arbitrary object To Html String

For debugging purposes me and my collegue wanted to dump details of the arbitrary object, and created function that uses LINQPad Dump functionality (thanks to http://stackoverflow.com/a/6035014/52277 and original http://linqpad.uservoice.com/forums/18302-linqpad-feature-suggestions/suggestions/447166-make-dump-extension-method-available-in-visual-s discussion)
   public static string DumpToHtmlString<T>(this T objectToSerialize)
       {
           string strHTML =
“”;

           try
           {
               var writer = LINQPad.
Util.CreateXhtmlWriter(true);
               writer.Write(objectToSerialize);
               strHTML = writer.ToString();
           }
           catch (
Exception exc)
           {
               
Debug.Assert(false, “Investigate why ?” + exc);
           }

           return strHTML;
       }

You will need to add the linqpad executable as a reference in your project.


TO DO similar in plain text ,look at https://github.com/ServiceStack/ServiceStack.Text StringExtensions , e.g. JsonSerializer/CsvSerializer

or http://objectdumper.codeplex.com/