I just found out from K. Scott Allen’s MVC3 training video on Pluralsight that the app_code directory in MVC3 is alive and well. Basically the Razor helpers here are pre-compiled and can be accessed globally in the application.
Apparently the usage in a Razor page is as follows:
@Common.Script(“myscript.js”, Url)
Note to self: compare and contrast with shared “editor” partial views.
Note: I composed this post with Windows Live Writer 2011 but it doesn’t seem to play well with Blogger’s own editor. ¡Qué pena!
Caution: when you are using strongly typed models in MVC3 and you modify a property of the model in an Action, that property will get discarded when you create the view unless you clear the ModelState first. When building the view, the model fields are overwritten with values from ModelState, so clearing the ModelState prevents this.
UPDATE 11/10/2011:
This only applies to values passed in via a POST (or a GET?) that you're attempting to override by changing the corresponding fields in the view model.
I have to do this in a piece of code, so I'm recording this here for my future reference.
In Visual Studio's Find and Replace dialog, type the following in the "Find what:" field: public string \{:i\} \{ get; set; \}
Type this into the "Replace with" field: private string _\1;\npublic string \1 \{\nget \{ return _\1 ?? ""; \}\nset \{ _\1 = value; \}\n\}
This pattern of performing a test in the getter versus the setter guarantees that it will never be null, and is the pattern used in the TextBox web control's Text property.
Afterwards you'll want to reformat the code, and possibly rename the backing fields, e.g. _FirstName, to be more camel-cased instead of being Pascal-cased(-like), e.g. _firstName instead of _FirstName.
Everything you've always wanted to know about date/time formats but were afraid to ask.
Date & Time Formats on the Web: "There are several different formats used in different places in the technologies of the World Wide Web to represent dates, times and date/time combinations (hereafter collectively referred to as “datetimes” unless a distinction has to be made). This document presents a survey of the most significant, details which formats are mandated by the key technologies of the web, and offers advice for deciding what formats you should use in your own web applications."
When attributes are an integral part of the work flow, testing is a bitch. Luckily I found this code.
Josh Reed Schramm - Software Development Thoughts And Opinions - Blog - Unit Testing Role Based Security w/ ASP.Net MVC: "I took Paul's code and turned it into a series of three controller extension methods which verify if the entire controller requires authorization, a particular method requires authorization or if a particular method requires a given role (i have not yet written the obvious 4th case - an entire controller requires a given role but it should be trivial.)"
Compiling MVC Views In A Build Environment: "It turns out we had a bug in our project templates in earlier versions of ASP.NET MVC that we fixed in ASP.NET MVC 3 Tools Update. But if you created your project using an older version of ASP.NET MVC including ASP.NET MVC 3 RTM (the one before the Tools Update), your csproj/vbproj file will still have this bug."
Don't mock HttpContext: "It's so easy to take a direct dependency on HttpContext and not even realize it. If you're in the code behind in Web Forms or in a controller action in MVC, it's just right there, tempting you to use it to access session variables, application security, etc.
If you try the following, it should set the visible text of the dropdown control in question, right?
listControl.Text = "4 Year College";
Well, unfortunately, no! The "Text" property is named that way for consistency across all ASP.NET controls and refers to the form value that is passed to the server when the page is submitted. So unfortunately for me, the "Text" property silently rejected my attempt to set it and the page did not work.
You may be asking yourself why I am trying to set the visible text and not the value of the control. The reason is that the application I'm working on receives the displayed text from a web service and not the value that is passed in the form variables. Why not create a dictionary, look up the the text string in the dictionary, and pass that to the control?
The answer? I already have a dictionary. It's called the SELECT control itself. The generated HTML for my control is, say, the following:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This control is essentially a dictionary of key-value pairs: the key is the value attribute of the option tag, and the value is the visible text that is displayed for the given item in the dropdown list. So in the spirit of Don't Repeat Yourself (DRY), I wrote a extension function to allow me to set not just the value but also the text. I give you ListControlExtensions.cs:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Here's a typical usage. In this particular scenario, my data should be scrubbed, but if not I log a warning:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Have you ever performed a merge in Git and not have it quite turn out the way you wanted it to? For example, you accidentally converted all of your UNIX line endings to DOS line endings, and now the entire file reports a conflict? Maybe you see a conflict that you don't really care about resolving, and want to resolve as theirs? Or perhaps the conflicted file is empty and you can't figure out just what happened there?"
Wow! Caffeine-Powered Life - Nested Collection Models in ASP.NET MVC 3: "We want to create form where I can save information about a person. That person has zero or more phone numbers and zero or more email addresses. The customer would like to edit everything about a person all at once, on a single form. This is a dynamic nested model problem."
After I relocated an IIS express application, it stopped working. Even though I re-registered it with Visual Studio, it appeared "stuck" in its old location. The problem is that Visual Studio doesn't tell you that it hasn't really done anything at all when it claims that it's successfully registered your app after you've moved it. After reading this FAQ I was able to delete the broken site registration and then re-add it in Visual Studio. To fix my problem, I ran "%userprofile%\documents\IISexpress\config" from the Windows start menu, did a ctrl-F to find the application name, and simply deleted the configuration node.
A: Yes, IIS Express uses the same applicationhost.config and web.config files supported by IIS 7.x. The key difference is that with IIS Express, the configuration is maintained on a per-user basis. In particular, whereas IIS has a global “applicationhost.config” file, IIS Express maintains a user-specific “applicationhost.config” file in the %userprofile%\documents\IISexpress\config” folder. This lets a standard user run IIS Express and also lets multiple users work on the same machine independently, without conflicting with each other. Some settings require Administrator user rights to set and modify (see question above about running as a standard user)."
Interesting stuff throughout, but here's the summary at the end:
"This was really a whistlestop tour of the "other" side of LINQ - and without going into any of the details of the real providers such as LINQ to SQL. However, I hope it's given you enough of a flavour for what's going on to appreciate the general design. Highlights:
Expression trees are used to capture logic in a data structure which can be examined relatively easily at execution time
Lambda expressions can be converted into expression trees as well as delegates
IQueryable and IQueryable form a sort of parallel interface hierarchy to IEnumerable and IEnumerable - although the queryable forms extend the enumerable forms
IQueryProvider enables one query to be built based on another, or executed immediately where appropriate
Queryable provides equivalent extension methods to most of the Enumerable LINQ operators, except that it uses IQueryable sources and expression trees instead of delegates
Queryable doesn't handle the queries itself at all; it simply records what's been called and delegates the real processing to the query provider"
Interesting stuff throughout, but here's the summary at the end:
"This was really a whistlestop tour of the "other" side of LINQ - and without going into any of the details of the real providers such as LINQ to SQL. However, I hope it's given you enough of a flavour for what's going on to appreciate the general design. Highlights:
Expression trees are used to capture logic in a data structure which can be examined relatively easily at execution time
Lambda expressions can be converted into expression trees as well as delegates
IQueryable and IQueryable form a sort of parallel interface hierarchy to IEnumerable and IEnumerable - although the queryable forms extend the enumerable forms
IQueryProvider enables one query to be built based on another, or executed immediately where appropriate
Queryable provides equivalent extension methods to most of the Enumerable LINQ operators, except that it uses IQueryable sources and expression trees instead of delegates
Queryable doesn't handle the queries itself at all; it simply records what's been called and delegates the real processing to the query provider"
When I worked atIntuit (makers of TurboTax, Quicken & QuickBooks) we used a method called "follow-me-home." It was as effective as it was simple in identifying customer problems and needs. We went to a customer's house or workplace and watched them do what they do and recorded their behavior and problems they encountered and how they solved them. Data from follow-me-homes were used for new product ideas and improving existing products. "
Also my comment on how to wire up the resultant .csproj file to have the MVC context menus:
Woot! I added the GUID {E53F8FEA-EAE0-44A6-8774-FFD645390401} to the ProjectTypeGuids node of the .csproj, and it's a bone fide MFC project with context menus in the Solution Explorer.
This is sort of a LINQ 101 thing, but I haven't had much of an opportunity to use LINQ to SQL yet, believe it or not.
I learned the hard way: when using IQueryable against a database, any predicates handed around should be Expression<func<type, bool>> instead of just Func<type, bool>. Func<type, bool> is evaluated in memory! That means that the entire table is fetched from the database, then filtered in memory. Bad, bad, bad!
Video Series: How To Give Great Presentations: "UGSS (Microsoft's User Group Support Services) have just published a video series that I recorded last year on How To Give Great Presentations. This free series of 8 videos covers the following subjects:-"
How To Use Amazon EC2 as Your Desktop - RestBackup™ Blog: "In this article, I describe how I use EC2 as my Linux development desktop. I provide detailed instructions for every step of the setup process. This guide assumes that your client machine is Windows."
Wednesday, January 19, 2011 5:18:17 PM (Pacific Standard Time, UTC-08:00) So maybe I'm late to the party, but I recently started playing with NuGet. It's a killer new way to find, install, maintain, and manage references to open source libraries in Visual Studio 2010. Plenty of people have written about it (Phil Haack and Scott Hanselman for example). Let's just say you should learn about NuGet if you don't know it already.
What I want to talk about is all the cool open source projects I found just by flipping through the pages of the NuGet directory in the Visual Studio 'Add Library Package Reference' dialog."