HttpPostedFileBase returning absolute path for FileName in IE6
Just a short one – When posting a file from IE6 the FileName on a HttpPostedFileBase will return an absolute path from the client’s machine.
Changing this:
//postedFile is an instance of HttpPostedFileBase
string filename = postedFile.FileName; //borked when posting from IE6
To this:
string filename = Path.GetFileName(postedFile.FileName);
should get around the issue.
Web.Config transformations injecting ‘ReplacableToken’ for connection string
Oh MSBuild, you so crazy. By default MSBuild will not replace connection strings when running Web.Config transformations. The thinking behind this is that if you miss a replacement value out of a Debug config you can’t deploy to a dev server with a release connection string in your Web.Config (from a previous transformation, I guess).
Personally I don’t think this makes sense anyway, but oh well. MSBuild will drop your actual connection string into a SetParameters.xml file in your obj\{Config}\Package directory. You can force MSBuild to transform connection strings through a (massive) MSBuild parameter.
At the command line:
msbuild MyApp.sln /p:AutoParameterizationWebConfigConnectionStrings=false
More at StackOverflow
sqlite3.h missing on Ubuntu
This one is more for my benefit as I forget *every* time.
sudo apt-get install libsqlite3-dev
The dev package should give you the header files needed. If you’re still having issues you may also need the build-essential
package.
Resizing the Android Emulator (when it’s too big)
So after finally getting the Android SDK on my MacBook I ran into this little usability gem, a true Androidism.
Yep, at my 1280×800 resolution the emulator runs off the bottom of the screen, including the resize handle in the bottom right. Thankfully, this blog post has the answer, although it wasn’t what I was expecting.
telnet localhost 5554 (or the port number shown in the emulator menu bar)
window scale 0.8
quit
Oh, how obvious! The post goes on to explain this can also be done through the AVD Manager although this wasn’t met with much success.
What worries me more is that this has been a reported issue since March 2009 (Google Code), yet it’s still here. I wonder how much other stuff I’ll run into over the next few days…
MS-MVC style validations with ASP.NET Web Forms
I haven’t used ASP.NET Web Forms in quite a while. If I had a pound for every time I forgot to add runat=”server” today I probably wouldn’t need to work again.
But I’m using Umbraco (awesome, if you haven’t used it) which is Web Forms based. I had a scenario where I was posting a form asynchronously and wanting to validate it server-side after pulling the values out of the form collection. MVC-style I created a class, added some validation attributes and set about calling IsValid(). Except that IsValid() is on a Page, not my model – useless.
After plenty of Googling I came across this blog post from @ipreferjim. By including his code and changing my model to inherit from Validatable I was able to call IsValid() – Validatable then reflects over the model’s properties, through each validation attribute on a property and checks each are valid.
I’m not sure if data annotations are meant to be used with Web Forms but it seems to work ok. Certainly nothing like MVC model binding but it should come in handy when using Umbraco. It’s not like I’d be using Web Forms for anything else 🙂
MonoTouch.Dialog basics
I’m slightly late to the game with this one, but MonoTouch.Dialog is awesome. If you’ve used it before then this post won’t be of much use, my aim is to give two quick examples to get you up and running.
What is it?
@migueldeicaza describes it as “foundation to create dialog boxes and show table-based information without having to write dozens of delegates and controllers”. In short, it’s a tool to create table views without you having to write an implementation of UITableViewSource for each one.
Why should I use it?
Practically every iOS view uses a table view to display information. Each of these requires a new implementation of UITableViewSource. These require you to implement a minimum of two methods, GetCell and RowsInSection. Often you have to implement many more including NumberOfSections, GetHeightForRow and RowSelected amongst others.
See where I’m heading? They’re not complicated but take up a load of time that could be spent doing other things (like writing more table views).
Attribute-based approach
The easiest way to use MT.Dialog is by adding attributes to a class – this is now our view model. This next bit is a bit dirty but an important point to remember. MT.Dialog will render the controls in the order our fields are declared.
Update: @RobertKozak pointed out that this isn’t strictly true – The order isn’t guaranteed although it usually works out this way. There is an explanation of the GetMembers method in the comments
The privacy property is an enum:
I’ve already added a navigation controller to the view. (MT.Dialog may be able to do this for you, I’ve not come across it yet though). Setup the view model, binding context and view controller. Once we’ve done that we can push the the dialog controller onto our navigation.
Run the solution and get ready for awesomeness…
…and without going anywhere near a UITableViewSource. Notice how we don’t have to handle pushing on our second view ‘Show real name’, MT.Dialog gives us that for free. Once we’re done with the view we can call _loginBindingContext.Fetch(). This will bind the UI back to our view model.
But my view is dynamic…
No problem:
Finishing up
Hopefully I’ve explained how to get started and shown why it’s a great tool. It can be a major timesaver and stops you from reinventing the wheel for every project, or worse, every view.
The project is up on GitHub, just download and add as a reference. GitHub also has the full documentation which is great to get started with. https://github.com/migueldeicaza/MonoTouch.Dialog
It’s also worth grabbing TweetStation, a Twitter client for iPhone. The full thing is built with MT.Dialog. It’s available for free in the AppStore and the code can also be found on GitHub. https://github.com/migueldeicaza/TweetStation
Any questions give me a shout on Twitter.
Cheers
iTunes file sharing with MonoTouch
For my current project I need users to add PDF files onto their iPad to display within an app. I could have asked to host them elsewhere and load in a URL but there’s a nicer and more integrated way – iTunes File Sharing.
If you have used an iWork app or GoodReader (and many others) you may already be familiar with this feature. Here’s how it looks in iTunes.
By default your app won’t display in this list. To enable this we add the key UIFileSharingEnabled into our info.plist file and set the value to true.
In our app we can then do something like the following:
string documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
FileInfo[] userSharedFiles = new DirectoryInfo(documentsPath).GetFiles();
Testing in the simulator can be a bit tricky as you won’t have synced any documents though iTunes. To get around this I grabbed the value out of our documentsPath variable, opened it in Finder and dropped in some files. Depending on which SDK version you are using the path will be something like
/Users/Username/Library/Application Support/iPhone Simulator/4.2/Applications/ApplicationID/Documents/
Straightforward but a really useful feature.
The always grey UITableView
I recently ran into a problem when setting the background colour of a UITableView. Specifically one running on an iPad (iOS 4.2) when the table view style is set to grouped and running under MonoTouch. Regardless of how the background colour property is set (both in code and Interface Builder) the background displays as the default grey.
//this code runs but the colour is never set
tableView.BackgroundColor = UIColor.Clear;
After some help from Twitter and useful StackOverflow post it turned out to be a generic iOS issue. A simple (possibly only) workaround is to set the background view property instead – and then set the required colour on that.
UIView dummyView = new UIView{BackgroundColor = UIColor.Clear};
tableView.BackgroundView = dummyView;
And in ObjectiveC (Taken from the StackOverflow link above)
[tableView setBackgroundView:nil];
[tableView setBackgroundView:[[[UIView alloc] init] autorelease]];
[tableView setBackgroundColor:UIColor.clearColor];
Seems to be an issue on the iPad only. The original code ran on the iPhone just fine.
Thanks to @ChrisNTR, @ArranM and @Fufie.