JQuery.Migrate saves the day with Telerik UI for ASP.NET MVC

The relentless pace with which libraries, and dependent javascript resources now change,  is quite difficult to keep up with – particularly when you’re attempting to be frugal and use open source projects like Telerik UI for ASP.NET MVC – which basically got dropped in 2013, and replaced by Kendo UI.

The basic problem is that when you’re using libraries like these, that depend quite a bit on things like JQuery, and get subsequently dropped – you can be left in a bit of an upgrade quandary.

It’s tempting to go to NuGet, and just ‘update all’ libraries you’re using, but all sorts of bad things can happen if you get a little trigger happy on that function.  The Telerik components for instance expect JQuery 1.7.1 (which is a 2012 version).  I now want to use Bootstrap to create a responsive theme, and that’s wanting JQuery 2.x.  I’d tried to update to a later JQuery version previously and basically the whole deal broke – almost all components were using deprecated JQuery features.  I was considering going through the code and patching where required, but I don’t have that kind of time.

Whilst looking for deprecated features on the JQuery API doco, I saw mention of JQuery.Migrate plugin – which basically fills in those gaps for you.  I then picked up the package in NuGet, added to my Bundle config (right under JQuery)

 bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
 "~/Scripts/jquery-{version}.js",
 "~/Scripts/jquery-migrate-1.2.1.js",
 "~/Scripts/jquery.cookie.js",
 "~/Scripts/jquery.imagemapster.js",
 "~/Scripts/jquery.tooltipster.js"));

Stopped the site in IIS Express, restarted, and everything just magically started working again!

Now – I just have to get the responsive stuff singing and dancing with BootStrap :)

Integrating ASP.NET MVC into an existing ASP.NET Webforms application

If, like me you’re not always blessed with the opportunity to build every application from scratch, you may find yourself wanting to introduce the wholesome goodness of ASP.NET MVC into an existing ‘classic’ ASP.NET Webforms application. Most tutorials out there concentrate on nice green field development.

What follows is largely a reference for me to remember how to do this.  It’s basically a matter of manually injecting what the project templates do for a new application.  I’m also not professing to have come up with all of these steps – I’m just bringing them together.

I’ll assume you’ve got all the necessary prerequisites (MVC 4.0) installed already, and if you have a web ‘site’ project, then I’d suggest you update it to a web application before doing all of this.

Getting the structure and configuration to look like MVC

There’s a number of standard folders, and bits of code you’ll find dotted around MVC applications – Models/Views/Controller for instance :)

The following article goes through the first steps of getting those folders into your project (assuming you don’t have a naming conflict).

Mixing ASP.NET WebForms and ASP.NET MVC

Updating to MVC4

This is all good, but that article’s a bit old, and you’ll find the next one brings you (mostly) up to date with MVC 4.0

Adding MVC 4.0 to WebForms Project

If you want to use any of the newer features such as bundling, or if you’ve copied some views from an MVC4 project into your new MVC project, you’ll need the ASP.NET Web Optimization Framework (get it from NuGet).

You may also want to take an MVC4 project and convert the global.asax code to call off to the classes in the App_Start folder…

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
        }
    }

Getting the Visual Studio MVC Template Goodness

This is great, but the icing on the cake is to make Visual Studio think this is an MVC project, so you get the nice right-click options, like add–>Controller if you’re in the controllers folder.  It turns out you just need to fool Visual Studio by adding a project type guid in your web projects csproj file…

With Visual Studio I just did a quick diff between a new MVC 4 project’s project file, and my ‘hybrid’ project’s file.

The following is what you’re looking for…


<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{18BBC72C-702B-40CD-B347-D7FC66D276FA}</ProjectGuid>
<ProjectTypeGuids>{E3E379DF-F4C6-4180-9B81-6769533ABE47};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

If you just add the first ‘ProjectTypeGuids’ guid to the corresponding place in your project file, and reload, the magic happens, and Visual Studio thinks it’s now an MVC project.  You’ll probably find you already had the other 2 guids.

Use SQL Server Trusted Connections with ASP.NET on Windows 2003 without impersonation

Access control and troubleshooting 401 errors must be one of the most annoying and recurring issues with configuring IIS.  One of the problems is that it’s often quite a long time between issues, and you simply forget how you solved something last time.  This time I decided to write it all down as I set things up.

Target Scenario
My target scenario is a local intranet, where you want to use a ‘service account’ to access SQL Server, directly from your ‘trusted’ web application, removing the need for impersonation. 

The benefits of this are of course that you can take advantage of connection pooling, but also removing the need to configure passwords in web.config for SQL users (or specific, impersonated domain users).  This also removed the overhead of configuring specific domain users and their SQL Server permissions.  It may also be that you just want to simplify your security model to work only on Windows authentication across the stack.  

SQL Server

  1. Create a new role in the database you’re accessing, for the purposes of your application
  2. Add your service domain user account to the role in SQL Server
  3. Assign permissions to objects, stored procedures etc to the role (not directly to the user)

IIS/Web Site

  1. Set up your web site/application as you would normally – one way to do things….
    1. Create your web application root folder on the web server
    2. Copy your files (or use your deployment tools/scripts to do this)
    3. Create a new application pool to house your new web application (probably model this from the default web site).  This is important as this is where the credentials will be set
    4. Create the new IIS web application against the root folder (if not already done as part of step 2)
    5. Associate the new IIS application with the new application pool
    6. Set the ASP.NET version of your IIS application appropriate (may need to restart IIS here)
  2. Ensure ‘Integrated Security’ is set ON in the Directory Security tab, and ‘Anonymous’ access is switched OFF
  3. Set the application pool’s ‘identity’ to the domain user you want to run the application (and connect to SQL Server) as
  4. Open a command window and Go to the windows\Microsoft.NET\Framework\vXXXXX folder
    1. run aspnet_regiis -ga <domain>\<user> to grant necessary access to the metabase etc for the service account (as per http://msdn.microsoft.com/en-us/library/ff647396.aspx#paght000008_step3 )
    2. In the command window go to the inetpub\adminscripts folder, and set
      NTAuthenticationHeaders metabase property as per instructions at
      http://support.microsoft.com/kb/326985.  you can also use MetaEdit from
      the IIS Resource Kit to change this.  If you’re fully configured to use Kerberos then you can potentially skip this step, as it’s all about making IIS use NTLM authentication.
  5. Navigate to ‘Web Service Extensions’ in IIS Manager, and ensure that the ASP.NET version you’re targeting is ‘allowed’.  e.g. ASP.NET 4.0 is ‘prohibited’ by default.

Summary
So here we’ve circumvented the need to use impersonation by running the ASP.NET application as a specific domain user that is configured as a SQL Server Login, and granted the right access by means of a SQL Server role.  The main work is the plumbing to get IIS to work happily with that user in standard NTLM authentication (you may be able to use Kerberos depending on your network configuration).

Other background on creating service accounts can be found at http://msdn.microsoft.com/en-us/library/ms998297.aspx

Fixing SharePoint error: No item exists at [url]?ID=n. It may have been deleted or renamed by another user

Yesterday I was creating a page in SharePoint Designer and on testing got a server error:

No item exists at http://sharepointsite/WebPages/My-Page?ID=56.  It may have been deleted or renamed by another user.

I’d got code in the page that examined the ‘ID’ QueryString parameter and tried to load that item from a particular list.  This same code was working on another page.

This MSDN article described the problem,

This problem happens because Sharepoint has its own variable named ID 
which it uses to identify documents/pages on the server. Our solution 
should not be using a variable named ID.

I changed my QueryString parameter to RequestID instead and all was good, apart from the thought of why the other page still worked fine. 

I then realised that if it didn’t know what list it was trying to target, then the ‘List’ querystring parameter needs to be there too – as per other ‘application page’ requests in the _layouts folder, like approve/reject.

It then became obvious that I was doing too much work anyway:

Passing in the List as well as the ID allows you to then just get straight to the list item with the following code…

        SPListItem item = (SPListItem)SPContext.Current.Item;

as the List and ID are already taken care of.  A little neater than what I ‘was’ doing….

        SPListItem currentItem = null;

        //Get ID and List Item information
        requestList = SPContext.Current.Web.Lists["My List"];        
        if (requestList != null && Request.QueryString["ID"] != null)
        {
            if (int.TryParse(Request.QueryString["ID"].ToString(), out requestID))
            {
                //Get Item
                currentItem = requestList.GetItemById(requestID);


            }
            
        }

This code’s still fine (apart from the querystring ‘ID’ name) if you need to load an item from a list that you don’t know the guid for at the time.

Deploying the minimum Oracle Instant Client files with ODP.NET

If you’re looking for the smallest and least hassle deployment of Oracle client files with a .NET application, then forget about everything else you’ve been told – the following did the trick for me, and involves just 5 Oracle dll’s.

Deploying ODP.NET with Oracle Instant client

One thing I found with this was that on my dev machine I already have (more than) one ‘standard’ Oracle installation and all the network config from that was really getting in the way meaning I couldn’t connect for one reason or another – OR I was connecting, but not using the correct client, meaning deployed files wouldn’t work on a ‘virgin’ machine.  All of this rather depends on how your company deploys Oracle server and clients I guess.

Rather than muck about with setting environment variables (that’s so 80’s) if you use a full connection string syntax as follows you can use your hostname and SID rather than try and fathom out service names. 

In your web.config

  <add name=”MyDB” connectionString=”Data Source=(DESCRIPTION = (ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = machinename)(PORT = 1521)))(CONNECT_DATA =(SID = mysid)));User Id=username;Password=password;” providerName=”” />

Any other variation of the (mucho confusing) Oracle connection syntax just didn’t work for me.

As an aside – I also kept getting System.OutOfMemoryException when building a web site project in Visual Studio 2008 when I was using the Oracle Basic client dll’s (110mb +).  I switched to the smaller Basic ‘Lite’ versions and it was happy again.  I guess a single file of over 100mb blows the lid off the IDE.

Using JQuery with DotNetNuke 4.x

I’m currently doing a project using DotNetNuke, and we’re using JQuery plugins to achieve certain content rotation and scroller functionality.  All was ‘amost’ good as I’d found a way to inject the JQuery script to the page header on a per-skin basis, but in ‘edit’ mode the actions button wasn’t showing up at the top of containers in FireFox and was causing JavaScript errors in IE.

I’d already gone through the hoops of declaring jQuery.noConflict(), but it still appeared to be conflicting with the dnn:actions (solpartactions) control.  I’d read somewhere else about Solpart code being incompatible with JQuery.

I tried one last thing, adding the noConflict() call in the JQuery library script file itself – rather than running as a fragment on page load.  This fixed everything, as something else was obviously getting in and hijacking in the meantime.  Apparently with V5 this will all be fixed as JQuery’s more integrated with the framework.  Anyway, for those interested here’s what I had to do to get JQuery (and associated plugins) talking nicely whilst still allowing the actions menu to pop up on my containers…

  1. Amend the JQuery library (jquery.1.x.x.min.js) by adding the following line at the bottom…

    jQuery.noConflict();

  2. Amend the skin you want to load the jquery library (and plugins) in (we’ve got it only in specific skins to avoid the overhead where it’s not required).  You could also do this in the module by checking ‘if loaded’, but here’s the code for a skin (in ascx file)…

    <script runat=”server”>
        Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
            ‘add a script reference for Javascript to the head section
            AddScript(“/js/jquery.scrollable-1.0.2.min.js”)
            AddScript(“/js/jquery.mousewheel.js”)
            AddScript(“/js/jquery-1.3.2.min.js”)
        End Sub
       
        Private Sub AddScript(ByVal fileName As String)
            Dim oLink As New HtmlGenericControl(“script”)
            oLink.Attributes(“language”) = “javascript”
            oLink.Attributes(“type”) = “text/javascript”
            oLink.Attributes(“src”) = fileName
            Dim oCSS As Control = Me.Page.FindControl(“CSS”)
            If Not oCSS Is Nothing Then
                oCSS.Controls.AddAt(0, oLink)
            End If
        End Sub
    </script>

    The order is important, as we’re adding the scripts to the ‘top’ of the scripts each time.  JQuery needs to be the first referenced.

  3. Make sure that anywhere you use jQuery you use the jQuery(xx) syntax, and not $(xx).

That’s it.

ASP.NET Data Binding – Accessing a parent data item from within a nested repeater

I’m maintaining an app at the moment that uses quite a few nested repeaters, and found that headers were being output when there was no data present.  It was found that the header was being written in the ItemTemplate of an ‘outer’ repeater, rather than as the HeaderTemplate of the ‘inner’ repeater.  The next problem was how to reference the outer repeater from the ‘inner’ HeaderTemplate…

The following will bind to a field called HeaderDescription.

<%# DataBinder.Eval(Container.Parent.Parent, “DataItem.HeaderDescription”) %>

The parent of the inner item is it’s repeater, so you have to go to it’s parent to get the right RepeaterItem.  Why don’t you just do the following you ask?

<%# DataBinder.Eval(Container.Parent.Parent.DataItem, “HeaderDescription”) %>

..’cos it doesn’t work – The Eval method expects a ‘Control’ as its first parameter.  There’s other ways to do this server-side, but the first option is probably the easiest.

To complete the picture and only show when there’s data you can add the following to the ‘inner’ repeater declaration

OnItemDataBound=”ItemDataBound” Visible=”false”

then..

        protected void ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item)
            {
                if (!e.Item.Parent.Visible)
                    e.Item.Parent.Visible = true;
            }

        }

This will ensure that you’ll only show if you’ve bound a ‘data’ item (remember you’re doing binding in the HeaderTemplate too).  You could also hook similar things into other events, but it’s generally more convenient to put these things into events that relate to the actual control (pre_render’s probably another good candidate as it will only get called once and you can check the count in the DataSource).

Technorati Profile

Removing references to HttpModules from ASP.NET SubFolders in web.config

If you have ASP.NET applications that live as subfolders of a larger site, you may find yourself with issues when it tries to find assemblies and httpmodules that are referenced in the parent’s web.config.

Fortunately this is something you can work around.  Matthew Nolton goes through how you ‘remove’ these references at the subfolder level using the <remove> element.

This is all fine until you get an even tastier situation like I encountered the other day…

ASP.NET application ‘A’ lives as subfolder ‘B’ of both parent site ‘C’ and ‘D’.  The configuration of ‘C’ and ‘D’ is slightly different (modules, handlers, assemblies etc).  Why is this a problem you ask?  We were trying to be a bit clever (and failed :) ) by only deploying application ‘A’ once.  Virtual directories in site ‘C’ and ‘D’ both point to the same physical ‘A’ folder.  This effectively means that the stuff that needs to be removed from ‘A’ varies depending on which parent site you’re accessing.

OK – I could just fix this by duplicating the installation, and varying the configuration but….

You can also remove all modules by adding a ‘clear’ element as follows…

<httpModules>
    

<clear/>

</httpModules>

This is fine, BUT if you’re using Session State or any other in-built features that are implemented as httpModules then you’ll get exceptions as ASP.NET will give you a ‘null’ session for instance.

The following is probably a safe list of modules you’d normally need (maybe even only the session for simple apps), so just add them back in after the ‘clear’….

<httpModules>
    
<clear/>
    
<add name=”OutputCache” type=”System.Web.Caching.OutputCacheModule”/>
    
<add name=”Session” type=”System.Web.SessionState.SessionStateModule”/>
    
<add name=”WindowsAuthentication” type=”System.Web.Security.WindowsAuthenticationModule”/>
    
<add name=”FileAuthorization” type=”System.Web.Security.FileAuthorizationModule”/>
</httpModules>

This is nicer for a couple of reasons

  1. It shows what dependencies the application has on ASP.NET/external features, and…
  2. It gives you the power back to have the application consumed by multiple sites as you’ve effectively decoupled yourself from the parent’s dependencies.

Serving SSL from localhost on IIS 5 on Windows XP using Self-Signed certificates

I’ve probably glossed past this a few times, but it turns out getting SSL working on your dev machine is less painful than you’d think…

  1. install iis60rkt.exe from http://www.microsoft.com/downloads/details.aspx?FamilyID=56fc92ee-a71a-4c73-b628-ade629c89499&DisplayLang=en on your local machine. It’s intended for IIS 6.0 but it works
    in IIS 5.1.
  2. Select custom install if you only want to use SelfSSL.
    Otherwise, install all.
    There’s a lot of other useful stuff there.
  3. Select Programs –> IIS Resources –> SelfSSL –> SelfSSL
    command prompt
  4. In the command prompt, you’ll see a list of all possible
    command parameters..
    1. Type ‘selfssl.exe
      /V:60′     This indicates the certificate is valid for 60 days
    2. Type Y to answer the
      question “Do you want to replace the SSL settings for site 1 (default website)
      ?
    3. Type ‘iisreset’ to
      restart IIS.

If your browser prompts something like ‘Certification Authority not recognised’ (in Firefox), just put the url in the exception list or override the warnings when viewing the page.


Thanks to Ricky for getting this info together.

More reasons to love JQuery

I’ve only recently started using JQuery, but needless to say – it rocks!

for those that don’t know it’s a Javascript library that’s basically revolutionising how you write client-side code.  My reasons to love JQuery.

  1. It’s open source, well tested and an open design.  This means you write less code and you can rely on functionality just ‘working’ in different browsers – or gracefully failing if something’s not right.
  2. It’s really light (especially when ‘packed’ – 31kb)
  3. It’s got a strong community with lots of really cool plugins (just take a look before you start developing that ‘widget’ in flash)
  4. It plays well with other libraries and code.  you just use it for what you need and plugins sit with other plugins.
  5. It’s obviously gaining momentum, as Scott Hansleman announced Microsoft are going to ship it with ASP.NET MVC and Visual Studio (that’s a pretty amazing move from Microsoft).

If you’re just getting started with it, and you’re familiar with Javascript already I’d start with the tutorials.  Some are better than others, but run through the first couple to understand how it works, then scan down the list to find something related to what you need to do.  Typically you’ll be wanting to write a plugin, so I found this one quite good for starters.

You should find everything you need in the Documentation

you’ll then spend most of your time in the API section, looking for specifics on how to do things.