Tag Archives: dotnet

Running shell (bash) commands in .NET Core C#

In a lot of languages and platforms, you can easily execute shell or bash commands – like using back tick for example in PHP:
[php]
`echo hello`;
[/php]

In the .NET Core world, it’s a little bit more involved – so I wrote a helper class:

[csharp]
using System;
using System.Diagnostics;

public static class ShellHelper
{
public static string Bash(this string cmd)
{
var escapedArgs = cmd.Replace("\"", "\\\"");

var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = $"-c \"{escapedArgs}\"",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
}
};

process.Start();
string result = process.StandardOutput.ReadToEnd();
process.WaitForExit();

return result;
}
}

[/csharp]

It’s an extension method, so after importing the namespace (if different), you can use it like this:

[csharp]
var output = "ps aux".Bash();
[/csharp]

output will contain the STDOUT of the result. Currently STDERR is not captured, but the above could easily be modified to do just that by changing the property RedirectStandardOutput and reading process.StandardError.

Dictionary Model Binder in ASP.NET MVC2 and MVC3

In a decidedly typical turn of events, Microsoft changed the API of BindModel in ASP.NET MVC 2 such that it breaks DefaultDictionaryBinder. No longer can you enumerate through the ValueProvider, instead you can only Get a value which you know the name of. I’ve updated the code to work with MVC2 and also tested it with the new MVC 3 RC.

The code is compatible with ASP.NET MVC 1, 2 and 3. To use it for ASP.NET MVC 1, just set the conditional compiler directive ASPNETMVC1 and it will enable the MVC 1 code, otherwise it will work with MVC version 2 and 3.

The code is now up at github: DefaultDictionaryBinder.cs.

There’s also an example MVC3 project showing the basic functionality of the Dictionary Binder: link

An intuitive Dictionary Model Binder for ASP.NET MVC

The other day I was working on an ASP.NET MVC website and came across a need to post an array from the browser into the web app. The framework comes with something called a Model Binder that automagically converts submitted form data into action parameters of the controller. For example, if we have form submitted data such as
person.FirstName=John&person.LastName=smith
for a theoretical model class ‘Person’, and
[csharp]public ActionResult SavePerson(Person person)[/csharp]
as the action method signature, SavePerson will be executed with the parameter equivalent to
[csharp]new Person() { FirstName = "John", LastName = "Smith" }[/csharp]

The default model binder is pretty powerful, using reflection to dig out and assign all the fields. It also supports arrays and dictionaries, but with big limitations. The array must start at 0 and be unbroken. That is understandable for arrays, but what if you had a dictionary? Surely it can start at any position? Not so. The dictionary has even more obscure requirements, with the need to specify explicit .Key and .Value parameters in your form submission. For example:
dict[0].Key=mykey&dict[0].Value=myvalue
This represented extra work to generate the form on the client side. I just want to input something more intuitive like:
dict[mykey]=myvalue
The ASP.NET MVC framework is highly extensible. It allows you to define your own custom model binder so that’s exactly what I did. Inheriting off DefaultModelBinder, I created DefaultDictionaryBinder that overrode the BindModel method and intercepts when a IDictionary<,> class is being bound.

The code is now up at github: DefaultDictionaryBinder.cs. Note that if you are using this on ASP.NET MVC 1, please define the macro ASPNETMVC1. If you are using it with MVC 2 or MVC 3, it should work as is.

To use, you have to override the default model binder. In global.asax.cs in Application_Start(), add the line:
[csharp]
ModelBinders.Binders.DefaultBinder = new DefaultDictionaryBinder();
[/csharp]

The code is very flexible, only requiring the dictionary key to be of a basic type convertible from string, ie. Dictionary or Dictionary. The value can be any object that is able to be bound by the default model binder.
An example follows:
If your form input is
persons[3].FirstName=John&persons[3].LastName=Smith&persons[4].FirstName=Jane&persons[4].LastName=Doe&
and our action signature
[csharp]public ActionResult SavePersons(Dictionary<int, Person> persons)[/csharp]
the persons parameter would be
[csharp]
new Dictionary<int, Person>() {
{ 3, new Person() {"John", "Smith"} },
{ 4, new Person() {"Jane", "Doe"} },
}
[/csharp]

Simple and intuitive.

Download: DefaultDictionaryBinder.cs Simple Example Project (ASP.NET MVC 3 required)

Thinking about Geolocation APIs for Windows Mobile

Since owning a WinMo phone (or windows phone?), I’ve been thinking of developing some real applications on it. Currently, Geolocation is all the rage, allowing a application to respond different depending on your current location. This is done automatically via different mechanisms such as the most obvious and accurate one, GPS, and less reliable ones such as Cell Tower ID and nearby WIFI hotspot mac addresses.

So I set about searching for a Geo-Location API for windows mobile. Unfortunately, compared to Android and iPhone, the WinMo API is severely lacking in this regard. There seems to be some support in the next version of the .NET Compact Framework (4), but nothing in the current released APIs.

So I set about looking at third party APIs, most notably Google Gears. Google Gears is a framework that plugs into browsers, giving web pages expanded functionality such as offline storage. It also provides what appears to be, a comprehensive Location API, supporting gps, cell ID, and wifi for positioning and returning the Longitude/Latitude and street address. There are 2 gear plugins available for Windows Mobile, one for IE Mobile and one for Opera Mobile. The gears framework API seems to be available only to web browsers, thus web page developers, but not normal application developers.

So I set about seeing if I can access the google location web service directly. Helpfully, google posts the web service API specifications to build your own location API service provider. Unfortunately, it doesn’t tell you where the google service end point is. According to this page, google only allows interaction with the location service via Gears API. So it seems that even if you sniffed out the end point URL, you’ll be in violation of the google TOS to use the service.

But all is not lost – a workaround to all this, is to somehow embed Google Gears in your own application. Since google gears is open source software, BSD licensed, you can freely embed and distribute it along with your application. Searching the web, there seems to be very little information regarding embedding. Looking at the source, there are code relating to integrating with specific browsers. Ideally, we should link with a distributed google gears runtime by emulating an already defined browser interface. The NPAPI interface seems to be the most hopeful. I suspect Gears for Opera Mobile uses the NPAPI interface.

My aim is to provide a Windows Mobile .NET CF interface to the location api of google gears. If I am successful in that endeavour, there will a part two of this post. If not, I hope this post helps someone out there.

Getting the intersection points of two [path] geometries in WPF

While working on an app that utilises geometries in WPF, I needed a way to get the intersection points of the lines of two arbitrary geometries. A google search didn’t yield any useful hints except a post suggesting to use mathematics. That would be ideal for very simple geometries like lines, but with complex geometries, it becomes tiresome real quick. The framework doesn’t seem to have any built in functions that calculate that, so it’s time for some hack and slash.

After a few days of thinking, I came up with a simple, yet effective (but not the most efficient solution). For those who just want the intersection between two geometries, there is the CombinedGeometry geometry class which takes input in the form of two geometries. Setting the GeometryCombineMode to Intersect gives a geometry which is the intersection of the two. At the otherside of the WPF realm, we have Geometry.GetWidenedPathGeometry(). This method basically converts/strokes path lines to an approximate geometry. Combining these two concepts, we can produce an intersection from two widened path geometries (the two paths which we want the intersection of).

[csharp]
public static Point[] GetIntersectionPoints(Geometry g1, Geometry g2)
{
Geometry og1 = g1.GetWidenedPathGeometry(new Pen(Brushes.Black, 1.0));
Geometry og2 = g2.GetWidenedPathGeometry(new Pen(Brushes.Black, 1.0));

CombinedGeometry cg = new CombinedGeometry(GeometryCombineMode.Intersect, og1, og2);

PathGeometry pg = cg.GetFlattenedPathGeometry();
Point[] result = new Point[pg.Figures.Count];
for (int i = 0; i < pg.Figures.Count; i++)
{
Rect fig = new PathGeometry(new PathFigure[] { pg.Figures[i] }).Bounds;
result[i] = new Point(fig.Left + fig.Width / 2.0, fig.Top + fig.Height / 2.0);
}
return result;
}
[/csharp]

The function will return an array of zero or more points of intersection. To test it

[csharp]
sg1 = StreamGeometry.Parse("M0,0 L100,100");
sg2 = StreamGeometry.Parse("M0,100 L100,0");
Point[] pts = GetIntersectionPoints(sg1, sg2);
// pts[0] is {50,50}
[/csharp]

Hope this helps someone.

The curious case of WindowsFormsParkingWindow

I was debugging a problem the other day involving WebKit.NET, a webkit wrapper control for winforms. When the webkit control was hosted inside winforms, it had a strange problem of always thinking that it is out of focus. This had the effect of drawing all selections as grayed out.

Everything I threw at it (WM_SETFOCUS, WM_ACTIVATE) seemed to be going into a void, so it was time to break into the source and figure out what exactly was wrong. After a few breakpoints and step overs, I found that the WebKit control searches for the parent window and listens to its messages by subclassing the window. It listens for WM_NCACTIVATE event and then determines whether it has focus or not.

This was working exactly as expected on a normal non-winforms window, so what was different? Debugging the code, I found that it got the root parent window as WindowsFormsParkingWindow. Why is it returning that as the parent window and not the actual parent window I’m not entirely sure. Maybe it’s some special super root window like the Application window in Delphi? It wasn’t shown in Spy++ either. Then again what’s a WindowsFormsParkingWindow? It’s something that I ought to google. Unfortunately google wasn’t very forth coming. Puzzled, I devised a hack by simply temporarily unassigning the immediate parent window of the webkit control WS_CHILD, simply because the webkit find ancestry detection algorithm stops when it encounters a non-child. After the setHostWindow() call, I make the parent window WS_CHILD again. That seemed to work but something lingered in the back of my mind telling that there is a better solution.

The next day as I was about to post a solution on the mailing list describing my solution, just when I was about to talk about this weird WindowsFormsParkingWindow, something in my mind clicked. Suddenly it all seemed to make sense. There was a reason WindowsFormsParkingWindow wasn’t in the tree ancestry when I looked at Spy++. There’s also a reason for the name. It turns out that on creation, all controls get put into WindowsFormsParkingWindow. It just so happens the setHostWindow call was made in the constructor when the parent control was still parked. The solution seemed obvious now. The setHostWindow should be called after the parent is correctly set, ie on the Load event. So, another case closed.