<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="./rss/rssfeed.xsl"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>mike's web log</title><link>http://www.mikepope.com/blog/</link><description>mike pope's Web log</description><language>en-US</language><docs>http://www.mikepope.com/blog/BlogFeed.rss</docs><webMaster>mike@mikepope.com</webMaster><lastBuildDate>Sat, 25 May 2013 20:44:56 GMT</lastBuildDate><pubDate>Saturday, May 25, 2013 8:44:56 PM</pubDate><ttl>60</ttl><item><title>Paging and posting with the Razor WebGrid Helper</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2377</link><description>The ASP.NET Web Pages/Razor &lt;code&gt;WebGrid&lt;/code&gt; helper lets you enable paging just by setting the &lt;code&gt;rowsPerPage&lt;/code&gt; property:&lt;br /&gt;&lt;pre&gt;var grid = new WebGrid(source: selectedData, rowsPerPage: 3);&lt;/pre&gt;&lt;br /&gt;Sometimes you want to be able to both to page and to filter the items that are displayed by the &lt;code&gt;WebGrid&lt;/code&gt; helper. Here’s an example from the &lt;a href="http://www.asp.net/web-pages/tutorials/introducing-aspnet-web-pages-2/getting-started" target="_blank"&gt;tutorial&lt;/a&gt; I posted on the &lt;a href="http://asp.net/web-pages" target="_blank"&gt;http://asp.net/web-pages&lt;/a&gt; site a couple of weeks ago:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left:25px;"&gt;&lt;img src="http://www.mikepope.com/blog/images/MoviesGridPaging.png" width='499' height='209' /&gt;&lt;/div&gt;&lt;br /&gt;The typical (?) approach here is to create a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element and set its &lt;code&gt;method&lt;/code&gt; attribute to &lt;code&gt;post&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;form &lt;span style='background-color:yellow'&gt;method="post"&lt;/span&gt;&amp;gt;&lt;br /&gt;  &amp;lt;div&amp;gt;&lt;br /&gt;    &amp;lt;label for="searchGenre"&amp;gt;Genre to look for:&amp;lt;/label&amp;gt;&lt;br /&gt;    &amp;lt;input type="text" name="searchGenre" value="" /&amp;gt;&lt;br /&gt;    &amp;lt;input type="Submit" value="Search Genre" /&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;    (Leave blank to list all movies.)&amp;lt;br/&amp;gt;&lt;br /&gt;    &amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/pre&gt;&lt;br /&gt;In the page’s code, you create an &lt;code&gt;is(IsPost)&lt;/code&gt; block in which you set up a parameterized SQL query and run that:&lt;br /&gt;&lt;pre&gt;@{&lt;br /&gt;    var db = Database.Open("WebPagesMovies") ;&lt;br /&gt;    var selectCommand = "SELECT * FROM Movies";&lt;br /&gt;    var searchTerm = "";&lt;br /&gt;&lt;br /&gt;    if(&lt;span style='background-color:yellow'&gt;IsPost &amp;&amp; &lt;/span&gt;!Request.QueryString["searchGenre"].IsEmpty() ) { &lt;br /&gt;        selectCommand = "SELECT * FROM Movies WHERE Genre = @0";&lt;br /&gt;        searchTerm = Request.QueryString["searchGenre"];&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    var selectedData = db.Query(selectCommand, searchTerm);&lt;br /&gt;    var grid = new WebGrid(source: selectedData, rowsPerPage:3);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2377'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2377</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2377</guid><pubDate>Wed, 06 Jun 2012 08:56:19 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2377">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2377</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2377</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2377</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>"Remembering" a selection in a &amp;lt;select&amp;gt; list in Razor</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2375</link><description>I'm just recording this for now, possibly for later investigation. In ASP.NET Web Pages 2 (Razor), you can take advantage of &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=2353" target="_blank"&gt;conditional attributes&lt;/a&gt; to set or clear attributes like &lt;code&gt;selected&lt;/code&gt; and &lt;code&gt;checked&lt;/code&gt;. These attributes don't need a value, they just need to exist, like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;select&amp;gt;&lt;br /&gt;  &amp;lt;option value="1"&amp;gt;One&amp;lt;/option&amp;gt;&lt;br /&gt;  &amp;lt;option value="2" &lt;span style='background-color:yellow'&gt;selected&lt;/span&gt; &amp;gt;Two&amp;lt;/option&amp;gt;&lt;br /&gt;  &amp;lt;option value="3"&amp;gt;Three&amp;lt;/option&amp;gt;&lt;br /&gt;&amp;lt;/select&amp;gt;&lt;/pre&gt;So how do you "remember" a list selection after a form submit? Here's one way. This seems a bit kludgy, but I can't offhand think of a way to do this without using JavaScript or something. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt; select name="NumberList"&amp;gt;&lt;br /&gt;  &amp;lt;option &lt;br /&gt;   selected=@(Request.Form["NumberList"] == "1")&lt;br /&gt;   value="1"&amp;gt;One&amp;lt;/option&amp;gt;&lt;br /&gt;  &amp;lt;option &lt;br /&gt;    selected=@(Request.Form["NumberList"] == "2")                &lt;br /&gt;    value="2"&amp;gt;Two&amp;lt;/option&amp;gt;&lt;br /&gt;  &amp;lt;option &lt;br /&gt;    selected=@(Request.Form["NumberList"] == "3")&lt;br /&gt;    value="3"&amp;gt;Three&amp;lt;/option&gt;                    &lt;br /&gt;&amp;lt;/select&amp;gt;&lt;/pre&gt;</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2375</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2375</guid><pubDate>Sat, 19 May 2012 21:33:55 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2375">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2375</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2375</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2375</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Login redirection (and back) in ASP.NET Web Pages Razor</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2374</link><description>When you use membership security in ASP.NET Web Pages Razor, you can limit access to pages so that only logged-in users can see those pages. One way to do that, as explained &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=2240&amp;count=no" target="_blank"&gt;before&lt;/a&gt;, is to add a test like the following to the top of a page (or to the &lt;em&gt;_PageStart.cshtml&lt;/em&gt; page in the protected folder):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@{&lt;br /&gt;    if (!WebSecurity.IsAuthenticated) {&lt;br /&gt;        Response.Redirect("~/Login");&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;If the user isn't logged in, they're redirected to the Login page (in this case, in the site's root). &lt;br /&gt;&lt;br /&gt;Nice, but then the user still has to find their way back to the page they originally wanted. Ideally, after the user has logged in, you send them back to the original page automatically. And because they're now logged in, the gatekeeper code lets them through.&lt;br /&gt;&lt;br /&gt;The usual way to approach this is to include a return URL address when you redirect to the login page. You can add it as a query-string value to the login URL. Then in the login page, once the user has logged in ok, you can get that return URL and jump back.&lt;br /&gt;&lt;br /&gt;Here's an updated version of the code from above with some logic to create a return URL:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;if (!WebSecurity.IsAuthenticated) {&lt;br /&gt;     Response.Redirect("~/Login?returnUrl=" + Request.Url.LocalPath);&lt;br /&gt;}&lt;/pre&gt;For a URL like the following:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;http://localhost/members/info.cshtml&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The &lt;code&gt;Request.Url.LocalPath&lt;/code&gt; property returns this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;/members/info.cshtml&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So the URL of the redirect to the Login page looks like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;http://localhost/Login?returnUrl=/members/info.cshtml&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The login page can then return to the original page using logic like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;if(IsPost){&lt;br /&gt;    var username = Request.Form["username"];&lt;br /&gt;    var password = Request.Form["password"];&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2374'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2374</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2374</guid><pubDate>Tue, 08 May 2012 23:20:34 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2374">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2374</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2374</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2374</wfw:commentRss><slash:comments>1</slash:comments></item><item><title>Razor tip: Escaping the "@" character</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2370</link><description>In ASP.NET Web Pages/Razor, you use the &lt;code&gt;@&lt;/code&gt; character inside markup to mean "here be code." Like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;p&amp;gt;@DateTime.Now&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;But suppose you want to &lt;em&gt;display&lt;/em&gt; the &lt;code&gt;@&lt;/code&gt; character instead of use it to mark code? Like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;p&amp;gt;You use the @ character to mark inline code.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Try that in a &lt;em&gt;.cshtml&lt;/em&gt; page and you're rewarded with a YSOD:&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" href="http://www.mikepope.com/blog/images/AtSignParserError.png"&gt;&lt;img src="http://www.mikepope.com/blog/images/AtSignParserError_th.png" width="299" height="206" /&gt;&lt;/a&gt;&lt;br /&gt;(Click to embiggen)&lt;br /&gt;&lt;br /&gt;Simple fix: escape the &lt;code&gt;@&lt;/code&gt; character with ... another &lt;code&gt;@&lt;/code&gt; character. Like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;p&amp;gt;You use the @@ character to mark inline code.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This makes the parser happy.&lt;br /&gt;&lt;br /&gt;(h/t, as usual with parser questions: &lt;a href="http://vibrantcode.com/" target="_blank"&gt;Andrew Nurse&lt;/a&gt;)</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2370</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2370</guid><pubDate>Wed, 25 Apr 2012 17:20:43 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2370">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2370</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2370</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2370</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>"Page" vs "PageData" objects  in ASP.NET Web Pages</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2368</link><description>I was playing around with &lt;a href="http://www.asp.net/web-pages/tutorials/working-with-pages/3-creating-a-consistent-look" target="_blank"&gt;layout pages&lt;/a&gt; in ASP.NET Web Pages the other day and realized that there are actually two ways to pass data from the content page to the layout page: the &lt;code&gt;Page&lt;/code&gt; object and the &lt;code&gt;PageData&lt;/code&gt; object. You can do either of these in the content page:&lt;br /&gt;&lt;pre&gt;Page.Title = "My Page";&lt;br /&gt;&lt;br /&gt;PageData["Title"] = "My Page";&lt;/pre&gt;And then use either of these in the layout page:&lt;br /&gt;&lt;pre&gt;&amp;lt;title&amp;gt;@Page.Title&amp;lt;/title&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;title&amp;gt;@PageData["Title"]&amp;lt;/title&amp;gt;&lt;/pre&gt;So what's the difference? Here's what I got from my usual sources.&lt;br /&gt;&lt;br /&gt;First, they really are the same object, just with differences in accessors. To show  this, you could do the following:&lt;br /&gt;&lt;pre&gt;Page.Me = "Mike";&lt;/pre&gt;and then get that value doing this:&lt;br /&gt;&lt;pre&gt;&amp;lt;p&amp;gt;@PageData["me"]&amp;lt;/p&amp;gt;&lt;/pre&gt;Notice that the property/value names &amp;mdash; &lt;code&gt;Me&lt;/code&gt;, &lt;code&gt;"me"&lt;/code&gt; &amp;mdash; aren't even case sensitive.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Page&lt;/code&gt; is a dynamic object, meaning that the properties aren't fixed. You can make up your own properties for the object, like &lt;code&gt;Page.Title&lt;/code&gt;, &lt;code&gt;Page.MyValue&lt;/code&gt;, or &lt;code&gt;Page.MyDogIsADoofus&lt;/code&gt;, and assign values to them. &lt;br /&gt;&lt;br /&gt;Some folks consider syntax like &lt;code&gt;Page.Title&lt;/code&gt; to be cleaner than using something like &lt;code&gt;PageData["Title"]&lt;/code&gt;. However, this isn't really the same as normal property syntax (e.g., &lt;code&gt;Request.Forms&lt;/code&gt;), because the dynamic property isn't getting compile-time type checking. And when you're using a dynamic property, some operations that look like they should work don't, like this:&lt;br /&gt;&lt;pre&gt;Page.MyCount = "3";&lt;br /&gt;if(Page.MyCount.IsInt()){&lt;br /&gt;    // Fail with compiler error. &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;PageData["name"]&lt;/code&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2368'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2368</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2368</guid><pubDate>Thu, 19 Apr 2012 01:04:11 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2368">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2368</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2368</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2368</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Two small ASP.NET Web Pages (Razor) syntax tips</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2366</link><description>Two tips for Razor syntax: using a conditional attribute to set the &lt;code&gt;selected&lt;/code&gt; attribute in a list item; working around a syntax restriction on &lt;code&gt;x@x&lt;/code&gt; (e.g. &lt;code&gt;&amp;lt;h@level&amp;gt;&lt;/code&gt;).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Tip 1&lt;/strong&gt;&lt;br /&gt;When I wrote recently &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=2353" target="_blank"&gt;about conditional attributes&lt;/a&gt; in ASP.NET Web Pages version 2 (new for that version), the example was the &lt;code&gt;checked&lt;/code&gt; attribute of a checkbox. What about dynamically selecting an item in a &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; list? &lt;br /&gt;&lt;br /&gt;I wanted the &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; list to remember the user’s choice after the page had been submitted. In an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element, you can do this by setting the &lt;code&gt;value&lt;/code&gt; attribute to the appropriate item in the &lt;code&gt;Request&lt;/code&gt; collection:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;input type="input" name="firstName" value="@Request.Form["firstName"]" /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In my case, I'm populating the &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; list from a database query (i.e. a collection) using a &lt;code&gt;foreach&lt;/code&gt; loop. So I can use this code to compare each item against the user's most recent selection and set the &lt;code&gt;selected&lt;/code&gt; attribute conditionally:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;select name="selectGenre"&amp;gt;&lt;br /&gt;   @foreach(var row in db.Query("Select DISTINCT Genre FROM Movies ORDER BY Genre")){&lt;br /&gt;      &amp;lt;option &lt;br /&gt;          &lt;span style='background-color:yellow'&gt;selected=@(row.Genre==Request.Form["selectGenre"])&amp;gt;&lt;/span&gt;&lt;br /&gt;          @row.Genre&lt;br /&gt;      &amp;lt;/option&amp;gt;&lt;br /&gt;   }&lt;br /&gt;&amp;lt;/select&amp;gt;&lt;/pre&gt;As each row is processed, I compare its &lt;code&gt;Genre&lt;/code&gt; property/field against whatever was selected for the last page submission. If there's a match, the comparison returns true and the &lt;code&gt;selected&lt;/code&gt; attribute is rendered.&lt;br /&gt;&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2366'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2366</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2366</guid><pubDate>Wed, 11 Apr 2012 07:15:32 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2366">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2366</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2366</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2366</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Full list of new features for ASP.NET Web Pages v2 Beta</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2359</link><description>Ok, we've now got a list of the new features for ASP.NET Web Pages v2 posted. Here's a list of the stuff that's been added since the December 2011 preview, as recounted in the updated &lt;a href="http://www.asp.net/web-pages/overview/what's-new/top-features-in-web-pages-2#Changes_for_the_Beta_Version" target="_blank"&gt;Top Features doc&lt;/a&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Conditional attributes. Described &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=2353" target="_blank"&gt;earlier&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;Validation.GetHtml&lt;/code&gt; has been changed to &lt;code&gt;Validation.For&lt;/code&gt;. This method renders the goo that's used to hook client-side validation. See &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=2347" target="_blank"&gt;earlier&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;li&gt;The &lt;code&gt;~&lt;/code&gt; operator is now recognized in HTML markup, so you don't need to use &lt;code&gt;Href&lt;/code&gt; any more to resolve it. See &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=2357" target="_blank"&gt;earlier&lt;/a&gt;. I think this is my favorite feature, actually, even tho some might consider it comparatively small, dunno. &lt;br /&gt;&lt;br /&gt;&lt;li&gt;The &lt;code&gt;Scripts&lt;/code&gt; helper was renamed to &lt;code&gt;Assets&lt;/code&gt; (aka the Assets Manager), and the method names were tweaked. If you were using &lt;code&gt;Scripts&lt;/code&gt; to register scripts or &lt;em&gt;.css&lt;/em&gt; files,  you have to change those references.&lt;/ul&gt;The rest of the doc describes the features that are new in v2 generally, starting in the December preview. If you installed that preview, then you'll know all about those. :-)</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2359</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2359</guid><pubDate>Wed, 14 Mar 2012 22:52:04 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2359">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2359</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2359</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2359</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>New for ASP.NET Web Pages: Better ~ operator support</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2357</link><description>Another improvement in the Beta release of ASP.NET Web Pages v2 is better integration of the &lt;code&gt;~&lt;/code&gt; operator. The &lt;code&gt;~&lt;/code&gt; operator, as ASP.NET people know, resolves to the root path of the current website. (&lt;a href="http://msdn.microsoft.com/en-us/library/ms178116.aspx" target="_blank"&gt;See also&lt;/a&gt;) This is handy for creating URL paths, because it means that a) you don't need to hard-code an absolute URL and b) it isn't relative to the location of the current page. You don't need to worry about how many folders up you need to count (e.g. &lt;code&gt;../../path&lt;/code&gt;) or about what happens if the current page moves.&lt;br /&gt;&lt;br /&gt;In Web Pages v1 (as in all ASP.NET code), the &lt;code&gt;~&lt;/code&gt; operator is supported. But it only works in server code; it's not supported in native HTML, so to speak. If you want to create a path that uses the &lt;code&gt;~&lt;/code&gt; operator, you therefore have to wrap the path into something that tells ASP.NET that you've got server code. Inside of markup, we &lt;a href="http://www.asp.net/web-pages/tutorials/basics/2-introduction-to-asp-net-web-programming-using-the-razor-syntax#ID_WorkingWithFileAndFolderPaths" target="_blank"&gt;use the &lt;code&gt;Href&lt;/code&gt; method&lt;/a&gt;. For example, to create an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; link that incorporates it, you have to do this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;a href="&lt;span style='background-color:yellow'&gt;@Href("~/Default")&lt;/span&gt;"&amp;gt;Home&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It works, but it's not very intuitive.&lt;br /&gt;&lt;br /&gt;For v2 Beta, the &lt;em&gt;.cshtml&lt;/em&gt; parser was enhanced so that it can recognize the &lt;code&gt;~&lt;/code&gt; operator inline with normal markup. So the previous example can now be written like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;a href="&lt;span style='background-color:yellow'&gt;~/Default&lt;/span&gt;"&amp;gt;Home&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;No need for the &lt;code&gt;Href&lt;/code&gt; method any more. In &lt;em&gt;.cshtml&lt;/em&gt; pages (not plain &lt;em&gt;.html&lt;/em&gt; or &lt;em&gt;.htm&lt;/em&gt; pages, of course), you really can treat the &lt;code&gt;~&lt;/code&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2357'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2357</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2357</guid><pubDate>Wed, 07 Mar 2012 08:40:38 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2357">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2357</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2357</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2357</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>New for ASP.NET Web Pages: Conditional attributes</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2353</link><description>The beta release of ASP.NET Web Pages has been released (for example, as part of the &lt;a href="http://www.asp.net/mvc/mvc4" target="_blank"&gt;ASP.NET MVC&amp;nbsp;4 Beta release&lt;/a&gt;). There are only a few differences from the December 2011 Developer Preview release. (Details when we've got them posted.)&lt;br /&gt;&lt;br /&gt;A very cool feature is what's being called &lt;em&gt;conditional attributes&lt;/em&gt;. The idea is that in markup, you can set the value of an element's attribute to a variable or expression. If the variable or expression returns false or null, the &lt;em&gt;entire attribute is not rendered&lt;/em&gt;. There are a variety of uses for this, but it does a great job of solving a problem we inherited from HTML 1.0 (I think it was).&lt;br /&gt;&lt;br /&gt;The problem manifests in cases where the simple appearance of an attribute name &amp;mdash; regardless of its value &amp;mdash; is sufficient to trigger HTML behavior. One case is the checkbox, i.e., the &lt;code&gt;&amp;lt;input&amp;nbsp;type="checkbox"&amp;gt;&lt;/code&gt; element:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;input type="checkbox" name="check1" value="check1" checked /&amp;gt;&lt;br /&gt;&amp;lt;input type="checkbox" name="check1" value="check1" checked="true" /&amp;gt;&lt;br /&gt;&amp;lt;input type="checkbox" name="check1" value="check1" checked="anyThingAtAll" /&amp;gt;&lt;/pre&gt;&lt;br /&gt;Notice that in the first one, the &lt;code&gt;checked&lt;/code&gt; attribute doesn't even have a value. Nonetheless, all of these work the same, namely they produce checkbox that's selected. &lt;br /&gt;&lt;br /&gt;There's a similar situation with items in a selection list:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;select&amp;gt;&lt;br /&gt;   &amp;lt;option value="A"&amp;gt;A&amp;lt;/option&amp;gt;&lt;br /&gt;   &amp;lt;option value="B" selected&amp;gt;B&amp;lt;/option&amp;gt;&lt;br /&gt;   &amp;lt;option value="C"&amp;gt;C&amp;lt;/option&amp;gt;&lt;br /&gt; &amp;lt;/select&gt;&lt;/pre&gt;&lt;br /&gt;Technically, to select item B, the tag should read &lt;code&gt;&amp;lt;option value="B" selected="selected"&amp;gt;&lt;/code&gt;, but just including the &lt;code&gt;selected&lt;/code&gt; attribute works.&lt;br /&gt;&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2353'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2353</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2353</guid><pubDate>Thu, 01 Mar 2012 14:07:57 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2353">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2353</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2353</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2353</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Updated validation in Web Pages v2, Part 3</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2351</link><description>As noted &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=2344" target="_blank"&gt;previously&lt;/a&gt;, to display validation errors in ASP.NET Web Pages v2, you can use &lt;code&gt;Html.ValidationMessage&lt;/code&gt; and &lt;code&gt;Html.ValidationSummary&lt;/code&gt;. You can use one or the other or both. If you use both, one idea is to use &lt;code&gt;ValidationMessage&lt;/code&gt; to show an "error icon" and &lt;code&gt;ValidationSummary&lt;/code&gt; to show the details:&lt;br /&gt; &lt;br /&gt;&lt;div style="margin-left:25px;"&gt;&lt;img src="http://www.mikepope.com/blog/images/ValidationFormatting2.png" width='273' height='174' /&gt;&lt;/div&gt;Rather a plain display. However, you can style the output of the messages using some reserved CSS class names, to wit:&lt;ul&gt;&lt;li&gt;&lt;code&gt;input-validation-error&lt;/code&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;field-validation-error&lt;/code&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;validation-summary-errors&lt;/code&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;field-validation-valid&lt;/code&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;input-validation-valid&lt;/code&gt;&lt;br /&gt;&lt;li&gt;&lt;code&gt;validation-summary-valid&lt;/code&gt;&lt;/ul&gt;For example, to make a particularly forceful (if ugly) error display, define classes like this:&lt;br /&gt;&lt;pre&gt;&amp;lt;style&amp;gt;&lt;br /&gt;   .validation-summary-errors{&lt;br /&gt;      border:2px solid red; &lt;br /&gt;      color:red; &lt;br /&gt;      font-weight:bold;&lt;br /&gt;      padding:10px;&lt;br /&gt;      margin:10px;&lt;br /&gt;      width:30%}&lt;br /&gt;   &lt;br /&gt;   .field-validation-error{&lt;br /&gt;      color:red; &lt;br /&gt;      font-weight:bold; &lt;br /&gt;      background-color:yellow;}&lt;br /&gt;   &lt;br /&gt;   .input-validation-error{&lt;br /&gt;      color:red; &lt;br /&gt;      font-weight:bold; &lt;br /&gt;      background-color:pink;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;/pre&gt;&lt;br /&gt;And when the errors appear, they will be &lt;em&gt;noticeable&lt;/em&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left:25px;"&gt;&lt;img src="http://www.mikepope.com/blog/images/ValidationFormatting1.png" width='496' height='208' /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Formatting Client-Side Validation Errors&lt;/h3&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2351'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2351</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2351</guid><pubDate>Sat, 25 Feb 2012 21:41:05 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2351">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2351</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2351</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2351</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Updated validation in Web Pages v2, Part 2</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2347</link><description>In the &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=2344" target="_blank"&gt;last post&lt;/a&gt;, I laid out the basics of the &lt;code&gt;Validation&lt;/code&gt; helper that's introduced in ASP.NET Web Pages v2. As I noted then, the helper supports both server- and client-side validation. Here's how to implement the client side.&lt;br /&gt;&lt;br /&gt;So, you've got a page that already does this:&lt;ol&gt;&lt;li&gt;In code, calls &lt;code&gt;Validation.RequireField&lt;/code&gt;, &lt;code&gt;Validation.RequireFields&lt;/code&gt;, or &lt;code&gt;Validation.Add&lt;/code&gt; to register each input element for validation.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In code, calls &lt;code&gt;Validation.IsValid&lt;/code&gt; to determine whether all validation checks have passed.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In markup, calls &lt;code&gt;Html.ValidationMessage&lt;/code&gt; (for each validated element) and/or &lt;code&gt;Html.ValidationSummary&lt;/code&gt; (once) to display any validation errors.&lt;/ol&gt;To add client functionality, you &lt;em&gt;additionally&lt;/em&gt; do this:&lt;br /&gt;&lt;ol start="4"&gt;&lt;li&gt;Register the following JavaScript libraries in the page:&lt;br /&gt;&lt;pre&gt;&amp;lt;script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.js"&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script &lt;br /&gt;src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.8.1/jquery.validate.js"&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script src="@Href("~/Scripts/jquery.validate.unobtrusive.js")"&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;Two of the three libraries are loadable from a content delivery network (CDN), so you don't necessarily have to have them on your computer or server. However, you do have to have a local copy of &lt;em&gt;jquery.validate.unobtrusive.js&lt;/em&gt;. For now, the easiest (if somewhat hacky) way to get this is to create a new Web Pages site based on one of the site templates (e.g. Starter Site). The site created by the template includes the &lt;em&gt;jquery.validate.unobtrusive.js&lt;/em&gt; file in its &lt;em&gt;Scripts&lt;/em&gt; folder, from which you can copy it to your site.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In markup, for each element that you're validating, add a call to &lt;strike&gt;&lt;code&gt;Validation.GetHtml(&lt;em&gt;field&lt;/em&gt;)&lt;/code&gt;&lt;/strike&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2347'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2347</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2347</guid><pubDate>Wed, 15 Feb 2012 08:55:34 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2347">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2347</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2347</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2347</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Updated validation in Web Pages v2</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2344</link><description>In v1 of ASP.NET Web Pages, you could add user-input validation by doing something like this in code:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;if (name.IsEmpty()) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ModelState.AddError("Name", "You must enter a name.");&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In v2, there's a new &lt;code&gt;Validation&lt;/code&gt; helper that has some nifty features:&lt;ul&gt;&lt;li&gt;Methods to check for required fields, data types, string length, numeric ranges, the same values in two fields (as for new passwords), and patterns (i.e., RegEx).&lt;br /&gt;&lt;li&gt;Methods to display both field-specific and summary validation error messages.&lt;br /&gt;&lt;li&gt;Both client-side (instant) and server-side (post-submit) validation. "A double dose of valid!" (&lt;a href="http://nancyfriedman.typepad.com/away_with_words/2011/07/i-scream-you-scream-we-all-scream-for-anthimeria.html" target="_blank"&gt;#&lt;/a&gt;)&lt;/ul&gt;For client validation, you also get:&lt;ul&gt;&lt;li&gt;Unobtrusive JavaScript techniques to minimize client code in the file, relying instead on semantic attributes in the markup.&lt;br /&gt;&lt;li&gt;No submit until all values are valid.&lt;/ul&gt;&lt;br /&gt;You can use the &lt;code&gt;Validation&lt;/code&gt; helper to provide only server-side validation or both client- and server-side checks. (You always get server validation, for security reasons.) The basic steps for server-side validation are:&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Determine which input elements (fields) you want to validate&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;You typically validate values in &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; elements in a form. However, it is a good practice to validate all input, even input that comes from a constrained element like a &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; list, because users can bypass the controls on a page and submit a form.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Add individual validation checks for each input element (field)&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In the page's code block, call one of the methods of the &lt;code&gt;Validation&lt;/code&gt; helper that perform validation: &lt;code&gt;RequireField&lt;/code&gt;, &lt;code&gt;RequireFields&lt;/code&gt;, or &lt;code&gt;Add&lt;/code&gt;. Pass to the method the name (the &lt;code&gt;name&lt;/code&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2344'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2344</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2344</guid><pubDate>Wed, 08 Feb 2012 20:45:45 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2344">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2344</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2344</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2344</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>WebMatrix and ASP.NET Web Pages books</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2342</link><description>We're quite happy to see a number of books about WebMatrix and ASP.NET Web Pages become available. Here is the list of books that I'm aware of at the moment:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/1118050487/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=oraforum-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399373&amp;amp;creativeASIN=1118050487"&gt;Beginning ASP.NET Web Pages with WebMatrix&lt;/a&gt;&lt;br /&gt;Mike Brind, Imar Spaanjaars. Mike is a superstar on the &lt;a href="http://forums.asp.net/1224.aspx/1?WebMatrix+and+ASP+NET+Web+Pages" target="_blank"&gt;ASP.NET Web Pages forums&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.co.uk/Building-ASP-NET-WebMatrix-Need2Know-ebook/dp/B006GHBZ3C"&gt;Building ASP.NET Web Pages with WebMatrix (Need2Know)&lt;/a&gt;&lt;br /&gt;Jim Wang. Jim is one of the testers on the ASP.NET team.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/1430240202/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=lamoswenebl-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1430240202"&gt;Building ASP.NET Web Pages with Microsoft WebMatrix (The Expert's Voice in .Net)&lt;/a&gt;&lt;br /&gt;Steve Lydford (&lt;strong style="color:red;"&gt;Update&lt;/strong&gt;: see Steve's &lt;a href="http://mikepope.com/blog/AddComment.aspx?blogid=2342#listComments_ctl00_labelCommentEntryDate" target="_blank"&gt;comment&lt;/a&gt;, including the bit about the open-source ecommerce sample that he's making available) &lt;br /&gt;&lt;br /&gt;&lt;a href="http://shop.oreilly.com/product/0790145308870.do"&gt;Introducing Microsoft® WebMatrix&lt;/a&gt;&lt;br /&gt;Laurence Moroney &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ubelly.com/2011/06/free-webmatrix-e-book/"&gt;UBelly: A Guide to Web Development 101 Using WebMatrix&lt;/a&gt;&lt;br /&gt;Andy Robb&lt;br /&gt;&lt;br /&gt;There's also the &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=15979" target="_blank"&gt;PDF version&lt;/a&gt; of the &lt;a href="http://www.asp.net/web-pages/tutorials/basics/1-getting-started-with-webmatrix-and-asp-net-web-pages" target="_blank"&gt;tutorials&lt;/a&gt; that are on the &lt;a href="http://asp.net/web-pages" target="_blank"&gt;http://asp.net/web-pages&lt;/a&gt; site. &lt;br /&gt;&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2342'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2342</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2342</guid><pubDate>Thu, 02 Feb 2012 10:50:40 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2342">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2342</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2342</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2342</wfw:commentRss><slash:comments>1</slash:comments></item><item><title>Horizontal menu as a Razor helper</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2341</link><description>On the forums, someone was asking about creating a horizontal menu using Razor code in ASP.NET Web Pages. The technique of combining an unordered list (&lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; element) with CSS to create a horizontal layout, using &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; elements as the menu items, is a pretty well-known one; you can find examples &lt;a href="http://www.maxdesign.com.au/articles/css-layouts/two-liquid/" target="_blank"&gt;here&lt;/a&gt; and &lt;a href="http://www.devinrolsen.com/pure-css-horizontal-menu/" target="_blank"&gt;here&lt;/a&gt;, not to mention in the &lt;em&gt;Site.css&lt;/em&gt; file that comes with a lot of the Visual Studio web project templates.&lt;br /&gt;&lt;br /&gt;The actual Razor part is likewise not hard. Someone showed this code as a way to dynamically build a list (to which you'd then apply the CSS):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;ul&amp;gt;&lt;br /&gt;@foreach (var item in collection)&lt;br /&gt;{&lt;br /&gt;    &amp;lt;li&amp;gt;@item&amp;lt;/li&amp;gt;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;/pre&gt;The interesting part was a comment that the original poster made: &lt;blockquote&gt;It sounds like if I have lots of logic inside the loop, I might be best served moving that to the back end somewhere and just calling a method that returns the text to display within each list item.&lt;/blockquote&gt;What this sounded like to me was a fun excuse to see about creating a custom helper. Helpers are, in effect, chunks of code and markup; when you invoke the helper, it runs the code and emits the markup. For example, by creating a helper to render a horizontal menu, you could do something like this in a page:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@MyHelpers.HorizontalMenu(&lt;br /&gt;    "Home|Default.cshtml", &lt;br /&gt;    "About|About.cshtml", &lt;br /&gt;    "Login|Login.cshtml", &lt;br /&gt;    "Register|Register.cshtml")&lt;br /&gt;&amp;lt;h1&amp;gt;My Page&amp;lt;/h1&amp;gt;&lt;br /&gt;      &amp;lt;p&amp;gt;Hello, horizontal menu.&amp;lt;/p&amp;gt;&lt;/pre&gt;And get something like this:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left:25px;"&gt;&lt;img src="http://www.mikepope.com/blog/images/RazorHorizontalMenu.png" width='477' height='161' /&gt;&lt;/div&gt;Well, anyway, in the &lt;em&gt;App_Code&lt;/em&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2341'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2341</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2341</guid><pubDate>Wed, 01 Feb 2012 18:01:21 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2341">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2341</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2341</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2341</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Need feedback: draft article about request validation</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2340</link><description>A couple of us on the ASP.NET documentation team are working on a topic that describes how to disable request validation in ASP.NET. What do you think about the following draft? Any feedback welcome.&lt;br /&gt;&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;em&gt;Request validation&lt;/em&gt; is a feature in ASP.NET that examines an HTTP request and determines whether it contains potentially dangerous content. In this context, potentially dangerous content is any HTML markup or JavaScript code in the body, header, query string, or cookies of the request. ASP.NET performs this check because markup or code found in the URL query string, cookies, or posted form values might have been added to the request for malicious purposes.&lt;br /&gt;&lt;br /&gt;For example, if your site has a form where users enter comments, a malicious user could enter JavaScript code in a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; element. Then when you display the page with the comment to other users, the browser would execute that JavaScript code as if it had been generated by your website. This is commonly referred to as a &lt;em&gt;cross-site scripting&lt;/em&gt; (XSS) attack. &lt;br /&gt;&lt;br /&gt;Request validation helps prevent this kind of attack. If ASP.NET detects any markup or code in a request, it throws a "potentially dangerous value was detected " error and stops page processing. The default error page looks like this (click to enlarge):&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left:25px;"&gt;&lt;a href="http://www.mikepope.com/blog/images/PotentiallyDangerousError.png" target="_blank"&gt;&lt;img src="http://www.mikepope.com/blog/images/PotentiallyDangerousError_th.png" width='410' height='205' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Request validation throws this exception when any HTML markup is detected, including harmless markup like &lt;code&gt;&amp;lt;b&amp;gt;&lt;/code&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2340'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2340</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2340</guid><pubDate>Mon, 23 Jan 2012 08:46:27 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2340">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2340</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2340</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2340</wfw:commentRss><slash:comments>4</slash:comments></item><item><title>Getting custom info from the FileUpload helper </title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2329</link><description>In ASP.NET Web Pages, you can use the &lt;code&gt;FileUpload&lt;/code&gt; helper[&lt;a href='#gettingcustominformationfromthefileuploadhelper1'&gt;1&lt;/a&gt;] to render HTML that lets users upload one or more files. For example, this helper:&lt;br /&gt;&lt;pre&gt;@FileUpload.GetHtml(&lt;br /&gt;    initialNumberOfFiles: 1,&lt;br /&gt;    allowMoreFilesToBeAdded: false,&lt;br /&gt;    includeFormTag: true,&lt;br /&gt;    uploadText: "Upload File 1",&lt;br /&gt;    name: "Upload1"&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Renders this:&lt;br /&gt;&lt;div style="margin-left:25px;"&gt;&lt;img src="http://www.mikepope.com/blog/images/FileUpload_Rendered1.png" width='236' height='85' /&gt;&lt;/div&gt;&lt;br /&gt;The upload controls consist of a &lt;code&gt;&amp;lt;input type="file"&amp;gt;&lt;/code&gt; element and a submit button (&lt;code&gt;&amp;lt;input type="submit"&amp;gt;&lt;/code&gt;). By default, the helper renders a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element around this. For example, the markup rendered by the previous example is this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;form action="" enctype="multipart/form-data" method="post"&amp;gt;&lt;br /&gt;&amp;lt;div class="file-upload" id="file-upload-0"&amp;gt;&lt;br /&gt;&amp;lt;div&amp;gt;&lt;br /&gt;    &amp;lt;input name="Upload1" type="file" /&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;div class="file-upload-buttons"&amp;gt;&lt;br /&gt;    &amp;lt;input type="submit" value="Upload File 1" /&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/pre&gt;&lt;br /&gt;(The &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; elements with their IDs let you specify CSS to make things pretty.)&lt;br /&gt;&lt;br /&gt;People sometimes ask whether there's a way to get additional information about the upload. For example, if you have two &lt;code&gt;FileUpload&lt;/code&gt; helpers on a page, can you tell which one submitted the file? &lt;br /&gt;&lt;br /&gt;Yes. Specify the helper this way:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;form method="post" name="form2" enctype="multipart/form-data"&amp;gt;&lt;br /&gt;	@FileUpload.GetHtml(&lt;br /&gt;	    initialNumberOfFiles: 1,&lt;br /&gt;	    allowMoreFilesToBeAdded: false,&lt;br /&gt;	    includeFormTag: false,&lt;br /&gt;	    uploadText: "Upload2",&lt;br /&gt;	    name: "Upload2"&lt;br /&gt;	)&lt;br /&gt;	&amp;lt;input type="submit" name="buttonUpload2" value="Upload File 2" /&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/pre&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2329'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2329</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2329</guid><pubDate>Thu, 17 Nov 2011 14:25:50 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2329">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2329</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2329</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2329</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>MembershipProvider error in ASP.NET Web Pages</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2327</link><description>If you use &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=2240" target="_blank"&gt;membership in ASP.NET Web Pages&lt;/a&gt;, you might get the error &lt;code&gt;To call this method, the "Membership.Provider" property must be an instance of "ExtendedMembershipProvider"&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left:25px;"&gt;&lt;img src="http://www.mikepope.com/blog/images/MembershipProviderError_YSoD.gif" width='592' height='542' /&gt;&lt;/div&gt;&lt;br /&gt;I happened to run across this while playing around with the &lt;a href="http://www.asp.net/webmatrix/tutorials/the-top-features-in-web-pages-2-developer-preview#oauthsetup" target="_blank"&gt;new OAuth login capabilities&lt;/a&gt; in the beta version of Web Pages 2, but you might see it under other conditions as well. &lt;br /&gt;&lt;br /&gt;Per one of our testers, this can indicate that the server has no &lt;code&gt;AspNetSqlMembershipProvider&lt;/code&gt; configured. (A clue here is that everything works great when you test locally, but then throws an error when you deploy to your hosting provider.)&lt;br /&gt;&lt;br /&gt;In my case, I fixed this by adding the following to the site's local &lt;em&gt;Web.config&lt;/em&gt; file:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;appSettings&amp;gt;&lt;br /&gt;  &amp;lt;add key="enableSimpleMembership" value="true" /&amp;gt;&lt;br /&gt;&amp;lt;/appSettings&amp;gt;&lt;/pre&gt;This is a child of the &lt;code&gt;&amp;lt;configuration&amp;gt;&lt;/code&gt; element and a peer of the &lt;code&gt;&amp;lt;system.web&amp;gt;&lt;/code&gt; element.&lt;br /&gt;&lt;br /&gt;Anyway, that worked for me. I'm curious if others have seen this error and if so, how they fixed it.</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2327</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2327</guid><pubDate>Tue, 15 Nov 2011 22:23:45 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2327">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2327</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2327</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2327</wfw:commentRss><slash:comments>3</slash:comments></item><item><title>Installing version 1 of WebMatrix after installing WM2 beta</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2318</link><description>The &lt;a href="http://www.microsoft.com/web/webmatrix/betafeatures.aspx" target="_blank"&gt;beta version of WebMatrix&amp;nbsp;2&lt;/a&gt; was put out for public consumption around the time of the //build/ conference in September. Very nice.&lt;br /&gt;&lt;br /&gt;However, installing WebMatrix&amp;nbsp;2 beta makes it harder to install (reinstall) the WebMatrix&amp;nbsp;1 (actually, 1.1), should you ever need to do that. (I did recently.) If you go to the download page and try to install the non-beta version of WebMatrix you won't get it, even if you carefully and explicitly don't choose the beta download option. You'll be offered WebMatrix&amp;nbsp;2 beta only.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.mikepope.com/blog/images/WebMaterixBetaInstall.png" width='677' height='163' /&gt;&lt;br /&gt;&lt;br /&gt;Turns out this is due to the installer. WebMatrix is installed via Web Platform Installer (WebPI). When you install the Beta release, you first get an updated version of WebPI, and the updated version of WebPI knows only about the beta version of WebMatrix&amp;nbsp;2.&lt;br /&gt;&lt;br /&gt;Anyway, long story short, if you've instaslled WebMatrix&amp;nbsp;2 Beta but for some reason need to reinstalled WebMatrix&amp;nbsp;1, you need to uninstall WebPI.&lt;br /&gt;&lt;br /&gt;(Thanks to &lt;a href="http://social.msdn.microsoft.com/Profile/Chris%20Sfanos%20-%20MSFT" target="_blank"&gt;Chris Sfanos&lt;/a&gt; and his WebMatrix expertise for sorting this one out for me.)</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2318</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2318</guid><pubDate>Tue, 18 Oct 2011 08:36:26 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2318">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2318</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2318</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2318</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Deploying Web Pages applications without a tool</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2317</link><description>The canonical way to deploy a Web Pages application to a remote server is to use the &lt;a href="http://www.microsoft.com/web/post/how-to-publish-a-web-application-using-webmatrix" target="_blank"&gt;Publish facility of WebMatrix&lt;/a&gt;. (Or the publish facilities in Visual Studio, if that's what you're using.) Using a publish tool is nice, because it copies not just your application files (&lt;em&gt;.cshtml&lt;/em&gt; pages, etc.), but also dependencies, notably the DLL files that are required for Web Pages (Razor) and the DLLs for SQL Server Compact, if needed.&lt;br /&gt;&lt;br /&gt;But what if you cannot (or don't want to) use WebMatrix for deploying? You can still deploy using something like FTP, but it's then up to you to include the dependencies. This isn’t hard, it's just that you need to know what files to copy, from where, and where to put them.&lt;br /&gt;&lt;br /&gt;To perform a manual FTP deploy, you copy everything from the website on your development computer (root folder + children) to the appropriate folder on the server. Copy all the &lt;em&gt;.cshtml&lt;/em&gt; files, &lt;em&gt;.html&lt;/em&gt; files, &lt;em&gt;.css&lt;/em&gt; files, images, etc. (If you've got data in &lt;em&gt;App_Data&lt;/em&gt;, there are additional considerations &amp;mdash; see below.) &lt;br /&gt;&lt;br /&gt;Then on the server, if there isn't already a &lt;em&gt;bin&lt;/em&gt; folder under your app root, create one. (If you've installed NuGet packages, there probably already is a &lt;em&gt;bin&lt;/em&gt; folder that contains the package files.) Copy everything that's in the following folder to the app's &lt;em&gt;bin&lt;/em&gt; folder on the server:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;C:\Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;For a 64-bit machine, that's the &lt;code&gt;Program Files&amp;nbsp;(x86)&lt;/code&gt; folder.&lt;br /&gt;&lt;br /&gt;This copies all the ASP.NET Web Pages assemblies &amp;mdash; that is, the dependencies &amp;mdash; to the server for this app. You need to copy the DLL files to the &lt;em&gt;bin&lt;/em&gt; folder separately for each application that you deploy.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Deploying SQL Server Compact&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2317'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2317</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2317</guid><pubDate>Fri, 14 Oct 2011 13:06:39 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2317">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2317</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2317</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2317</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Using Windows authentication in ASP.NET Web Pages</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2298</link><description>When I &lt;a href="http://mikepope.com/blog/AddComment.aspx?blogid=2240" target="_blank"&gt;wrote&lt;/a&gt; about using simple membership in ASP.NET Web Pages a little while ago, commenter akshayms &lt;a href="http://mikepope.com/blog/AddComment.aspx?blogid=2240#2240_2661" target="_blank"&gt;asked&lt;/a&gt; "How can I use Windows authentication"? Simple membership uses a login form and a membership database for managing a site's users. In contrast, Windows authentication just uses your existing Windows login credentials; no need to log in separately. Windows auth is useful for intranet sites, like on a corporate network.&lt;br /&gt;&lt;br /&gt;When the question first came up, I asked around, because I hadn't played with it myself. The first answer was "Just like in 'normal' ASP.NET!", which is to say, by setting the authentication mode in the application's &lt;em&gt;Web.config&lt;/em&gt; file to "Windows." (&lt;a href="http://msdn.microsoft.com/en-us/library/ff647405.aspx" target="_blank"&gt;Documentation&lt;/a&gt;.) Like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;authentication mode="Windows" /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It turned out, tho, that this didn't entirely  work. Anyway, long story short, it looks like you do this:&lt;ul&gt;&lt;li&gt;Disable simple membership.&lt;/li&gt;&lt;li&gt;Require authentication. (Duh, right? Hold that thought.)&lt;/li&gt;&lt;/ul&gt;(Windows authentication also needs to be enabled, but that's the default in ASP.NET, so you don't actually need to explicitly switch that on.)&lt;br /&gt;&lt;br /&gt;You can do these by creating a &lt;em&gt;Web.config&lt;/em&gt; file in the Web Pages application and adding the following to it. (Highlights for the interesting bits.) &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;    &lt;span style="background-color:yellow;"&gt;&amp;lt;appSettings&amp;gt;&lt;br /&gt;        &amp;lt;add key="EnableSimpleMembership" value="false" /&amp;gt;&lt;br /&gt;    &amp;lt;/appSettings&amp;gt;&lt;/span&gt;&lt;br /&gt;    &amp;lt;system.web&amp;gt;&lt;br /&gt;        &amp;lt;compilation debug="false" targetFramework="4.0" /&amp;gt;&lt;br /&gt;        &lt;span style="background-color:yellow;"&gt;&amp;lt;authorization&amp;gt;&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2298'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2298</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2298</guid><pubDate>Tue, 16 Aug 2011 10:53:47 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2298">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2298</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2298</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2298</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Componentizing code in WebMatrix pages</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2283</link><description>At first glance, you might thing that in WebMatrix Razor (&lt;em&gt;.cshtml&lt;/em&gt;, &lt;em&gt;.vbhtml&lt;/em&gt; files) you have to put &lt;em&gt;all&lt;/em&gt; your code into the page.  For example, if you sift through pages created by the Starter Site template or look at tutorials (&lt;a href="http://msdn.microsoft.com/en-us/library/hh145668(VS.99).aspx" target="_blank"&gt;example&lt;/a&gt;), you'll see the code -- including data-access code -- all in one page. &lt;br /&gt;&lt;br /&gt;Not so. WebMatrix websites are dynamically compiled. As such, you can work with them as with ASP.NET web sites -- specifically as with Visual Studio Web site projects. In particular, you can use &lt;a href="http://msdn.microsoft.com/en-us/library/t990ks23.aspx" target="_blank"&gt;shared code folders&lt;/a&gt;, which includes the &lt;em&gt;Bin&lt;/em&gt; and &lt;em&gt;App_Code&lt;/em&gt; folders. You can drop assemblies (&lt;em&gt;.dll&lt;/em&gt; files) into the &lt;em&gt;Bin&lt;/em&gt; folder, and they're automatically part of the site. Likewise you can put source-code files into the &lt;em&gt;App_Code&lt;/em&gt; folder, and they'll likewise automatically be part of your site. This makes it quite possible (easy, even) to componentize code for your pages.&lt;br /&gt;&lt;br /&gt;Here's a simple example. I've been messing around with creating a new blog from scratch using &lt;em&gt;.cshtml&lt;/em&gt; pages.[&lt;a href='#componentizingcodeinwebmatrixpages1'&gt;1&lt;/a&gt;] I'm told that for SEO, the URL of an individual entry should include keywords that are separated (only) by hyphens, like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;http://mysite/blog/an-example-blog-entry&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You see this on popular blog engines (&lt;a href="http://evolvingenglish.blogspot.com/2011/05/from-greek-battles-to-all-day.html" target="_blank"&gt;example&lt;/a&gt;, &lt;a href="http://nancyfriedman.typepad.com/away_with_words/2006/10/fear_of_words_a.html" target="_blank"&gt;example&lt;/a&gt;). My thinking here is that I can take the blog entry title, whatever it might be, and use that as the basis for an ID.&lt;br /&gt;&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2283'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2283</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2283</guid><pubDate>Wed, 06 Jul 2011 01:12:15 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2283">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2283</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2283</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2283</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>"Potentially Dangerous" errors in ASP.NET Web Pages (Razor)</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2282</link><description>By default, ASP.NET performs &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=441" target="_blank"&gt;request validation&lt;/a&gt; to prevent people from uploading HTML markup or script to your site. If someone includes markup in a page that they post to your site, ASP.NET throws a big ol' error:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left:25px;"&gt;&lt;img src="http://www.mikepope.com/blog/images/PotentiallyDangerousError.png" width='554' height='312' /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;"Potentially dangerous Request.Form value" is a little dramatic; ASP.NET throws this error for even innocuous stuff, like &lt;code&gt;&amp;lt;b&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt;. &lt;br /&gt;&lt;br /&gt;There are times when it's ok to let people submit HTML. For example, if you let people comment on things in your site, maybe you want to let them format their comments.&lt;br /&gt;&lt;br /&gt;&lt;p style="border:1px red solid;padding:6px;"&gt;&lt;strong&gt;Update 30 June 2011&lt;/strong&gt;: Ok, h/t to a &lt;a href="https://twitter.com/#!/shaver/status/86483661578448896" target="_blank"&gt;tweet&lt;/a&gt; about this post: before proceeding, make sure you have read and understand the &lt;span style="color:red;font-weight:bold;"&gt;very important&lt;/span&gt; note at the end.  :-) &lt;/p&gt;&lt;br /&gt;The error message suggests a remedy. However, if you're working with ASP.NET Web Pages (&lt;em&gt;.cshtml&lt;/em&gt; or &lt;em&gt;.vbhtml&lt;/em&gt; files), the information isn't really relevant, in two ways:&lt;ul&gt;&lt;li&gt;The proposed fix &amp;#8212; add &lt;code&gt;requestValidation="2.0"&lt;/code&gt; to the Web.config file &amp;#8212; isn't necessary. Don't do this if you're working with only &lt;em&gt;.cshtml&lt;/em&gt;/&lt;em&gt;.vbhtml&lt;/em&gt; pages.&lt;br /&gt;&lt;li&gt;The actual fix isn't listed.&lt;/ul&gt;Instead, to accept HTML, you can use code like this:&lt;br /&gt;&lt;pre&gt;@{&lt;br /&gt;  var editedText = "";&lt;br /&gt;  if(IsPost){&lt;br /&gt;      editedText = &lt;span style="background-color:yellow;"&gt;Request.Unvalidated().Form["textbox1"];&lt;/span&gt;&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2282'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2282</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2282</guid><pubDate>Wed, 29 Jun 2011 10:21:45 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2282">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2282</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2282</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2282</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Moving a website in WebMatrix</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2279</link><description>I created a website in WebMatrix and decided later to move it to a different location. Since the site's files are all self-contained, I just moved them in Windows Explorer. However, when I opened up WebMatrix, I went to My Sites and clicked on the site:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left:25px;"&gt;&lt;img src="http://www.mikepope.com/blog/images/MoveWMSite1.png" width='488' height='330' /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;However, this resulted in an error:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left:25px;"&gt;&lt;img src="http://www.mikepope.com/blog/images/MoveWMSite2.png" width='511' height='287' /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Of course. So the question is how to get WebMatrix to understand the site's new location. Turns out to be pretty easy. The site information is in the &lt;em&gt;applicationhost.config&lt;/em&gt; file which is in turn in (here's the not-intuitive part) the &lt;em&gt;My Documents\IISExpress\config&lt;/em&gt; folder. &lt;br /&gt; &lt;br /&gt;This is an XML file that has a &lt;sites&gt; element containing a child &lt;site&gt; element for each site that WebMatrix knows about. All I had to do was change the highlighted bit to point to the new location:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;site name="MotorcycleBlog" id="11"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;application path="/"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;virtualDirectory path="/" &lt;span style="background-color:yellow;"&gt;physicalPath="C:\MotorcycleBlog"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/application&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;bindings&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;binding protocol="http" bindingInformation="*:6867:localhost" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/bindings&amp;gt;&lt;br /&gt;&amp;lt;/site&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And thereafter WebMatrix opened the moved site from the correct location.</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2279</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2279</guid><pubDate>Sat, 04 Jun 2011 10:05:54 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2279">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2279</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2279</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2279</wfw:commentRss><slash:comments>3</slash:comments></item><item><title>Constructing site URLs in ASP.NET Razor</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2273</link><description>The other day I showed &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=2267" target="_blank"&gt;how to send a confirmation email when people register on your site&lt;/a&gt;. In the example, I created a link that points to a confirmation page on my site, and I hard-coded the URL of that link. This isn't such a great idea; it makes the code non-portable should you decide to use it in a different site. If you only have one place in your site where you're constructing a link, maybe that isn't a huge problem, but in general, hard-coding things like your site's address will end up biting you. (Ask me how I know.)&lt;br /&gt;&lt;div style="margin-left:50px"&gt;&lt;a href="http://blog.peelmeagrape.net/" target="_blank"&gt;&lt;img src="http://www.mikepope.com/blog/images/UrlGraphic.png" width='178' height='123' style="margin:8px;border:none;"/&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;There are a couple of ways to get around this. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Hard-coding in a central location&lt;/h3&gt;&lt;br /&gt;One approach is to go ahead and hard-code the site's URL, but to do it in only one central place where you can easily change it if you want to. (Semi-hard-coding it?) In ASP.NET Web Pages applications, you can do this in the &lt;em&gt;_AppStart.cshtml&lt;/em&gt; (or &lt;em&gt;_AppStart.vbhtml&lt;/em&gt;) file using the &lt;code&gt;AppState&lt;/code&gt; object. This object just stores information that you want to have available anywhere in the site. This would be a typical way to store something global like the site's URL:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@{&lt;br /&gt;    WebSecurity.InitializeDatabaseConnection("TestMembership",&lt;br /&gt;       "UserProfile", &lt;br /&gt;       "UserId", &lt;br /&gt;       "Email", &lt;br /&gt;       true);&lt;br /&gt;&lt;br /&gt;    WebMail.SmtpServer = "&lt;em&gt;mySMTPServer&lt;/em&gt;";&lt;br /&gt;    WebMail.EnableSsl = true;&lt;br /&gt;    WebMail.UserName = "&lt;em&gt;myUserName&lt;/em&gt;";&lt;br /&gt;    WebMail.Password = "&lt;em&gt;myPassword&lt;/em&gt;";&lt;br /&gt;    WebMail.From = "mike@mikepope.com";&lt;br /&gt;    &lt;br /&gt;    &lt;span style="background-color:yellow;"&gt;AppState["siteURL"] = "http://www.mikepope.com/TestMembership/"&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2273'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2273</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2273</guid><pubDate>Thu, 26 May 2011 23:25:40 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2273">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2273</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2273</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2273</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Using the confirmation feature for ASP.NET Web Pages security</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2267</link><description>When I &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=2240"&gt;described&lt;/a&gt; the most basic way to implement security (membership) for ASP.NET Web Pages/Razor websites, I skipped over a feature that you can add to the registration page &amp;#8212; namely, confirmation for registration. You're undoubtedly familiar with how this works. You register on a site, and they say "Go check your email!" You get an email from them that requests that you click a link in order to finish the registration process. You do that, and then &amp;#8212; but only then &amp;#8212; you are allowed to log in.&lt;br /&gt;&lt;br /&gt;This two-step process has a couple of benefits. One is that it helps to make sure that whoever is registering is actually a human and not a bot. In a sense, I suppose, it also helps make sure that people who register really want to register, since they need to go to some extra trouble. It also prevents people from registering multiple identities, since their user name is their (real) email name.&lt;br /&gt;&lt;br /&gt;Adding confirmation to the registration process requires this:&lt;ul&gt;&lt;li&gt;In the registration page, you create the member account like normal by calling &lt;code&gt;WebSecurity.CreateUserAndAccount&lt;/code&gt;, but you pass &lt;strong&gt;true&lt;/strong&gt; for the &lt;code&gt;requireConfirmationToken&lt;/code&gt; parameter.&lt;br /&gt;&lt;br /&gt;The method creates the membership account and also returns a token to you. The token is a value (it might look like &lt;code&gt;LR9888HmlCEkiL3/GdUY5g==&lt;/code&gt;) that uniquely identifies the new membership account. In the database record for the membership account, there's an &lt;code&gt;IsConfirmed&lt;/code&gt; field that will be set to &lt;strong&gt;false&lt;/strong&gt;. Because of this, the user cannot log in yet.&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left:50px"&gt;&lt;img src="http://www.mikepope.com/blog/images/Membership_IsConfirmedFalse.png" width="485" height="109" alt="Image of membership table showing IsConfirmed field as false for several users" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2267'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,webmatrix</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=2267</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2267</guid><pubDate>Sun, 15 May 2011 22:47:06 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2267">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=2267</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=2267</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=2267</wfw:commentRss><slash:comments>0</slash:comments></item></channel></rss>