Posts Tagged ‘ asp.net MVC ’

Expressing Intent with the new IHtmlString interface

If you’re paying close attention, you might be asking yourself “Html.TextBox is supposed to return HTML that is already sanitized. Wouldn’t using this syntax with Html.TextBox cause double encoding?

ASP.NET 4 also introduces a new interface, IHtmlString along with a default implementation, HtmlString. Any method that returns a value that implements the IHtmlString interface will not get encoded by this new syntax.

In ASP.NET MVC 2, all helpers which return HTML now take advantage of this new interface which means that when you’re writing a view, you can simply use this new syntax all the time and it will just work. By adopting this habit, you’ve effectively changed the act of HTML encoding from an opt-in model to an opt-out model.

The Goals

There were four primary goals we wanted to satisfy with the new syntax.

  1. Obvious at a glance. When you look at a page or a view, it should be immediately obvious which code blocks are HTML encoded and which are not. You shouldn’t have to refer back to flags in web.config or the page directive (which could turn encoding on or off) to figure out whether the code is actually being encoded. Also, it’s not uncommon to review code changes via check-in emails which only show a DIFF. This is one reason we didn’t reuse existing syntax.

    Not only that, code review becomes a bit easier with this new syntax. For example, it would be easy to do a global search for <%= in a code base and review those lines with more scrutiny (though we hope there won’t be any to review). Also, when you receive a check-in email which shows a DIFF, you have most of the context you need to review that code.

  2. Evokes a similar meaning to <%=. We could have used something entirely new, but we didn’t have the time to drastically change the syntax. We also wanted something that had a similar feel to <%= which evokes the sense that it’s related to output. Yeah, it’s a bit touchy feely and arbitrary, but I think it helps people feel immediately familiar with the syntax.

  3. Replaces the old syntax and allows developers to show their intent. One issue with the current implementation of output code blocks is there’s no way for developers to indicate that a method is returning already sanitized HTML. Having this in place helps enable our goal of completely replacing the old syntax with this new syntax in practice.

    This also means we need to work hard to make sure all new samples, books, blog posts, etc. eventually use the new syntax when targeting ASP.NET 4.

    Hopefully, the next generation of ASP.NET developers will experience this as being the default output code block syntax and <%= will just be a bad memory for us old-timers like punch cards, manual memory allocations, and Do While Not rs.EOF.

  4. Make it easy to migrate from ASP.NET 3.5. We strongly considered just changing the existing <%= syntax to encode by default. We eventually decided against this for several reasons, some of which are listed in the above goals. Doing so would make it tricky and painful to upgrade an existing application from earlier versions of ASP.NET.

    Also, we didn’t want to impose an additional burden for those who already do practice good encoding. For those who don’t already practice good encoding, this additional burden might prevent them from porting their app and thus they wouldn’t get the benefit anyways.

To upgrade an existing ASP.NET MVC 1.0 application to version 2, perform the following steps:

1. Make a backup of the existing project.

2. Open the project file (the file with the .csproj or .vbproj file extension) and locate the ProjectTypeGuid element. In the value of that element, replace the GUID {603c0e0b-db56-11dc-be95-000d561079b0} with {F85E285D-A4E0-4152-9332-AB1D724D3325}.When you are done, the value of that element should be as follows:

<ProjectTypeGuids>{F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

3. In the Web application root folder, edit the Web.config file. Search for System.Web.Mvc, Version=1.0.0.0 and replace all instances with System.Web.Mvc, Version=2.0.0.0.

4. Repeat the previous step for the Web.config file located in the Views directory.

5. Open the project using Visual Studio and expand the References node in Solution Explorer. Delete the reference to System.Web.Mvc (which points to the version 1.0 assembly). Add a reference to System.Web.Mvc (v2.0.0.0).

6. Add the following bindingRedirect element to the Web.config file in the application root under the configuraton section:

<runtime>

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

<dependentAssembly>

<assemblyIdentity name="System.Web.Mvc"

publicKeyToken="31bf3856ad364e35"/>

<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>

</dependentAssembly>

</assemblyBinding>

</runtime>

7. Create a new ASP.NET MVC 2 application. Copy the files within the Scripts directory into the Scripts directory of the existing application.

8. Compile the application and run it. If any errors occur, refer to the Breaking Changes section of this document for possible solutions.

The primary framework goals of ASP.NET MVC are…

1)Frictionless testability – By “frictionless” I mean that when you want to test your code, the framework it was written it doesn’t cause you friction. This is very important if you want to seriously perform long-term unit testing on an application, because if developers were constantly running into points of friction when trying to test, they would eventually abandon it.

2)Tight cover over markup – ASP.NET MVC doesn’t contain any server controls or high-level abstractions that mask their underlying rendering. When you develop an ASP.NET MVC application, you have complete control over the markup. ASP.NET MVC does include some HTML helpers that “hide” away some HTML, but they are at the most basic level of rendering (i.e. just an <input> element).

3)Leverage the benefits of ASP.NET – Because ASP.NET MVC is built on top of the core ASP.NET runtime, you still have plenty of old-friends that can be used (i.e. profiles, membership, roles, caching). All of the same intrinsics you’ve always known are still valid and used heavily.

4)Conventions and guidance – ASP.NET MVC comes with a set of predefined conventions that make the use of it much easier, without the need to for tons of configuration. It also provides framework-level guidance. The idea is that ASP.NET MVC wants to try to lead developers down the pit of success.

For security reasons related to exploits or whatever that is, I need to store the files uploaded by users in a different partition. That’s OK.

But then, and here’s the problem, I need to get them on order to display them to users (this includes pictures). I tried this (it worked perfectly the time I used php), but apparently does not work with ASP.NET or maybe I am doing something wrong.

I write this code in the aspx file:

<img src="/Image/Index/filename.extension" alt="…" />

The src of this image is another action that gets the image from our secret directory in our different partition and it goes like this:

        public Image Index(string fileName)
        {
            string source = Constants.ImagesPath + fileName;
            Image img = System.Drawing.Image.FromFile(source);
            return img;
        }

I get the image, debugging confirms it! But the only thing presented is the alternative text. As I said before, I used to do something similar with php and it worked, but, of course, php also has its problems and that’s way we changed to ASP.NET.

the solution is:

1. public void Index1(String FilePath)  

2. {  

3.     byte[] FileStreamBytes = null;  

4.     FilePath = @"c:\sampleImage.png";  

5.     FileStream objFileStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read);  

6.     FileStreamBytes = new byte[objFileStream.Length];  

7.     objFileStream.Read(FileStreamBytes, 0, FileStreamBytes.Length);  

8.     objFileStream.Close();  

9.     objFileStream = null;  

0.     Response.BinaryWrite(FileStreamBytes);  

1.     Response.End();  

2. }