Saturday, November 19, 2011

MonoCross - a different kind of WP7 project approach

Just thought I'd drop a note about MonoCross. The first Wp7 code was only made available this week and so I've only had a few days to play with it. So far I'm finding it fascinating as an alternative way of thinking about how to construct an app.

I know not everyone is doing multiplatform... and I'm already finding that MonoCross gets in the way of some MVVM and data binding stuff, but I'm also finding that there are some very interesting parts to the way MX approaches development - in particular:

  • MX splits the Model and Controller out into one class library, then puts the Views into the app project
  • MX Views are ultimately PhoneApplicationPage's but you inherit via an MXView<TModel> class - it's quite nice that this means you always get a Model to use
  • The navigation framework intercepts the calls to "routes" like "{Controller}/{Action}/{Id}" - so you no longer have to navigate to urls like "Views/EditThing.xaml?ThingId=12" and the navigation framework also takes care of the Model creation/selection for you.

There's plenty of "rough parts" in there - plenty that will get done differently in the future (e.g. there are static class and static member variables everywhere - Mx desparately needs an injection of IoC) and I'm not sure how blendable this approach is - but overall it's very interesting to see an application structured differently - something other than yet another Mvvm platform.

If you're interested, check it out on http://bit.ly/smT0Di

Stuart

P.S. Just in case you were wondering - I've nothing to do with the MX project - it's got some sort of book publisher behind it. I'm just one of the first 1.0 users (I think!)

Tuesday, November 15, 2011

Using MXTabActivityView in MonoCross (MonoDroid flavour)

1. In your application project, add your model - this model will be *shared* by all views within the tabs, plus also shared by the parent tabview itself:
    public class FirstModel
    {
        public List<string> Items1 { get; set; }
        public List<string> Items2 { get; set; }
        public FirstModel()
        {
            Items1 = new List<string>()
                        {
                            "one",
                            "two",
                            "three"
                        };
            Items2 = new List<string>()
                        {
                            "hello",
                            "world",
                            "monocross"
                        };
        }
    }
  
2. Again in your application project, add your controller:
    public class FirstController : MXController<FirstModel>
    {
        public override string Load(Dictionary<string, string> parameters)
        {
            Model = new FirstModel();
            return ViewPerspective.Default;
        }
    }
3. Finally in the application project, make sure you have a route setup for the controller - e.g. a default route like:
            NavigationMap.Add("", new Controllers.FirstController());
4. In your Android container, add the activity views which will sit inside the tabs - e.g.:
    [Activity(Label = "First View!")]
    public class FirstView : MXListActivityView<FirstModel>
    {
        public override void Render()
        {
            ListView.Adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, Model.Items1.OrderBy(x => x).ToList() );
        }
    }
and:
    [Activity(Label = "Second View!")]
    public class SecondView : MXListActivityView<FirstModel>
    {
        public override void Render()
        {
            ListView.Adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, Model.Items2 );
        }
    }
5. In your Android container project, set up your tab activity view - this is a bit like http://docs.xamarin.com/android/tutorials/User_Interface/tab_layout
Set up the xml resource - e.g.:
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
  <LinearLayout
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:padding="5dp">
    <TabWidget
        android:id="@android:id/tabs"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
    <FrameLayout
        android:id="@android:id/tabcontent"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="5dp">
    </FrameLayout>
  </LinearLayout>
</TabHost>
Also, add the tab icons if you want them (see notes in http://docs.xamarin.com/android/tutorials/User_Interface/tab_layout)
Then for the MXTabActivityView:
    [Activity(Label = "A TabView!")]
    public class TabView : MXTabActivityView<FirstModel>
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.TabHost);
            TabHost.TabSpec spec;     // Resusable TabSpec for each tab
            Intent intent;            // Reusable Intent for each tab
            // Create an Intent to launch an Activity for the tab (to be reused)
            intent = new Intent(this, typeof(FirstView));
            intent.AddFlags(ActivityFlags.NewTask);
            // Initialize a TabSpec for each tab and add it to the TabHost
            spec = TabHost.NewTabSpec("first");
            spec.SetIndicator("First", Resources.GetDrawable(Resource.Drawable.ic_tab_artists));
            spec.SetContent(intent);
            TabHost.AddTab(spec);
            intent = new Intent(this, typeof(SecondView));
            intent.AddFlags(ActivityFlags.NewTask);
            spec = TabHost.NewTabSpec("second");
            spec.SetIndicator("Second", Resources.GetDrawable(Resource.Drawable.ic_tab_artists));
            spec.SetContent(intent);
            TabHost.AddTab(spec);
       }
        public override void Render()
        {
           // nothing to do here currently!
        }
    }
}
6. That's it! run and enjoy :)

Wednesday, November 09, 2011

Storage scopes cannot be created when _AppStart is executing.

If you see this error when running ASP.Net MVC apps:

Storage scopes cannot be created when _AppStart is executing.


Then don't panic  - it seems this is just a Cassini problem - if you switch across to IIS express or to a real IIS server then the problem doesn't exist

(phew)

Friday, November 04, 2011

A honey trap - if anyone's running PHPMyAdmin then people will come looking!

I left a website running for a month on Azure... this is what came attacking:

404  /phpmyadmin/scripts/setup.php 23
404 /pma/scripts/setup.php 14
404 /myadmin/scripts/setup.php 11
404 /content/images/skins/simple/awesome-overlay-sprite.png 8
404 /mysql/scripts/setup.php 6
404 /scripts/setup.php 6
404 /robots.txt 5
400 /w00tw00t.at.blackhats.romanian.anti-sec:) 5
404 /pma2005/scripts/setup.php 4
404 /phpmyadmin2/scripts/setup.php 4
404 /web/phpmyadmin/scripts/setup.php 4
404 /user/soapcaller.bs 3
404 /cube/readme 3
404 /round/readme 3
404 /roundcube-0.2/readme 3
404 /roundcube-0.1/readme 3
404 /roundcubemail-0.1/readme 3
404 /roundcubemail-0.2/readme 3
404 /wm/readme 3
404 /webmail2/readme 3
404 /rms/readme 3
404 /mail2/readme 3
404 /mss2/readme 3
404 /mss/readme 3
404 /roundcubemail/readme 3
404 /rc/readme 3
404 /webmail/readme 3
404 /roundcube/readme 3
404 /mail/readme 3
404 /readme 3
404 /manager/html 3
404 /sql/scripts/setup.php 3
404 /mysqladmin/scripts/setup.php 3
404 /phpmya/scripts/setup.php 3
404 /phpmyadmin1/scripts/setup.php 3
404 /phpmyadmin/config/config.inc.php 3
404 /mini-profiler-results 2
404 /sslmysqladmin/scripts/setup.php 2
404 /admin/phpmyadmin/scripts/setup.php 2
404 /admin/scripts/setup.php 2
404 /bbs/data/scripts/setup.php 2
404 /cpadmin/scripts/setup.php 2
404 /cpadmindb/scripts/setup.php 2
404 /cpanelmysql/scripts/setup.php 2
404 /cpanelphpmyadmin/scripts/setup.php 2
404 /cpanelsql/scripts/setup.php 2
404 /cpdbadmin/scripts/setup.php 2
404 /cpphpmyadmin/scripts/setup.php 2
404 /db/scripts/setup.php 2
404 /dbadmin/scripts/setup.php 2
404 /mysql-admin/scripts/setup.php 2
404 /mysqladminconfig/scripts/setup.php 2
404 /p/m/a/scripts/setup.php 2
404 /mysqlmanager/scripts/setup.php 2
404 /php-my-admin/scripts/setup.php 2
404 /php-myadmin/scripts/setup.php 2
404 /phpmyadmin-2.2.3/scripts/setup.php 2
404 /phpmyadmin-2.2.6/scripts/setup.php 2
404 /phpmyadmin-2.5.1/scripts/setup.php 2
404 /phpmyadmin-2.5.4/scripts/setup.php 2
404 /phpmyadmin-2.5.5-pl1/scripts/setup.php 2
404 /phpmyadmin-2.5.5-rc1/scripts/setup.php 2
404 /phpmyadmin-2.5.5-rc1config/scripts/setup.php 2
404 /phpmyadmin-2.5.5/scripts/setup.php 2
404 /phpmyadmin-2.5.6-rc1/scripts/setup.php 2
404 /phpmyadmin-2.5.6-rc2/scripts/setup.php 2
404 /phpmyadmin-2.5.6/scripts/setup.php 2
404 /phpmyadmin-2.5.7-pl1/scripts/setup.php 2
404 /phpmyadmin-2.5.7/scripts/setup.php 2
404 /phpmyadmin-2.6.0-alpha2/scripts/setup.php 2
404 /phpmyadmin-2.6.0-beta1/scripts/setup.php 2
404 /phpmyadmin-2.6.0-beta2/scripts/setup.php 2
404 /phpmyadmin-2.6.0-pl1/scripts/setup.php 2
404 /phpmyadmin-2.6.0-pl2/scripts/setup.php 2
404 /phpmyadmin-2.6.0-pl3/scripts/setup.php 2
404 /phpmyadmin-2.6.0-rc1/scripts/setup.php 2
404 /phpmyadmin-2.6.0-rc2/scripts/setup.php 2
404 /phpmyadmin-2.6.0-rc3/scripts/setup.php 2
404 /phpmyadmin-2.6.0/scripts/setup.php 2
404 /phpmyadmin-2.6.1-pl1/scripts/setup.php 2
404 /phpmyadmin-2.6.1-pl2/scripts/setup.php 2
404 /phpmyadmin-2.6.1-pl3/scripts/setup.php 2
404 /phpmyadmin-2.6.1-rc2/scripts/setup.php 2
404 /phpmyadmin-2.6.1/scripts/setup.php 2
404 /phpmyadmin-2.6.2-beta1/scripts/setup.php 2
404 /phpmyadmin-2.6.2-pl1/scripts/setup.php 2
404 /phpmyadmin-2.6.2-rc1/scripts/setup.php 2
404 /phpmyadmin-2.6.2/scripts/setup.php 2
404 /phpmyadmin-2.6.3-pl1/scripts/setup.php 2
404 /phpmyadmin-2.6.3-rc1/scripts/setup.php 2
404 /phpmyadmin-2.6.3/scripts/setup.php 2
404 /phpmyadmin-2.6.4-pl2/scripts/setup.php 2
404 /phpmyadmin-2.6.4-pl3/scripts/setup.php 2
404 /phpmyadmin-2.6.4-pl4/scripts/setup.php 2
404 /phpmyadmin-2.6.4-rc1/scripts/setup.php 2
404 /phpmyadmin-2.6.4/scripts/setup.php 2
404 /phpmyadmin-2.7.0-beta1/scripts/setup.php 2
404 /phpmyadmin-2.7.0-pl2/scripts/setup.php 2
404 /phpmyadmin-2.7.0-rc1/scripts/setup.php 2
404 /phpmyadmin-2.7.0-rc1/scripts/setup.php 2
404 /phpmyadmin-2.7.0/scripts/setup.php 2
404 /phpmyadmin-2.8.0-beta1/scripts/setup.php 2
404 /phpmyadmin-2.8.0-rc1/scripts/setup.php 2
404 /phpmyadmin-2.8.0-rc2/scripts/setup.php 2
404 /phpmyadmin-2.8.0.1/scripts/setup.php 2
404 /phpmyadmin-2.8.0.2/scripts/setup.php 2
404 /phpmyadmin-2.8.0.4/scripts/setup.php 2
404 /phpmyadmin-2.8.1-rc1/scripts/setup.php 2
404 /phpmyadmin-2.8.1/scripts/setup.php 2
404 /phpmyadmin-2.8.2/scripts/setup.php 2
404 /phpmyadmin-2/scripts/setup.php 2
404 /phpadmin/scripts/setup.php 2
404 /phpmanager/scripts/setup.php 2
404 /phpmy-admin/scripts/setup.php 2
404 /roundcube/scripts/setup.php 2
404 /sl2/data/scripts/setup.php 2
404 /sqladmin/scripts/setup.php 2
404 /sqlmanager/scripts/setup.php 2
404 /sqlweb/scripts/setup.php 2
404 /typo3/phpmyadmin/scripts/setup.php 2
404 /web/scripts/setup.php 2
404 /webadmin/scripts/setup.php 2
404 /webdb/scripts/setup.php 2
404 /websql/scripts/setup.php 2
404 /xampp/phpmyadmin/scripts/setup.php 2
404 /~/pma/scripts/setup.php 2
404 /phpmyadmin2/config.inc.php 2
404 /backup/phpmyadmin/scripts/setup.php 2
404 /bkup/phpmyadmin/scripts/setup.php 2
404 /_phpmyadmin/scripts/setup.php 2
404 /phpmy/scripts/setup.php 2
404 /phpmyadmin/index.php 2
404 /phpmyadmin2/index.php 2
404 /phpmyadmin3/index.php 2
404 /cgi-bin/if.cgi 2
404 /admin/pma/scripts/setup.php 1
404 /mail/scripts/setup.php 1
404 /phpmyadmin-2.5.5-rc2/scripts/setup.php 1
404 /phpmyadmin-2.7.0-pl1/scripts/setup.php 1
404 /phpmyadmin-2.8.0.3/scripts/setup.php 1
404 /phppgadmin/scripts/setup.php 1
404 /webmail/scripts/setup.php 1
404 /~/admin/scripts/setup.php 1
404 /~/myadmin/scripts/setup.php 1
404 /~/phpadmin/scripts/setup.php 1
404 /~/phpmyadmin/scripts/setup.php 1
404 /pma/config/config.inc.php 1
404 /admin/config/config.inc.php 1
404 /dbadmin/config/config.inc.php 1
404 /mysql/config/config.inc.php 1
404 /php-my-admin/config/config.inc.php 1
404 /myadmin/config/config.inc.php 1
404 /config/config.inc.php 1
404 /phppgadmin/config.inc.php 1
404 /mail/config.inc.php 1
404 /webmail/config.inc.php 1
404 /wall/data/carbonapple_mono1024.jpg 1
404 /3rdparty/phpmyadmin/scripts/setup.php 1
404 /_admin/scripts/setup.php 1
404 /admm/scripts/setup.php 1
404 /admn/scripts/setup.php 1
404 /databaseadmin/scripts/setup.php 1
404 /phpm/scripts/setup.php 1
404 /phpmyadmin-2.11.10/scripts/setup.php 1
404 /phpmyadmin-2.11.1-all-languages/scripts/setup.php 1
404 /phpmyadmin-2.11.8.1-all-languages-utf-8-only/scripts/setup.php 1
404 /phpmyadmin-2.6.0-alpha/scripts/setup.php 1
404 /phpmyadmin-2.6.1-rc1/scripts/setup.php 1
404 /phpmyadmin-2.8.0/scripts/setup.php 1
404 /phpmyadmin-3.0.0-rc1-english/scripts/setup.php 1
404 /phpmyadmi/scripts/setup.php 1
404 /phpmyad/scripts/setup.php 1
404 /phpmyad-sys/scripts/setup.php 1
404 /php/scripts/setup.php 1
404 /vhcs2/tools/pma/scripts/setup.php 1
404 /wp-content/plugins/wp-phpmyadmin/wp-phpmyadmin/phpmyadmin/scripts/setup.php 1
404 /wp-phpmyadmin/phpmyadmin/scripts/setup.php 1
404 /wp-phpmyadmin/scripts/setup.php 1
404 /nosuichfile.php 1
404 /noxdir/nosuichfile.php 1
404 /pma/index.php 1
404 /mysql/index.php 1
404 /myadmin/index.php 1