Example code:
GDirections directions = new GDirections(startAddress, endAddress);
if (directions.IsValid)
Response.Write(directions.RoutesHtml[0]);
else
Response.Write("Route not valid.");
GDirections directions = new GDirections(startAddress, endAddress);
I've been working on an ASP.NET MVC project with a nice and fancy model layer. My models have a nice'n'friendly UpdateFrom(NameValueCollection) method to bind HTTP request parameters to an object. The only problem is that sometimes, I don't want to have every column on a form, and some of the related database columns should remain unchanged.
In HTML forms, this presents a problem: checkboxes that are unchecked don't post anything. How am I to tell if a field has been left off the form or if a field is unchecked? After some aimless wanderings on the inter-tubes, I found this article which documents a solution for Rails.
It's pretty simple, so I figured I would take this idea and wrap it up in a server control. We have a small set of server WebControls that play nice with the rest of our code, so it was just a matter of adding a few lines of code. You could also wrap this up in a helper method like in the rails version.
CheckBox checkbox = new CheckBox();
checkbox.InputAttributes.Add("class", CssClass);
checkbox.InputAttributes.Add("id", (string.IsNullOrEmpty(ID) ? (FieldName + "CheckBox") : ID));
checkbox.InputAttributes.Add("value", "true");
checkbox.InputAttributes.Add("onclick",
"document.getElementById(\"" + FieldName + "TextBox\").value = this.checked.toString()");
checkbox.Checked = Checked;
checkbox.RenderControl(writer);
TextBox textbox = new TextBox();
textbox.Attributes.Add("style", "display: none;");
textbox.Attributes.Add("id", FieldName + "TextBox");
textbox.Attributes.Add("name", FieldName);
textbox.Text = Checked ? "true" : "false";
textbox.RenderControl(writer);
Now I can tell if a checkbox field is truly meant to either just not be there or is false.
One of my projects needed a wizard form. Being the jQuery fanboy that I am and given that I couldn't find any existing wizard form plugins for jQuery, I made my own! You can check it out here: http://plugins.jquery.com/project/WizardForm
It's not what I would consider finished, but it works if you need a quick form and don't mind dealing with my markup choices. It behaves sort of like the jQuery tabs plugin, so if you have used that, you should be able to get started fairly quickly.
I hate trying to resolve CSS and Javascript conflicts between web browsers. What I hate even worse is going about it in an "unclean" way.
Conditional comments for IE have been around a long time and I haven't really seen too many people (if any) using them for resolving style bugs. Check out what I do on every web site I build.
<link href="/public/css/style.css" rel="stylesheet" type="text/css" />
<!--[if lte IE 7]>
<link rel="stylesheet" type="text/css" href="/public/css/style-ie.css" />
<![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="/public/css/style-ie6.css" />
<![endif]-->
Note that I normally don't bother with IE 5.5, but this could work for that as well. With these CSS links in place, I can simply expect a normal, sane style sheet to be included on well-behaved browsers, a special style sheet for IE7, and an even more "special" style sheet for IE6. Since these are declared in order of insanity, (from least to greatest) I can simply copy style declarations from my original style sheet, override whatever I need to, and keep everything squeaky clean.
There's my solution. If anyone reading still uses CSS hacks, I would love to know why. It may be something I just don't "get."
ALERT! A better, more complete version of this code can be found here: http://www.sagecraft-studios.com/2008/11/google-driving-directions-in-c---update.html
This is something I've been wanting to figure out for a while. What I'll be demonstrating in this post is how to get driving directions, distances, and trip durations from Google's mapping service... without using Javascript! The demonstration code below is just that - a demonstration. It is your job, dear reader, to make a friendly, accessible interface out of the underlying code.
Note: As far as I can tell, this is undocumented. If you're using this in a production environment, I would advise writing some unit tests in case URLs change, parameters change, etc...
You will need JSON.NET referenced to deserialize the data sent from Google.
using Newtonsoft.Json;
namespace xxxx
{
public class GDirections
{
private string _key = "xxxx";
private string _output = "js";
private string _requestFormat = "http://maps.google.com/maps/nav?key={0}&output={1}&q={2}";
private Hashtable _data = new Hashtable();
Our underlying data. Yes, you could certainly use a generic Dictionary rather than a Hashtable. In the code above, make sure to set _key to your Google Maps API key, which can be generated here.
/// <param name="path">A path in the format "From {a} to {b}". Example: "From Lexington, KY to Bowling Green, KY"</param>
public GDirections(string path)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(
string.Format(_requestFormat, _key, _output, Uri.EscapeUriString(path)));
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string json = reader.ReadToEnd();
_data = readJson(new JsonReader(new StringReader(json)));
}
In our constructor, we basically just grab the response from a web page. (or in this case, JavaScript object) Using Json.NET, we deserialize the object and somehow stick it in a Hashtable.
private Hashtable readJson(JsonReader jreader)
{
Hashtable data = new Hashtable();
while (jreader.Read() && jreader.TokenType != JsonToken.EndObject)
{
string key = null;
object value = null;
if (jreader.TokenType == JsonToken.PropertyName)
{
key = (string)jreader.Value;
jreader.Read();
switch (jreader.TokenType)
{
case JsonToken.StartArray:
value = readJsonArray(jreader);
break;
case JsonToken.StartObject:
value = readJson(jreader);
break;
case JsonToken.Null:
case JsonToken.Undefined:
value = null;
break;
default:
value = jreader.Value;
break;
}
}
if (key != null)
data.Add(key, value);
}
return data;
}
private ArrayList readJsonArray(JsonReader jreader)
{
ArrayList value = new ArrayList();
while (jreader.Read() && jreader.TokenType != JsonToken.EndArray)
{
switch (jreader.TokenType)
{
case JsonToken.StartArray:
value.Add(readJsonArray(jreader));
break;
case JsonToken.StartObject:
value.Add(readJson(jreader));
break;
case JsonToken.Null:
case JsonToken.Undefined:
value.Add(null);
break;
default:
value.Add(jreader.Value);
break;
}
}
return value;
}
}
}
This is the "somehow stick it in a Hashtable" (or Dictionary
IDEALLY, we would want to create classes for each kind of object we get in our response. For example, Placemark, Status, Point, and Direction classes would need to be created. If even this is too much work, (which it shouldn't be if you are serious about implementing and fully using this functionality!) some more friendly accessor methods/properties shouldn't be a huge chore to do. For example, since we're using this thing just for driving time and duration, I implemented the following accessors
public decimal DrivingMeters
{
get { return Convert.ToDecimal(((Hashtable)Directions["Distance"])["meters"]); }
}
public TimeSpan DrivingTime
{
get { return new TimeSpan(0, 0, Convert.ToInt32(((Hashtable)Directions["Duration"])["seconds"])); }
}
public decimal DrivingMiles
{
get { return Math.Round(DrivingMeters * (decimal)0.000621371192, 2); } // according to Google.
}
private Hashtable Directions
{
get { return (Hashtable)_data["Directions"]; }
}
So yes, I'm basically saying take this foundation and make it your own. Make it friendly and then give it back to me. :)
Recent Comments