|
iPhone StopWatch Sample (part 3) |
Sunday, January 02, 2011 9:21 PM |
|
The first function is called when the startButton is pressed. If the text of the button
is Start, then we want to disable the resetButton, change the startButton's text to Stop
mark the startTime, and instantiate the timer callback. If the text of the startButton is
not Start, then we want to enable the resetButton, disable the startButton, and invalidate
the timer callback funtion.
The second function handles the resetButton. If the resetButton's been pressed, the timeLabel
is reset to 00:00:00.0, the startButton text is set to Start and enabled, and the resetButton
is disabled.
Finally, we have a function to handle the timer callback. This method is called when
the timer fires - in this case, every 0.1 seconds.
- (void) updateStopWatchLabel { nowTime = [NSDate timeIntervalSinceReferenceDate]; NSTimeInterval interval = nowTime - startTime; int seconds = (int)interval; int tenths = (int)((interval - seconds) * 10); [timeLabel setText:[NSString stringWithFormat:@"%02d:%02d:%02d.%1d",(seconds/3600)%24,(seconds/60)%60, seconds%60, tenths]]; }
In the simulator and on the iPhone, the application looks like this:
Lessons learned
In many of the sample code I ran across on the web, people would use an integer to keep track of the elapsed time.
Don't. NSTimeInterval is a quick way to grab the elapsed time in milliseconds from a fixed reference point. It's
fast, neat, and works well. It would be easy to only have one function handle all the button UI. I kept it in two
functions just to make it clearer, I hope. Enjoy.
Technical
|
|
|
iPhone StopWatch Sample (part 2) |
Sunday, January 02, 2011 9:18 PM |
|
In interface builder, we'll want to hook the UI elements to these variables so we can work with them.
From Xcode's project window, open StopWatchViewController.xib. This will allow you to place the elements
which will comprise the StopWatch application. Place a label and two buttons on the viewcontroller's window
and initialize them with appropriate values. We'll tie the label and buttons to the variables timeLabel, startButton, and
resetButton in StopWatchViewController by Control dragging from the File's Owner to each element. When you release the
mouse, Interface Builder will prompt you for the appropriate variable. We'll also want to tie our two functions,
startButtonPressed and resetButtonPressed to each of our buttons by Control dragging from the buttons to
the StopWatchViewController. Be sure to save your work before switching back to Xcode.
With the buttons and label in place, let's go back to Xcode and modify the implementation file,
StopWatchViewController.m, to put the whole thing together. First, we can add the two functions
to handle each of the button presses:
- (IBAction)startButtonPressed:(id)sender { if ([startButton.titleLabel.text isEqualToString:@"Start"]) { // If the startButton is equal to start when it is pressed we want to // disable the resetButton, change the text of the startButton to Pause, and // start keeping track of the time [resetButton setEnabled:false]; [startButton setTitle:@"Stop" forState:UIControlStateNormal]; startTime = [NSDate timeIntervalSinceReferenceDate]; stopwatchTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateStopWatchLabel) userInfo:nil repeats:YES]; } else { // startButton says Stop [resetButton setEnabled:true]; [startButton setEnabled:false]; [stopwatchTimer invalidate]; } }
- (IBAction)resetButtonPressed:(id)sender { [timeLabel setText:@"00:00:00.0"]; [startButton setTitle:@"Start" forState:UIControlStateNormal]; [startButton setEnabled:true]; [resetButton setEnabled:FALSE]; }
Technical
|
|
|
iPhone StopWatch Sample (part 1) |
Sunday, January 02, 2011 9:16 PM |
iPhone Stop Watch
In this article, I explain the ins and outs of creating a stop watch application similar
to the one in the iPhone's Clock application. As a refresher, let's take a look at the start
screen for the iPhone StopWatch. There's the Start and Reset buttons and a label indicating the time
in tenths of seconds. This sample won't do anything too complicated like keeping laps.
Xcode Project
First of all, let's start up Xcode and create a view-based project and call it StopWatch.
Once the project has been created, Xcode will have the following project window.
Next, let's setup our variables. We know we need a label to hold the stopwatch's elapsed time. We will probably also
need a couple of buttons. We'll also need some variables to figure out the elapsed time. So, open StopWatchViewController.h
in xCode and add the following lines.
#import <UIKit/UIKit.h>
@interface StopWatchViewController : UIViewController { IBOutlet UILabel *timeLabel; IBOutlet UIButton *startButton; IBOutlet UIButton *resetButton; NSTimeInterval startTime; NSTimeInterval nowTime; NSTimer *stopwatchTimer; }
@property (retain, nonatomic) UIButton *startButton; @property (retain, nonatomic) UIButton *resetButton; @property (retain, nonatomic) UILabel *timeLabel;
- (IBAction) startButtonPressed:(id)sender; - (IBAction) resetButtonPressed:(id)sender;
@end
Technical
|
|
|
Nice Beginner LINQ Article |
Thursday, February 12, 2009 2:22 PM |
|
Ran across this nice article entitled: A Beginners Guide to use LINQ to SQL within ASP.NET in Visual Studio 2008 and CSharp(C#). Check it out if you're just getting started.
Technical
|
|
|
Language Versions |
Tuesday, November 11, 2008 10:46 AM |
Language Versions
Some of the languages I've learned and used in the past have been: FORTRAN, COBOL, 360 Assembler, PL/1, Pascal, C, and C++. Currently, almost all my work has been in C#. Prior to C#, the languages I have been very static. I had assumed the same of C#. While I'm cognizant of the fact that API change (like win16 to win32), I'm not really used to the notion of languages having versions. However, the .NET platform has shaken that basic assumption.
There are a number of fundamental changes which have occured to C# since it's initial release. What has made this more abscure is that there have also been changes in the version of the .NET Framework leading to the following matrix:
| C# Version |
CLR Version |
Framework Version |
| 1.0 |
1.0 |
1.0 |
| 1.1 |
1.1 |
1.1 |
| 2.0 |
2.0 |
2.0 |
| 2.0 |
2.0 |
3.0 |
| 3.0 |
2.0(updated) |
3.5 |
This is somewhat confusing because there are framework versions, CLR versions, and language versions.
As I'm looking at doing some new work, I've been keeping current on the latest events in the .NET world. I've been pretty good about keeping up with changes in the framework api and changes in the CLR (per my review of Jeffrey Richter's book CLR via C# - it's a great book). However, since I've never expected much evolution of languages, I didn't pay too much attention to changes in the C# language. Well, I've been doing a little bit of updating lately. So what type of things have changed since version 1.1?
- Lambda expressions
- Expression trees
- The var keyword, object and collection intializations and anyonymous types
- Extension methods
- Partial methods
- Query expressions
Over the next/past couple of weeks, I'll be logging postings here which discuss these new features as well as what looks to be the future of ASP.NET and the data story coming out of Microsoft.
Technical
|
|
|
Collections and Generics (part 3) |
Wednesday, October 29, 2008 1:05 PM |
|
All this leads eventually to a discussion of generic methods. The CLR makes it easy to create methods which take a type parameter. That is, a parameter which is a generic type - hence the name, generic methods. Generic methods enable you to specify, with a single method declaration, a set of related methods. Generic classes enable you to specify, with a single class declaration, a set of related classes. Similarly, generic interfaces enable you to specify, with a single interface declaration, a set of related interfaces. Generics provide compile-time type safety. An example of a generic method would be: static void Swap<T>(ref T first, ref T second)
{
T temp;
temp = first;
first = second;
second = temp;
}
To call the generic swap method, you would do something like this: public static void TestSwap()
{
int a = 1;
int b = 2;
Swap<int>(ref a, ref b);
System.Console.WriteLine(a + " " + b);
}
The code to call this generic method could look something like this: int a = 10, b = 90;
Console.WriteLine("Before swap: {0}, {1}", a, b);
Swap<int>(ref a, ref b);
Console.WriteLine("After swap: {0}, {1}", a, b);
Console.WriteLine();
// Swap 2 strings.
string s1 = "Hello", s2 = "There";
Console.WriteLine("Before swap: {0} {1}!", s1, s2);
Swap<string>(ref s1, ref s2);
Console.WriteLine("After swap: {0} {1}!", s1, s2);
Console.ReadLine();
Technical
|
|
|
Collections and Generics (part 2) |
Wednesday, October 29, 2008 11:10 AM |
|
It seems that discussions of generics always start with arrays and collections because arrays and collections are well understood data structures in modern programming languages. There's a tension which exists between the use of arrays and collections. Arrays allow for a strongly typed sequence of objects which you can iterate over. Lists are growable arrays and have tons of nice functionality with methods which allow for sorting and growing. However, you lose strong typing. This means that types can't be checked until runtime and that means that there can be issues. With generics, you can have strong type checking and the convenience which manageability offers. Collections have the following interfaces:
- ICollection - defines general characteristics such as size, inmeration, and thread safety for all nongeneric collection types
- IComparer - Allows two objects to be compared
- IDictionary - Allows a nongeneric collection object to represent its contents using name/value pairs.
- IDictionaryEnumerator - Enermerates the contents of atype supporting IDictionary.
- IEnumerable - Returns th eIEnumerator interface for a given object.
- IEnumerator - Enables foreach style iteration of subtypes
- IHashCodeProvider - Returns the hash code for the implementing type using a customized hash algorithm.
- IList - profices behavior to add, remove, and index items in a list of objects. Also, this interface defines members to determine whether the implementing collection type is read-only and/or a fixed size container.
The .NET Framework contains implemented interfaces for the following collection classes:
- ArrayList
- Hashtable
- Queue - the implementation includes Dequeue(), Enqueue(), and Peek()
- SortedList
- Stack - includes push() and pop() methods.
- BitArray
As a side note, types can be categorized as either value or reference types. Value types are light-weight objects that are allocated on the current stack. Reference types are allocated off the general heap. When you move from a value type to a reference type the CLR dynamically "boxes" the type and allocates it on the heap for you. When you need it to be a value type, the CLR automatically transfers it to the stack which will eventually be garbage collected. Why this is important to this discussion is that you can imagine if that is done with an array of objects, you run into performance and type safety issues. You can imagine an array of thousands of objects which would need to be boxed and unboxed would cause your code to run more slowly.
Technical
|
|
|
Collections and Generics (part 1) |
Wednesday, October 29, 2008 11:05 AM |
Collections and Generics
Generics introduce the concept of type parameters, which make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code. For example, by using a generic type parameter T you can write a single class that other client code can use without incurring the cost or risk of runtime casts or boxing operations, as shown here: // Declare the generic class
public class GenericList<T>
{
void Add(T input) { }
}
class TestGenericList
{
private class ExampleClass { }
static void Main()
{
// Declare a list of type int
GenericList<int> list1 = new GenericList<int>();
// Declare a list of type string
GenericList<string> list2 = new GenericList<string>();
// Declare a list of type ExampleClass
GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
}
}
- Use generic types to maximize code reuse, type safety, and performance.
- The most common use of generics is to create collection classes.
- The .NET Framework class library contains several new generic collection classes in the System.Collections.Generic namespace.These should be used whenever possible in place of classes such as ArrayList in the System.Collections namespace.
- You can create your own generic interfaces, classes, methods, events and delegates.
- Generic classes may be constrained to enable access to methods on particular data types.
- Information on the types used in a generic data type may be obtained at run-time by means of reflection.
Technical
|
|
|
One thing leads to another |
Monday, October 27, 2008 10:34 PM |
Where things take you
So, I downloaded the new version of Internet Explorer the other day. I took it for a test drive and checked out some of my frequently visited sites. It seemed pretty nice. However, I noticed in a couple of places where things didn't render quite right and I thought I would check out some of my sites. I was a little surprised to find out that on some of my sites, the dynamic menu items didn't render correctly (or at least what I thought was correctly).
Hmmm, thought I. How could this be? My standard way of doing menus is to use the asp.net menu control and bind it to the web.sitemap. Occasionally, a client will ask me to do a CSS type of menu but the asp.net menu control is the way I normally go. I like how it works with the authentication model and handles whether to show menu items based upon the user's role.
So, I started doing some research and ran across a reference to a bug report for ie8 - and noted that it has been resolved by design. This means Microsoft doesn't plan to do anything about it. Now, it's not that I'm doing anything outrageous in the way I'm using the asp.net menu control. IE8 doesn't display dynamic submenu items in the simplest use case: <asp:Menu ID="Menu1" runat="server"
Orientation="Horizontal"> <Items> <asp:MenuItem
Text="File"> <asp:MenuItem
Text="Open"></asp:MenuItem> <asp:MenuItem
Text="Save"></asp:MenuItem> <asp:MenuItem
Text="New"></asp:MenuItem> <asp:MenuItem
Text="Exit"></asp:MenuItem> </asp:MenuItem> </Items> </asp:Menu>
So, I'm using a Microsoft development environment (Visual Studio 2008), a Microsoft runtime environment (ASP.NET), and a Microsoft browser (IE8) and Microsoft is going to make all my users who install their new browser, switch to compatibility mode. A pretty poor job of customer service if you ask me.
But the main part point of my entry today is to talk about where all this led me because that's really the interesting part. Turns out Microsoft is trying to make the new version of IE more standards based. In that regard, they are breaking everyone (including themselves) who isn't in strict adherence to the standards. But that the problem is that there is no reference standard. That is, one place where you can run your page against and have it give you a thumbs up or a thumbs down.
In one of the forums I was researching, I ran across a pointer to this very nicely written article by Joel Spolsky's website JoelonSoftware.com about Martian Headsets. In the article he discusses the difficulty Microsoft and other browsers face as they try to make things compatible. In that article he also cites another very interesting article he wrote entitled How Microsoft Lost the API War. When I worked at Microsoft, I thought a lot about how developers work. Be sure to check out Joel's articles if you're interested in some great insights - he's got it spot on.
Technical
|
|
|
Why MVC? |
Friday, October 24, 2008 8:08 PM |
|
Casual web developers will probably stay with webforms. you switch to mvc when any of the following are important enough to switch:
- You are unit test developer (use test first design) are tried of webforms "fake" and complex event model.
- Are writing lots of javascript and tired of id's changing, and want standard html components.
- Want better seperation of view and controller code.
- Want a ruby on rails coding experience (mvc is easier with a dynamic language like ironpython, ironruby or javascript)
- You are commited to the mvc pattern, and want a supported platform
- You switched to jQuery (see #3)
- Your web site is going to be large and complex.
What are the disadvantages?
- No UI designer tools for it at this point.
- Requires good understanding of anonymous function and lambda
expressions to take full use of it.
- Coding is harder with a highly typed languages like c# and vb.net,
but dynamic style features are being added to these languages.
- Requires you know the mvc pattern and has a littler longer learning
curve.
- Doesn't attempt to hide the stateless nature of a web site from the
coder.
Technical
|
|
|
NUnit Testing and Generating User Stories |
Friday, October 24, 2008 11:18 AM |
NUnit Testing and Generating User Stories and ASP.NET MVC Applications
NUnit is a unit-testing framework for .Net languages. There are certain difficulties associated with Test Driven Development of ASP.NET webform applications.
In order to do test, you have to pull your code out of the webpage portion of the application and run it into code outside the normal mode of application
operation. This is because we're limited in our abilities to emulate what happens inside a web server. This isn't all bad because it forces the developer
to structure application logic in a more tiered approach. One of the main goals of the ASP.NET MVC framework is to allow Test Driven Development in an
easier manner.
One way to start an application is to begin with User Stories from your customers or clients.
User stories should be interesting to the customer and have little to do with
any technology driven discussion. For example if you were working on a blog
application, you might have the following User Stories:
- A user should be able to create a new blog entry
- People should be able to add comments to a blog entry
- People should be able to view blog entries
- People should be able to view blog comments
To start the application, choose a story and start building a framework for the
application. (As a side note, in
Extreme Programming
don't spend too much time on documenting requirements because things change.)
Typically, Unit Tests are comprised of 3 stages: 1) Setup 2) Execution and 3)
Verification.
Technical
|
|
|
Creating Custom HTML Helpers for ASP.NET MVC Applications |
Thursday, October 23, 2008 3:37 PM |
Creating Custom HTML Helpers for ASP.NET MVC Applications
An HtmlHelper is a method you can use in a view to render some special html content. The theory behind the Html helper class is that it makes life easier for you in that you don't have to type out the actual html. Why you would want to create a custom html helper is that there are a limited number of html helper methods built into the box. Custom html helpers allow you to create helpers which are customized to your design/development efforts. For example, there are no built in helpers which allow you to display database results in a table (huh? that can't be right).
There are two ways to create an html helper:
- The easy way - create a class which renders a string.
- Slightly less easy way - Extension method. If you want your html helper methods to work the same way as the built-in html helper classes, this is the way to go. In other words, if you them to show up in the view page under the Html helper class you would use this method. In VB you create a module with an <Extension> attribute. In C#, you'd have to create a sealed class with static functions.
Custom Html helpers seem like a nice thing if you're doing alot of html editing but they don't seem to go to the heart of application development.
Technical
|
|
|
Unit Testing ASP.NET MVC Applications |
Tuesday, October 21, 2008 4:33 PM |
Unit Testing an ASP.NET MVC Applications
Unit testing is of concern to two audiences: 1) Testers and 2) Test-driven developers. The ASP.NET MVC framework was especially designed to support (encourage) unit testing by testers and test-driven development.
There are different ways to test an ASP.NET MVC application:
- Test a view
- Test ViewData
- Test other results
To create the unit tests for the MVC application, open a new project in Visual Studio and select OK in the Create Unit Test Project dialog. You can select the Visual Studio default Unit Test framework or if you have another framework you like, you can create the unit tests based upon that. I'll have to look into this a bit more before writing any more detailed blog entries.
Technical
|
|
|
Preventing Javascript Injection Attacks in ASP.NET MVC Applications (Part 1) |
Tuesday, October 21, 2008 2:03 PM |
Preventing JavaScript Injection Attacks and Cross-Site Scripting Attacks in MVC Apps (part 1)
Whenever you ask your users for input, you run the rusk of someone doing something unreasonable. Unreasonable in the sense of mistaken input which causes some damage or that someone has maliciously does something bad. In the case of feedback forms, it could be easy for someone who has bad intentions to enter in some javascript code which might cause some problems. For example, a hacker could enter something like this into a textbox: <script>alert(“Boo!”)</script>
If you feed this into a database and redisplay it without validating the input, everytime it is shown, it is going to show a javascript alert box. That can pretty annoying for your users. And while this is not awful for your users, it could be possible without data input validation to be opened to cross site scripting attacks (XSS). Cross site scripting attacks could allow hackers to collect your users personal information on a form and post it to their website or allow them to steal sensitive information stored in browser cookies.
Okay, so let's say your controller code looks like the following:
public class HomeController : Controller
{
private FeedbackDataContext db = new FeedbackDataContext();
public ActionResult Index()
{
return View(db.Feedbacks);
}
public ActionResult Create(string message)
{
// Add feedback
var newFeedback = new Feedback();
newFeedback.Message = message;
newFeedback.EntryDate = DateTime.Now;
db.Feedbacks.InsertOnSubmit(newFeedback);
db.SubmitChanges();
// Redirect
return RedirectToAction("Index");
}
}
Technical
|
|
|
Preventing Javascript Injection Attacks in ASP.NET MVC Applications (Part 2) |
Tuesday, October 21, 2008 2:01 PM |
Preventing Javascript Injection Attacks in ASP.NET MVC Applications (part 2)
The Index method displays the default view and passes to it the feedbacks stored in the database. The Create method takes the new Feedback item and adds it to the database. The Index view would look something like this: <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="CustomerFeedback.Views.Home.Index"%>
<%@ Import Namespace="CustomerFeedback.Models" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h1>Customer Feedback</h1>
<p>
Please use the following form to enter feedback about our product.
</p>
<form method="post" action="/Home/Create">
<label for="message">Message:</label>
<br />
<textarea name="message" cols="50" rows="2"></textarea>
<br /><br />
<input type="submit" value="Submit Feedback" />
</form>
<% foreach (Feedback feedback in ViewData.Model)
{%>
<p>
<%=feedback.EntryDate.ToShortTimeString()%>
--
<%=feedback.Message%>
</p>
<% }%></asp:Content>
The Index view baskically contains two sections: the section to post the new feedback information to the /Home/Create action and the part which displays the feedback passed into the view from the controller. So, what can we do to prevent the input or injection of javascript into the database? We can take two approaches:
Technical
|
|
|
Preventing Javascript Injection Attacks in ASP.NET MVC Applications (Part 3) |
Tuesday, October 21, 2008 1:50 PM |
Preventing JavaScript Injection Attacks and Cross-Site Scripting Attacks in MVC Apps (part 3)
- We can call Html.Encode on what we're displaying from the database in the view before sending it off to the browser (converts the braces to the appropriate literal):
<% foreach (Feedback feedback in ViewData.Model)
{%>
<p>
<%=feedback.EntryDate.ToShortTimeString()%>
--
<%=Html.Encode(feedback.Message)%>
</p>
<% }%>
- Another approach you could take is to encode input before it is submitted to the database. You can do this in the Create method of the controller:
public ActionResult Create(string message)
{
// Add feedback
var newFeedback = new Feedback();
newFeedback.Message = Server.HtmlEncode(message);
newFeedback.EntryDate = DateTime.Now;
db.Feedbacks.InsertOnSubmit(newFeedback);
db.SubmitChanges();
// Redirect
return RedirectToAction("Index");
}
In the first approach, we stored the actual javascript in the database. This might seem less safe to some but the advantage of it is that if you need to return it later as is, it is easier to deal with. If you take the second approach you may alter what the user has altered and it may be difficult to unalter it later.
Technical
|
|
|
ASP.NET MVC URL Routing |
Monday, October 20, 2008 5:45 PM |
ASP.NET MVC URL Routing
While URL routing is an optional aspect of ASP.NET webforms application, it is essential to ASP.NET MVC applications. It's how browser requests get over to MVC action controllers. When you create an ASP.NET MVC web application in Visual Studio 2008, the web.config file contains (among other things) the following lines: <modules runAllManagedModulesForAllRequests="true">
<remove name="UrlRoutingModule"/>
<add name="UrlRoutingModule"
type="System.Web.Routing.UrlRoutingModule, System.Web.Routing,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</modules>
...
The routing table is setup in the global.asax file: public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
...
The default route is setup to handle 85% of the routing requirements for your application. In the example above, the MapRoute method is naming the route as "Default", setting up the basic pattern for the route url and giving the parts names, and then initializes those parts with default values. Specifically in the code above, it sets the default controller as Home, the default action as Index, and the default id as nothing.
You run into limitations of the default URL routing pretty quickly. For example, if you were creating a blogging application you would want a URL similar to /Archive/11-06-2007. This obviously doesn't fit into the default routing scheme which would read the default as an action. You really want to use the date as a parameter. So, you have to put a new route into the URL routing table by editing the global.asax file. You want to add your new route before the one already in the routing table so that it gets routed first. The modified file looks like the following: public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Blog", // Route name - this our new blog route
"Archive/{entryDate}", // This gives us the archive action with the entrydate parameter
new { controller = "Archive", action = "Entry"} // and of course the results.
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
Next we have to create a controller for the Archive action and we end up with a new controller class. It is important that we name the parameter for the action appropriately and that it matches what we named the parameter in the global.asax file (in this case, entryDate). Of course, there is no parameter checking going on in this example: public class ArchiveController : Controller
{
public ActionResult Index()
{
// Add action logic here
throw new NotImplementedException();
}
public ActionResult Entry(DateTime entryDate)
{
return Content("You requested the blog entry for" + entryDate.ToString());
}
}
Technical
|
|
|
MVC Views |
Monday, October 20, 2008 4:03 PM |
MVC Views and HTML Helpers
Views are not the same thing as .NET aspx pages in that there is no direct correspondence between what URL you type in the address bar and what page is shown as a view. There is a level of indirection which occurs and it is up to the controller action to decide view is sent back to the browser. By default the name of the view returned from a controller action is the name of the controller action. For example, if the controller Product has a method named Index and it returns a default view, it is the Index view: public class ProductController : Controller
{
public ActionResult Index()
{
// Add action logic here
return View();
}
}
Again, it is important to have the view in the correct directory structure. So, the view must be created in the Views\Product directory. You can specifically name the view which is returned besides defaulting to the same name as the Controller Action. It seems you have to use embedded script with views (which seems like a drag - but maybe I just don't know enough yet).
For ViewPages, there are two imporant properties:
- ViewData - you use this to access all the data sent over from the controller action. The ViewData object can be thought of as a dictionary type of object containing key/data pairs. You can certainly stick database records into the ViewData object.
- Html - this property exposes the HtmlHelper class.
Technical
|
|
|
MVC Controllers |
Thursday, October 16, 2008 2:54 PM |
MVC refers to Model View Controller
MVC architecture depends alot on having things in the right folders and having the right names. So, when your ProductController.Index() function returns the default View(), it has to be in the \Views\Product directory.
Controllers
- Controllers return ActionResults
- ViewResults - contains HTML markup and content you want to send back to the brownser.
- JsonResult
- RedirectToRouteResult - allows you to re-route the controller action to another controller action.
- ContentResult - allows you to send some text back.
- Custom Action Result - create your own custom action result. For example, an Excel spreadsheet file.
Technical
|
|
|
MVC Overview |
Wednesday, October 15, 2008 4:34 PM |
|
I've been watching the videos from www.asp.net\mvc. Here are some of my notes:
MVC Overview
Model == Contains business and data access logic.
View == contails HTML markup and content that is returned to the browser.
Controller ==> fires off some logic in response to a browser request.
In Visual Studio, you want to select the ASP.NET MVC Web Application under New Project. I originally thought you would want to select Open Website but that is not the case. Visual Studio also lets you select to have Unit Tests created at the same time. The default MVC Web Application contains three folders: Models, Controllers, and Views. The default MVC web application is very simple and consists of the home page and an about page. The important thing to notice about the application is the url - there is no extension listed for the Home or Home/About pages. No .aspx, no .html. This highlights the difference between an ASP.NET application and an MVC application.
For an ASP.NET application, a url == an .aspx page.
This is not true for an MVC application. For an MVC application, a url == a Controller Action.
To summarize, an ASP.NET application is more content centric. Whereas, an MVC application is more logic-centric. This leads to the observation that url routing is a key aspect of MVC application architecture. Look in the global.asax file to see where the route table is setup. During the Application_Start the routing table is initialized. public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
The default routing table is set up to handle a controller, an action, and an id. The default route is controller = "Home" action = "Index" and id = " ". So, if you typed in the url /MyController/DoSomething/34, the MyController controller would be invoked with the DoSomething action and an id of 34.
So, the HomeController.cs file int he Controllers directory invokes Index view contained in the Views\Home directory by default. The directory structure and file names are by convention and have to be followed for everything to work. This seems particularly fragile to me but I don't know very much at this point.
Models are supposed to contain all the logic for the application. The controller actions are supposed to be skinny and the model is supposed to do all the work in a series of classes.
Technical
|
|
|
Silverlight Cut Copy Paste |
Wednesday, July 23, 2008 1:24 PM |
|
Hmmmm....
I've been thinking about getting an IPhone for the last couple of months and one of the things which bugged me about the IPhone is that it doesn't do cut/copy/paste operations.
Well, I was thinking about Silverlight. I don't believe it will be possible in the current architecture to do cut/copy/paste. It will be interesting to see what happens.
Technical
|
|
|
Silverlight Introduction |
Wednesday, July 23, 2008 1:19 PM |
|
I've started looking at Silverlight and I'm very excited. What is Silverlight? It is a cross-browser, cross-platform, and cross-device plug-in for delivering the next generation of .NET based media experiences and rich interactive applications for the Web.
Why does that seem cool? For me, it allows me to do rich, interactive applications driven by C#. I've always avoided developing Flash applications because they are driven by ActionScript/JavaScript and when I have a choice writing unmanaged code or managed code, I always choose managed code.
Technical
|
|
|
Menus, mouseovers, and the IPhone |
Thursday, January 31, 2008 6:16 PM |
|
So, I've been thinking about getting an IPhone or a Tilt. I went down to the AT&T store yesterday. It was the first time ever that I was in a phone store that didn't have a zillion people in it. I was left alone with the IPhone for 45 minutes . What a great interface and device - but more on that later. It came as a bit of surprise to me when I browsed to the LimberTech website and tried navigating around using the menu. I never thought about it before but mouseover's won't work on a touch screen type of interface because when you press your finger on the menu item, it means to select it. There is no notion of hovering over a link. I'm not sure there is a way to do a popup menu'ing system on the IPhone. I'll have to do a bit of research to figure that one out.
I almost walked out with an IPhone. I had my credit card out and they had brought a box up from the back. However, I came to an abrupt halt when I found out there was no way to use the phone as a modem for the laptop. I just took for granted that you would be able to hook the phone to the computer and use the EDGE network for data access. But the salesperson said that you couldn't do that because the IPhone "wasn't a true PDA". So I had them put the IPhone back and went to look at the Tilt.
The Tilt certainly didn't wow me like the IPhone did. But I was still blown away by the device. While the interface isn't anywhere near as tight/nice as the IPhone, it seems like the features might be a better match for me - re: Outlook integration and better support for IE.
Technical
|
|
|
Why Silverlight? |
Thursday, January 10, 2008 3:35 PM |
|
Silverlight is a cross-browser, cross-platform plug-in from Microsoft for delivering the next generation of Rich Internet Applications (RIA). Silverlight is nom de development for the platform to deliver these applications. While Microsoft has made some mis-steps along the way, Silverlight represents a qualitative step forward in the evolution of web applications.
Silverlight is based upon XHTML, Javascript, and XAML (eXtensible Application Markup Language). Once the Silverlight "player" plug-in has been installed on the client the client has only to:
- Load a web page (XHTML)
- Run a small bit of Javascript for invocation of the plug-in
- Play the XAML in the plug-in
One advantage of this model over other RIA technologies like Flash or Java Applets, or ActiveX is that the XAML is simply a fire-wall friendly, text-based XML file which is well defined and can be easily audited for security purposes. XAML also allows designers, using a tool like Microsoft Express Blend to deliver designs which can be directly delivered to the browser. In the past, designers might have been constrained by a developer as they incorporated the designer's work into the application.
Technical
|
|
|
HVTP - Hyper Video Transfer Protocol |
Wednesday, January 24, 2007 5:24 PM |
|
I got a new video camera for my birthday in November and I've been reading and thinking alot about Digital Video. One of the things I really like about the camera is that it records directly to a 30GB harddisk. I connect it to my PC through a USB port and treat the videos as files.
I've also thought alot about Google's purchase of YouTube. I think it was a brilliant move on Google's part because it comes at the beginning of the coming wave of video on the web. Within 10 years we will be getting most of our entertainment over the web.
So, thinking about all this had made me start to wonder about the digital video file format. Right now, everything is streamed to the player alá music from a CD. It has always been to my dismay that more encoding of meta data hasn't caught on to CD's. While DVD's are better, I think that meta data should be allowed in the stream of the image, similarly to what HTTP allows for the text stream. I believe you should be able to have links appear in the video stream to other web pages, sound files, spreadsheets, even other videos. I think it should even have a similar name to HVTP - HyperVideo Transfer Protocol.
Just my little musing for the day.
Technical
|
|
|
Smart people and Web 2.0 Applications |
Monday, January 15, 2007 11:53 AM |
|
There are some smart people doing some innovative work out there. I recently ran across this article on CodeProject's website: Build Google IG like Ajax Start Page in 7 days using ASP.NET Ajax and .NET 3.0 by Omar Al Zabir. It was an interesting article which spoke to creating mashup pages using AJAX. Even more so, the article led me to Al Zabir's website PageFlakes.
He's doing some interesting work. Websites like PageFlakes.com, Window Live (if you personalize it), and Google's IG brings to life the idea of mass individualization.
One of the interesting aspects of the next generation of web applications is that they face some of the same problems faced by GUI applications as they evolved. For example, on PageFlakes you can select the feeds you want to appear on your personalized webpage. These little windows (gadgets) remind me of the windows in mdi applications back in Windows 3.x. The central issue is how do you manage the UI in a consistant way so that the user doesn't become confused. On PageFlakes I selected an entry from one of the feeds and was presented with the content. But was I still on PageFlakes or had I moved to the website which hosts the content? When I hit the back button, the unexpected happened - I left PageFlakes and went to the website I was viewing before I came to PageFlakes. Weird.
As "Web 2.0" applications become more popular smart people are going to have to re-solve some of the problems GUI developers faced in the past.
Technical
|
|