mike's web log

Entries for category aspnet
 

Blog Search


(Supports AND)

 

Google Ads

 

Technorati

 

Feed

Subscribe to the RSS feed for this blog.

See this post for info on full versus truncated feeds.

 

Quote

The reality is that everything in science is tentative. Tomorrow's experiment, observation, or theory may well show that current beliefs need revision or replacement. However, our minds work differently. Most of us usually take what we hear or see and accept it as "fact." Once we do this, it is very hard to change our belief on the subject.

Neil Comins



 

Navigation






<September 2010>
SMTWTFS
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789


 

25 Most-Visited Entries

 

Categories

  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
  RSS
 

Blogs I Read

 

Contact

Email me
 

Blog Statistics

Dates
First entry - 6/27/2003
Most recent entry - 8/26/2010

Totals
Posts - 2109
Comments - 2170
Hits - 1,138,425

Averages
Entries/day - 0.80
Comments/entry - 1.03
Hits/day - 434

Update every 30 minutes. Last: 6:46 PM Pacific

 
   |  Handling version changes in documentation

posted at 06:12 PM | | |

Just wondering what sorts of examples people might have of documentation sets that cover multiple versions of the same product. In our doc set in MSDN, we basically republish each complete doc set, but updated for the new version with corrections and new features:


The advantage is you can go right to your version and be assured that what you're reading applies to you. The disadvantage is that the versions pile up (4 versions and counting), with a lot of overlap, which is inefficient in various dimensions.

Are you familiar with a doc set that handles versioning differently than this? (Conceptual or API reference or both.) If so, leave a comment with a link.

Thanks!

[categories] , ,


   |  WebMatrix and ASP.NET Razor

posted at 03:06 PM | | |

By now you'll probably know that we released (in beta) a new version, I guess you'd call it, of ASP.NET. It's not really a new version -- same old ASP.NET behind the scenes -- just a new and simpler syntax on top of ASP.NET. There are various ways to think about this, like "MVC for the rest of us" or "ASP Classic done right" or, you know, many others. :-) The emphasis is on reducing the amount of code (indeed, the "concept count") required to do many of the things that people want to be able to do with websites.

I just love this stuff. The Web Forms model was predicated on the idea of making web development something like forms for Windows client apps -- the page is a form, you drop controls onto it, set their properties, and respond to their events. This basically worked, although as many people pointed out over the years, this type of client-forms analogy was a leaky abstraction. There's a certain black-box quality to the Web Forms model, and doing tricky stuff -- perhaps just adding controls on the fly -- tended to make it clear just how much man there was behind the curtain. Plus its 8+ years of development have left it with a certain amont of cruft; even internally we still see questions about how to do things with (e.g.) the DataGrid control.

ASP.NET MVC of course seeks to remove all this and, in a sense, get back to the basics of GET and POST, and instead of patching over them, embraces the realities of Web programming, like statelessness. The theory of MVC is lovely, but the implementation remains, at this point anyway, something that seems a bit ambitious as a candidate for Web Development 101.[1] (Likewise Ajax, which in spite of the elegance of libraries like jQuery, is still for the code junkie.)

And now there's Razor syntax. I said it earlier sort of jocularly, but in a sense it really is MVC for the rest of us. It has the purity of MVC -- the abstraction level is (comparatively) low (no "web controls"), it trucks openly with standard Web mechanics, it does not spill gallons of markup into your pages. Plus it offers a set of APIs that represent, to sound contradictory for a moment, thoughtful abstractions of functionality that is popular and, lest we forget, can sometimes be annoyingly complex to accomplish in "normal" ASP.NET, like database access or managing files. Plus it's completely backed by ASP.NET and beyond that, the .NET Framework in a -- and if I read this word much more I'm going to scream -- seamless way.

For years I've poked at redoing my blog app, through ASP.NET 2.0, Dynamic Data, and then MVC. This time, I might really do it.[2] :-)

Anyway, we did something a little different for the documentation this time around as well. More about that next time.


[1] This is the point where someone says that no, MVC is precisely what people should learn first, in the way that C should be the first programming language you learn -- purity over abstractness.

[2] Not that I should have to. WebMatrix (the web stack of which Razor is one piece) comes with apps that you can download and customize, including several blog engines. But as before -- why, for the first version of Web Matrix -- the point for me was learning.

[categories]


   |  Out, damned space

posted at 02:48 AM | | [8] |

The other day I was doing something where I wanted to display some data as a comma-delimited list, like so:

a, b, c, d

This seemed like a job for the Repeater control. So I created the markup for the control and included a separator template, like this:

<asp:Repeater runat="server" ID="Repeater1" DataSourceID="LinqDataSource3"  >
<ItemTemplate>
<asp:Label runat="server" ID="labelCategory" Text='<%# Eval("Category") %>'>
</asp:Label>
</ItemTemplate>
<SeparatorTemplate>, </SeparatorTemplate>
</asp:Repeater>

The result was this:

a , b , c, d

One thing was right (no trailing comma). But there was that silly space between the data item and the delimiter.

I spent as much as a minute looking to see if there was an easy fix for this. Failing in this effort, I invented a solution that seems ... well ... kinda complex, considering. So this is where the Internet tells me that a) I'm using the wrong control and/or b) alls you have to do is set a property, duh.

In the meantime, tho, what I ended up doing was this: I handled the Repeater control's PreRender event, which is well after data binding and about the last time you can go in and mess about with the markup that the control will render. In that event, I walked the contents of the Repeater control to, in effect, trim spaces.

But it wasn't quite as simple as I thought. Instead of being able to grub around directly -- in a simple string that represented the markup being rendered, say -- I was obliged to walk the control tree that was inside the Items collection exposed by the control. And even then, I did not get access to the actual delimiters, only to the data items. (This would be another good place for someone to tell me how I managed to overlook the easy way.)

The, dunno, peculiarity of the way that the Repeater renders is that the controls being rendered for each data item go something like this:

[LiteralControl][Bound control][LiteralControl]

IOW, the Repeater control brackets the data-bound control (in the example above, the Label control) with a LiteralControl instance on each side that pads the data with a space. Or that's what I was seeing, anyway. I'm not so clear on why it does this, but poking around inside the Items collection for each data element seemed to show this. (Is this the design? How come?)

What I ended up doing, then, was walking through the Items collection to get each item's control collection. Then I walked the control collection, and whenver I found a LiteralControl, I set its text to an empty string. If I found a Label control or Hyperlink control, I did a trim on it. Here's the code:

Public Sub RepeaterTrimItems(ByVal source As Object, ByVal e As EventArgs)
Dim r As Repeater = CType(source, Repeater)
For itemCtr As Integer = 0 To r.Items.Count - 1
For controlCtr As Integer = 0 To r.Items(itemCtr).Controls.Count - 1
Dim controlObj As Object = r.Items(itemCtr).Controls(controlCtr)
Dim controlType As Type = controlObj.GetType()
Select Case controlType.ToString().ToUpper()
Case "SYSTEM.WEB.UI.LITERALCONTROL"
Dim lit As LiteralControl = CType(controlObj, LiteralControl)
lit.Text = lit.Text.Trim()
If lit.Text = " " Then
lit.Text = ""
End If
Case "SYSTEM.WEB.UI.WEBCONTROLS.LABEL"
Dim lab As Label = CType(controlObj, Label)
lab.Text = lab.Text.Trim()
Case "SYSTEM.WEB.UI.WEBCONTROLS.HYPERLINK"
Dim hlink As HyperLink = CType(controlObj, HyperLink)
hlink.Text = hlink.Text.Trim()
End Select
Next
Next
End Sub

There are a number of ways in which this is messy. It's hard-coded to work for a Repeater control, for one. Then in order to be able to set the Text property of any given control it encounters, it has to cast the objects in the Controls collection to an appropriate type. To do that, I have to get the type (GetType), and then I have a messy Select block that is (again) hard-coded to look for certain control types only. (This feels like something that could be done a lot more elegantly.) On the plus side, it works. To get it hooked up, all I do is this, on any Repeater control:

<asp:Repeater runat="server" ID="Repeater1" 
DataSourceID="LinqDataSource3"
OnPreRender="RepeaterTrimItems" >
<ItemTemplate>
<asp:Label runat="server" ID="labelCategory"
Text='<%# Eval("Category") %>'>
</asp:Label>
</ItemTemplate>
<SeparatorTemplate>, </SeparatorTemplate>
</asp:Repeater>

Having done all this (once you get started, you sort of get caught up in the challenge), I took a step back and thought "But surely this isn't necessary for the slick new ListView control." But as far as I can tell, it's the same. I have a function that does virtually the same thing for the ListView control, the only difference being that I use an ItemSeparatorTemplate instead:

<asp:ListView ID="ListView2" runat="server" 
DataSourceID="LinqDataSource3"
OnPreRender="TrimListView">
<ItemTemplate>
<asp:Label runat="server"
ID="labelCategory"
Text='<%# Eval("Category") %>'>
</asp:Label>
</ItemTemplate>
<ItemSeparatorTemplate>,</ItemSeparatorTemplate>

<LayoutTemplate>
<div ID="itemPlaceholderContainer" runat="server" style="">
<span runat="server" id="itemPlaceholder" />
</div>
</LayoutTemplate>
</asp:ListView>

Again, I'd be delighted to hear about how this is supposed to be done for real. In the meantime, tho, I have my comma-separated list.

[categories]


   |  New template for ASP.NET Web site projects

posted at 05:21 PM | | |

Visual Web Developer has long had a blank-sheet-of-paper issue when you create a new Web site project or Web application project in Visual Studio. As in, you create the project and then you, developer person, get to start adding your own layout (master pages, css), content, and optionally, authentication. Among other things.

In the 2.0 release, we had what were referred to as Starter Kits, which were prebuilt apps for what were perceived to be common tasks -- "personal Web site" (which included a photo album -- this was before Flickr), time tracker, club site, stuff like that. But Starter Kits were, at best, a kind of add-on, and of course assumed that your goal was one of the types of Web sites for which a Starter Kit was available.

For ASP.NET 4, they've decided that pretty much all apps needed a certain core set of functionality. So for ASP.NET 4, when you create a Web project, you get certain functionality out of the box. The exception is if you explicitly choose to create an empty Web site (thusly named), which is about as empty as you can get. (You get a skeleton Web.config file and that's it.)


What you get
Here's what Visual Studio 2010 builds for you when you create a new Web site/application project:
  • Web site folder structure.
  • A master page.
  • A Menu control (tabs) on master page that link to individual content pages.
  • A CSS file (Styles folder).
  • 2 free-form content pages (Default, About).
  • jQuery (Scripts folder).
  • Routing (which is basically just enabled by default).
  • A Web.config file.
  • A Global.asax file.
  • forms authentication, which includes:

    • A Login link on the master page
    • A LoginView control on master page (shows “Hello, <you>” when you’re logged in)
    • An Account folder that includes the following pages:
      • Registration page (content page + CreateUserWizard control)
      • Login page
      • Change-password page
      • Change-password success page






What you don’t get
Certain functionality was left out by design:
  • Roles. This is explicitly disabled in the Web.config file.
  • For forms authentication:
    • A link to the change-password page.
    • Reset password capability. (Because we don’t know what settings you might end up with for the membership provider, we don’t know whether we can (e.g.) send you your password.)
  • SMTP configuration. You would need this to support change-password functionality.

What you would typically do
The preceding is what's built (or not built) for you. You can actually press CTRL+F5 and see pages with content and some measure of design appear immediately after you create the site, which is quite a step up from the old days, where you'd just see a blank Default.aspx page.




If you want to restrict content to "members", you can do that by creating a folder, adding content, and then creating an authorization rule (either manually or using the Web Site Administration Tool) for that content. Note that you can do this all using declarative syntax; no code required for these various tasks.

What you'd typically do is along the lines of the following:
  • Add content pages.
  • Add menu items (tabs) to the master page for any new content you create.
  • (Optional) Tweak the layout of the master page.
  • (Optional) Tweak the CSS file.
  • (Optional) Define routes if you want to use routing.
  • For forms authentication:
    • Add a link somewhere to the ChangePassword.aspx page. (A good place might be on the Login page.)
    • Create a folder for restricted content.
    • Add content pages to the restricted folder.
    • Configure authorization for the restricted content. Simplest case: deny access to anonymous users.
    • (Optional) Configure the membership provider to specify how passwords are stored. You can do this using the Web Site Administration Tool.
    • (Optional) Create a way for users to recover passwords. (Depends on how password encryption is configured, and this might require SMTP configuration.)
    • (Optional) Configure SMTP, if you want to support recover-password scenarios.
  • For roles/authorization (all optional):
    • Enable roles.
    • Create roles.
    • (Manually) add users to roles. The default registration page does not a way to specify roles for users added at run time.
    • Configure restricted content to allow access by role.
Notes
On the master page, the link to the login page is a hyperlink, not a LoginStatus control. This was a deliberate decision so that pages that are rendered for anonymous users are lightweight – no view-state goo, no postback-link goo, etc. If you run the default page and look at the source, it’s very clean HTML.

The default page in the template contains this link: “You can also find documentation on ASP.NET at MSDN.” This links (will link) to some documentation on how to proceed from where you are.

By default, there is no link to the change-password page. Not all site necessarily want or need this functionality, and it's easy enough to change.

The login controls in the Account folder are all fully templated. (Templates are optional for these controls.) This makes it easier to tweak the layout and CSS for those controls.


The membership database and deployment
There are a couple of issues with the membership database. First, if SQL Server Express is installed, the database is created automatically in App_Data by the membership provider the first time a user is registered. (Some consider it a bad practice to allow the database to be autocreated like this.) If you’re using the Visual Studio Development Server (a.k.a. Cassini) -- that is, you have created a file-system project -- this all works great. However, if you are using a) an IIS project and b) IIS 7 or above, the app pool uses an identity that does not have permission to write to the App_Data folder. There’s a KnowledgeBase article that describes how to fix this. If you don't, you see an error message when ASP.NET tries to write to the membership database. (The error does, however, link to the article, nice.)

A second issue is deployment. In general, you don’t want to deploy an .mdf file in the App_Data folder; most hosters won’t accept this. Instead, they give you a connection string to your piece of their SQL Server. Therefore, if you have an ASPNETDB.MDF file, during deployment you either have to migrate your local database or (probably more common) re-create it. For novice users, deploying the database isn’t necessarily a trivial task, so it's either re-create, as noted, or some drill-down to figure out how to do this.


In conclusion ...
This is just a quick summary of what's going on with the new template. Interestingly, for those of us on the ASP.NET documentation team, the template means that we need to go revisit some of our docs and tweak them. For example, a lot of our walkthroughs (tutorials) were written with the assumption that you'd have to create these pages -- master page, CSS, login -- by hand as part of the tutorial. Not any more! Plus of course we need some documentation that guides users toward what to do next after they've created a Web site. But we can't really complain, since the change overall should make it easier for users (novices and experienced users, we hope) to get going with new Web sites.

[categories]


   |  ASP.NET page life cycle

posted at 09:51 AM | | |

Just a quick note to draw your attention to an updated ASP.NET page life-cycle diagram that my colleague Tom has done for the docs:

ASP.NET Page Life Cycle Diagram

Here's a little peek (I don't want to steal his thunder, so I won't show the whole thing):


[categories]


   |  Documentation survey!

posted at 02:35 PM | | |

Do you use our documentation? (Golly, hope so. :-) ) Give us some feedback -- take the survey that's posted here:

https://www.surveymonkey.com/s.aspx?sm=qQnlYIN2D5gQH7UhLrQyuA_3d_3d

This asks some basic information, like where you get your technical information and how you go about finding it, as well as how best to get your feedback, what type of development you do, etc.



I can assure you that we look at this stuff intently, we really do. I encourage you to go through the survey. It's only 11 questions, and it will help us out.

Thanks!

[categories] , ,


   |  New location (and look) for ASP.NET documentation

posted at 10:41 AM | | |

ASP.NET documentation actually has a couple of homes. There's the grab-bag of articles, tutorials, and videos about ASP.NET that's posted on the http://asp.net site. And the official documentation -- the stuff I work on -- lives on MSDN, the gigantic library of Microsoft information.

We released Beta 2 of the .NET Framework 4 and Visual Studio 2010 today. As part of the docs push, we managed a change that we've actually been wanting to make for a long time. Since approximately forever, our stuff has been part of the overall Visual Studio documentation, and it's taken some digging to find it:


Whereas all this time we've had this other node in MSDN that seemed like it would make a good home for our docs. And as of today, that's where you'll find our stuff:


The new organization reflects a couple of things. One, obviously, is that if you're scanning the MSDN table of contents (TOC) looking for ASP.NET stuff, a pretty likely place to look is in a node that's about Web development. We wanted to reduce the clicking required to get to the doc, of course. Another change is that because the docs are not tied specifically to versions of Visual Studio, you can see that we can keep ASP.NET 4 and ASP.NET 3.5 documentation close to each other in the TOC.[1]

Notice that we also have the MVC docs nearby. We debated how best to organize the MVC docs w/r/t the main ASP.NET docs. The MVC development team understandably does not want to suggest that there's this thing called ASP.NET, see, and then there's this other thing called MVC. But it's a logistical problem for us, because the MVC team versions their stuff more frequently (more agile-y) than the .NET+VS releases go out. Plus the versions don't necessarily align -- you can use MVC 2.0 on ASP.NET 3.5. In the end, we went with having the MVC docs close to, but not underneath, ASP.NET docs.

Anyway, as part of the B2 release, the folks at MSDN debuted an overhaul of the MSDN site. It's, like, prettier. :-) And it has been reorganized. And -- this is the part I think is way cool -- there are now two alternative views (three total, eh?).


There's "Classic," which is the MSDN we all know (but prettier); there's "ScriptFree" (known as "loband" during its testing phase); and there's now "Lightweight Beta." ScriptFree is intended to be very lo-band indeed. It's amazingly fast for those of us used to MSDN, but I often find that the keyhole TOC a little too sparse. I'm really pleased with Lightweight view, which is fast but retains the structural elements that I've come to rely on. I even like the page design better than in Classic view.


Incidentally, if you go to ScriptFree view, the view-switch UI changes (no script, right?). It's up at the top:


I won't blather more about the MSDN redesign right this second, coz lots of other people have had lots to say about it (e.g. new design, loband). However, there are a couple more things about Lightweight view that I really like that I'll note later.

Let us know what you think, good or bad, about the new location of the docs, about the way we organize the TOC withal, and of course about MSDN!

And speaking of MSDN, maybe I should go do some work now. :-)


[1] For complicated technical reasons, it's essentially not possible for us to be able to just stack up all versions of ASP.NET docs, from 1.0 through 4.

[categories] ,


   |  Foiled attack

posted at 02:07 PM | | |

Earlier today, someone left the following "comment" on an entry in the blog:

<% foreach (var x in ConfigurationManager.ConnectionStrings){%><%= x.ToString() + "<br />" %><% } %>

This is an attempt, obviously, to get connection information about any and all databases that the blog has access to.

In this particular case, the attack was not successful because I encode stuff in comments, so it was just passed through as text. I sure hope that I've anticipated other, relatively straightforward attacks of a similar nature. But as we know, hackers are wily. And I am not particularly so, alas.

It goes to show that no matter how trivial your site, someone is interested in hacking it. Security: It's not just for commercial web sites.

[categories] ,


   |  If you can't say something nice ...

posted at 11:18 AM | | [4] |

At work, we write documentation for programmers, so our docs include many code examples[1]. We should comment our code, right? Of course. However, a discussion broke out in our ranks yesterday about the whole idea of commenting the example code. The discussion arose out of the complaint that a lot of comments in a lot of code (not just ours) are actually lame. This was an observation made in a recent blog entry, which used the following as an example:



In the wake of this, a semi-unserious proposal was made that because most comments are dumb, we should just strip all comments from the example code. Because code examples are not translated, we have to explain the code in the text of a topic anyway.

Hmmm. This type of proposal is useful for goading me into thinking through our policy. Herewith my thots:
  • Having decent comments in a snippet is useful for the person who copies and pastes an example into their application, even if the code is explained in the topic.

  • As with member descriptions, descriptions in orientation topics, UI reference topics, and other such, it takes time and thought to create a comment that is actually useful to the reader. All of these types of text share the characteristic that they are often written as an afterthought, in a hurry, only to fulfill a general requirement, or while the writer's attention is focused elsewhere.

  • Comments might could be written by bearing in mind the Alzheimer's Law of Programming: Looking at code you wrote more than two weeks ago is like looking at code you are seeing for the first time.

  • James Edwards once suggested "comment-driven development". Bet you'd get better comments that way, eh?

  • Lame comments are partly the result of comments being unedited. Opines the editor.
This business also provides what I think is a good response when I hear anyone suggest that a good way to document APIs is "just have the developers comment their code." Sounds good in theory. But see the preceding.

[1] A topic of additional debate is whether we include enough code examples. Consensus: no.

[categories] ,


   |  Why not link to Wikipedia?

posted at 10:07 PM | | [2] |

An issue that has come up a number of times at work is the question of linking to articles in Wikipedia. It's not terribly unusual for us to link from the documentation set to non-Microsoft resources. A common example in my world is linking to the W3C site. For example, in the topic (article) ASP.NET and XHTML, we discuss how we implement (or don't) XHTML standards, but we refer you to the W3C site for actual standards.

Other examples where we've linked to external sites:
  • The Section 508 site for information about accessibility.
  • The IANA site for a reference of MIME types.
  • The Mozilla developer site for information about the document object model (DOM) supported in the Gecko browser rendering engine.
  • The Unicode site for (duh) information about Unicode.
There are more, but you get the idea. The thought here is that these sites provide information that is not specific to our product but that is useful to our audience. It would be silly for us to copy this info or (god forbid) rewrite it so it could be part of our documentation site.

You will probably note that sites have certain features in common. They are:
  • Authoritative. Many of our links are to the sites of standards bodies.
  • Commercially neutral, at least for the purposes for which we are linking. For example, the Mozilla site could be thought of as a competitor to, say, Internet Explorer, but from our perspective (server-based Web coding), it's just another client.
  • Stable. None of these sites are going away anytime soon, and the content that we link to essentially won't change.
Which brings us to Wikipedia. The fact is, there is a ton of good information on Wikipedia. The ever-expanding nature of the site means that it often has in-depth articles on topics that are of interest to our audience. Here are a few examples of articles that were recently proposed as links:We didn't link to these articles. In fact, we currently have a blanket prohibition (at least, within our group) on linking to Wikipedia. This can be hard for the writers to accept. And you can see why -- rather than us having to describe some general, non-product-specific technology, why not just link to it? And the articles that are listed above are quite good, certainly better than we are apt to produce without considerable trouble on our part. I mean, why spend days and days writing up a description of cross-site script exploits when we can link to a fine article right there?



It's tempting. But if you review the characteristics of the sites that we do link to, Wikipedia comes up short, to wit:

Authority. Wikipedia articles are anonymous. There is an inherent conflict between the wisdom-of-crowds nature of wikis and the authority of a single, recognizable author. Jeff Atwood explored this issue recently. More simply put, a Wikipedia article cannnot answer the question "Oh, yeah? Sez who?"

Moreover, as has been shown repeatedly, not everything in Wikipedia is, in fact, correct. Anyone can change anything, any time, and there's no guarantee that any given change results in accuracy. John McIntyre, who has a dim view of Wikipedia indeed, recounts a recent scandal in which should-know-better journalists picked up a faked citation that was planted on Wikipedia with malice aforethought.

Neutrality. Most information on Wikipedia does not seem particularly controversial, but the site has problems with partisan battles. Politics is an obvious area for this, but there are plenty of people who have heated opinions about, oh, Microsoft. Imagine for a moment that article on cross-site script exploits. A reader who has a particular issue with Microsoft might amend the article to note that Microsoft products are particularly susceptible to this type of exploit. Whether or not this is true, this type of debate is not something we want to be linking to.

Stability. Wikipedia articles change constantly. The paragraph that you have in mind when you link to an article today might not even be there a week from now. Of course, that's not very likely with the types of articles that I listed above. But the point is, we don't know and certainly cannot guarantee it.

Our attitude about linking to Wikipedia might change over time. I imagine that it will change pretty much in step with what the attitude at large is about the reliability of Wikipedia articles. If college professors start letting students cite Wikipedia for research bibliographies, then we'll probably feel comfortable linking to it. And maybe before then, who knows. But as of today, no.

[categories] , ,
[tags] wikipedia, documentation