Lightswitch Deployment for 3-tier app

I’ve been having a problem trying to deploy my first Lightswitch app to IIS, where the first Application Administrator isn’t being created.

I kept getting an error similar to “unable to create the application administrator”.

Google eventually brought me to look at the MSDTC settings on the IIS server, but that definitely wasn’t the right direction.

However, I did find the following thread which provided the solution:

http://social.msdn.microsoft.com/Forums/hu/lightswitch/thread/615aaa1b-4f37-40a1-ace2-0735c294c57e

I set “enlist = false” within the web.config application string for my database connection, and this resolved the issue!

 

I’m still impressed by LightSwitch, although I’ve been finding myself wishing it was easier to use custom SQL queries when building the datasets.

Set default value for lookup parameter in Lightswitch

I’ve begun developing an IT Inventory project within Visual Studio Lightswitch, both for use and to learn the product so that I can use it on a new line-of-business application for my company.
While working through this, I came across the need to set a default value for a parameter and I struggled for a long time to find the answer.

 

Luckily there are great resources like Stackoverflow, which has given me an answer in less than 24 hours!

My full question (and the answer) can be found here: http://stackoverflow.com/questions/13710308/set-default-value-for-parameter-in-lightswitch but below is a little background on what I’m trying to do.

 

There are multiple “Companies” to which our assets can be assigned, but 90% of the assets belong to CompanyA. When opening my default screen that displays the list of inventory items, I want it to default to CompanyA, with an option to change it afterwards.

So I’ve created a Query on my data source, assigned a parameter, and then added the proper data objects within the screen to provide the filter. It was trying to set a default for that parameter which was causing me problems.

 

I’m actually quite impressed by LightSwitch; it has enabled me to build this Inventory application in less than a week’s worth of time. There have been some quirks to work around, and you’ll want to be sure that you have a final decision on what type of data source you’re using (SQL vs RIA Service in my case) before proceeding with lots of work since you can’t change the screen’s data source later.

I bring this up because I started using two SQL data sources which are separate databases but have a join. LightSwitch makes this a ‘virtual join’ and thus doesn’t allow you to make queries and filters on the second data source. I’ve since converted to a RIA Service and am now redeveloping the application.

 

 

 

 

 

Mindtouch – Add links to horizontal link bar in Beechbeta-pale

For the Mindtouch wiki at my company, I have taken a copy of Beechbeta-Pale and modified it to closer match our corporate image. Part of this modification includes the horiztonal link bar just below the wiki logo, as identified here:

horizontal menu bar with links

 

These links can be modified quite easily, which is great because this area provides a highly visible spot for common links.

To modify this area you’ll need SSH access to your wiki.

  • Navigate to: /var/www/dekiwiki/skins/beechbeta/pale (or your custom skin)
  • Modify html.php with Nano or your chosen file editor.
  • Find the line containing “<ul class=”nav”>” (around line 43)

If you want to add a static link, it will be in this form:

<li><a href="ftp://ftp.domain.com" title="">FTP</a></li>

You can add the class “first” to the <li> to add a vertical bar on the left, or class “last” to add a vertical bar on the right.

Comment out any predefined php functions (such as Watched Pages) that you don’t want to appear).

Something additional I did on my wiki was separate links from the left and right on the horizontal link bar.

For the links that you want to appear on the right, add a new class name to your <li> such as “customlink”.

Then open the “_style.php” file from the same location as html.php, and jump down to around line 144, which should be “.nav last”.

Add the following with your custom class name just below that:

.nav .customlink{
float:right;
}

 

Now your links should appear something like this:

PHP form with Active Directory attribute lookup

With the Mindtouch wiki I have set up, I occasionally use a small form and mysql database to meet someone’s needs. Right now that happens to be a few sign-up tables for some training sessions.

I do this with an html form right in the page, pointing to a php file within the wiki’s OS, to a new mysql database on the linux VM that the wiki is packaged with. This way this form and database is externally available to my users without having to open up additional resources through our reverse proxy.

 

One problem I came across is that the usenames are first initial last name, such as jmiles. However for readability I wanted this to be Jeff Miles. Despite using Active Directory single sign on for Mindtouch, it doesn’t record or use the AD displayname attribute unless you specifically tell it to, and then only for new users.

Instead I have just incorporated an extra lookup into my PHP file to do the lookup for me.

HTML Form:
This form is placed within the source editor on your wiki page.
 

<form action="/config/qms_training.php" method="post">
	<table align="center" border="0" cellpadding="1" cellspacing="1" frame="box" style="width: 550px; border-style: solid; border-width: 1px;">
		<thead>
			<tr>
				<th scope="col">Training Session:</th>
				<th scope="col">Manager Name:</th>
				<th scope="col">&nbsp;</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td><select name="session"><option selected="selected" value=""></option><option value="sp_nov17_830">SP - November 17 - 8:30 AM</option><option value="sp_nov17_100">SP - November 17 - 1:00 PM</option><option value="sp_nov18_100">SP - November 18 - 1:00 PM</option><option value="sp_nov23_830">SP - November 23 - 8:30 AM</option><option value="sp_nov23_100">SP - November 23 - 1:00 PM</option><option value="sp_nov24_830">SP - November 24 - 8:30 AM</option><option value="sp_dec2_100">SP - December 2 - 1:00 PM</option><option value="sp_dec8_830">SP - December 8 - 8:30 AM</option><option value="sp_dec19_100">SP - December 19 - 1:00 PM</option><option value="sp_dec20_100">SP - December 20 - 1:00 PM</option><option value="bv_dec6">BV - December 6 - 5:30 PM</option><option value="cg_dec22_1100">CG - December 22 - 11:00 AM</option><option value="cg_dec22_100">CG - December 22 - 2:00 PM</option><option value="gp_nov29_100">GP - November 29 - 1:00 PM</option><option value="gp_nov30_800">GP - November 30 - 8:00 AM</option><option value="lb_dec23_1000">LB - December 23 - 10:00 AM</option><option value="online">Online Session (Exam Required)</option></select></td>
				<td><input name="manager_name" /></td>
				<td><input type="submit" value="Submit" />
                                <!-- This line below is the important part, to take the current wiki user -->
                                <input name="username" type="hidden" value="{{user.name}}" /></td>
			</tr>
		</tbody>
	</table>
</form>

 

PHP file:
This php file is placed on the wiki, in /var/www/dekiwiki/config
 

<?php
// variable takes current logged on user from the Dekiscript in the form.
$wikiusername = $_REQUEST['username'];
 
// Active Directory Username to Display name conversion
// Takes the wiki username, checks AD and returns full name
        $dn = "OU=UserAccounts,DC=domain,DC=ca";
    //$username = $_SERVER['REMOTE_USER'];
    $username = $wikiusername;
    $attributes = array("displayname");
    $filter = "(samaccountname=".$username.")";
    $ad = ldap_connect("ldap://server.domain.ca") or die("Couldn't connect to AD!");
    ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3);
    $bind = ldap_bind($ad,"user@domain.ca","password") or die("Couldn't bind to AD!");
    $result = ldap_search($ad, $dn, $filter, $attributes) or die ("ldap search failed");
    $entries = ldap_get_entries($ad, $result);
                if ($entries["count"] > 0)
                        {
                                for ($i=0; $i<$entries["count"]; $i++)
                                        {
                                                $fullname = $entries[$i]["displayname"][0];
                                        }
                        }
        // Close the connection
        ldap_unbind($ad);
 
 
// Remainder of the variables from the form
$session = $_REQUEST['session'] ;
$manager_name = $_REQUEST['manager_name'] ;
$username = $fullname;
 
// Define the connection parameters to connect to the MySQL database.
// This is a local database on the wiki VM.
$conn = mysql_connect("localhost", "root", "password");
mysql_select_db("qms_training",$conn);
 
// If connection does not work, let the user know
 
if (!$conn)
 {
  die('Could not connect: ' . mysql_error());
 }
// Actual SQL command to insert new data into database. The On DUPLICATE KEY UPDATE command ensures
// That if the key exists, it will be updated instead of a new one created.
 
$username = mysql_real_escape_string($username);
$manager_name = mysql_real_escape_string($manager_name);
 
$sql="INSERT INTO session_tracking (username, manager_name, session)
VALUES ('$username','$manager_name','$session')
ON DUPLICATE KEY UPDATE session=VALUES(session), manager_name=VALUES(manager_name)";
 
// Provides feedback for the user to know their submission was successful
if (!mysql_query($sql,$conn))
{
die('Error: ' . mysql_error());
}
echo $username . ", your training session booking has been added.\n Please wait while the page is refreshed.";
mysql_close($con)
 
?>
<!-- redirects user back to the wiki page -->
<meta http-equiv="refresh" content="4;url=http://wiki.domain.ca/Resources/QMS/QMS_Training/QMS_Training_Sign_Up" />

 

Output in the wiki page:
Place this text in the WYSIWYG editor on your wiki page. It will pull from your mysql database and display in table format. This requires the setup of an additional mysql extension, described here: http://developer.mindtouch.com/App_Catalog/MySql

{{ mysql_qms_training.table{query: "SET @rank=0; SELECT @rank:=@rank+1 AS Count, username as 'Name', manager_name as Manager FROM session_tracking WHERE session = 'sp_nov17_830' ORDER BY username"} }}

 

Now, you’ll have output on your wiki page, with proper attributes from AD!
(table shrunk for this image, it’ll actually be wider)

Mindtouch – Show additional Active Directory information for user

Beginning with Mindtouch 10.0, a feature for User Dashboards was added. Effectively this is an additional set of tabs within the “My Page” section for each user page on your wiki.

Display dashboard tabs.

 

Included in this Mindtouch has created an “Activity Dashboard”, which is a pretty great feature. For me and my company, it didn’t quite fit what we needed, so we have modified it, as well as added an additional tab within the dashboard.

This post details how to add those additional tabs. In a future post I’ll show how I’ve modified the Activity Dashboard.

What I wanted to provide for my users was a central spot to view additional Active Directory information about the user who’s page they were viewing. I originally wanted to place this information within the Activity Dashboard, but couldn’t get that working for some reason I can’t remember. Instead I ended up with a separate tab within the user dashboard.

None of this would have been possible without this post from crb on the Mindtouch developer forums.

To start you’ll need to have ssh or console access to your wiki. Navigate to /var/www/dekiwiki/deki/plugins/user_dashboard.

Create a new folder with a related name to your new tab (“adpull” for example).

Inside that folder, create a php file with the same name as the folder: adpull.php

Fill out that php file with the following code. Take note of the comments separating the common code for additional dashboard tabs and the actual content of that tab.

<?php
// Replace references of "adpull" with your chosen name, but don't change anything else in this code.
// This can probably be made easier with a php variable rather than repeated instances of the text.
 
DekiPlugin::registerHook(Hooks::DATA_GET_USER_DASHBOARD_PLUGINS, array('adpull', 'getDashboardPluginsHook'));
 
class adpull extends UserDashboardPage
{
        protected $pluginFolder = 'adpull';
 
public static function getDashboardPluginsHook(&$plugins, $User) {
                $Plugin = new self($User);
                $plugins[] = $Plugin;
        }
 
        public function initPlugin() {
                $this->displayTitle = 'Info';
  //            $this->pagePath = 'Template:MindTouch_UserWelcome';
//              parent::initPlugin();
        }
 
        public function getPluginId() {
                return 'adpull';
        }
 
// Fill out the following function with what you want to populate your tab page with. 		
  public function getHtml() {
 
	// This sets up a connection to an Active Directory server to pull various attribues for the user page
   $dn = "OU=UserAccounts,DC=domain,DC=ca";
    $attributes = array("title", "department", "l", "telephonenumber", "mail");
    $username = $this->User->getUsername();
    $filter = "(samaccountname=$username)";
    $ad = ldap_connect("ldap://server.domain.ca") or die("Couldn't connect to AD!");
 
    ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3);
 
    $bd = ldap_bind($ad,"user@domain.ca","password") or die("Couldn't bind to AD!");
    $result = ldap_search($ad, $dn, $filter, $attributes);
    $entries = ldap_get_entries($ad, $result);
 
		// For the results in the array, put them into this html output.
    for ($i=0; $i<$entries["count"]; $i++)
    {
        $html = '<div style="float:left; font-weight:bold;padding-right:5px;">Title: <br /> City: <br /> Telephone: <br /></div>'
        .$entries[$i]["title"][0].
        "<br />"
        .$entries[$i]["l"][0].
        "<br />"
        .$entries[$i]["telephonenumber"][0].
        //"<br />"
        //'<a href="mailto:'.$entries[$i]["mail"][0].'">'.$entries[$i]["mail"][0].'</a>'
        //.$entries[$i]["mail"][0].
        "<br />";
        $html .='
        <div style="float:left; font-weight:bold;padding-right:32px;">Email: </div>
        <a href="mailto:'.$entries[$i]["mail"][0].'">'.$entries[$i]["mail"][0].'</a>';
    }
    ldap_unbind($ad);
        //$html .=$template;
    return $html;
    }
}

 

The example above pulls out AD attributes for the page that’s being viewed. You could just as well fill the php function with:

$html .='Hello World';
return $html;

Now all you need to do is enable this page in the configuration of Mindtouch.
Navigate to the control panel, and choose Configuration

 

Choose “Advanced Config”

 

Find the config key ui/user_dashboards, and then add a comma and the name of what you named your folder:

user_page,Template:MindTouch/Views/ActivityDashboard, adpull

Save that change, and now you should see an additional tab on your user dashboard: