Gunnar Peipman's ASP.NET blog

ASP.NET, C#, SharePoint, SQL Server and general software development topics.

Sponsors

News

 
 
 
DZone MVB

Links

Social

July 2010 - Posts

ASP.NET MVC 3: Using multiple view engines in same project

One of nice features of ASP.NET MVC 3 is support for multiple view engines. There will be two out-of-box view engines: one for classic ASPX-based views and one for Razor-based views. In this posting I will show you this new feature and demonstrate how to use different view engine in same project.

Currently, I think, there is no real application to tricks in this posting but you never know. When ASP.NET MVC has been available for longer period of time I think there will be need to migrate two projects that use different view engines.

Support for multiple view engines

ASP.NET MVC 3: Select view engineHere you can see screenshot of Add View dialog where view engine dropdown is opened.

Currently there are two choices:

  • ASPX – classic ASP.NET MVC views,
  • Razor – new Razor based views.

If you select another view engine then file and master page names are changed appropriately.

In the future there will be maybe third option for Visual Basic.NET based Razor views (CSHTML means C# based views).

Using multiple view engines in same project

Now let’s make little experiment. Here is my step by step guide.

  1. Create ASP.NET MVC 3 ASPX project.
  2. Create ASP.NET MVC 3 Razor project.
  3. Copy Site.master and LogOnUserControl.ascx from ASPX project shared views folder to Razor project shared views folder.
  4. Copy About.aspx from Home views folder of ASPX project to Home views folder of Razor project.
  5. Rename About.aspx to AboutAspx.aspx.
  6. Open _Layout.cshtml and add the following line to the end of menu:
    <li>@Html.ActionLink("About ASPX", "AboutAspx", "Home")</li>
  7. Open Site.master and add the following line to the end of menu: 

    <li><%: Html.ActionLink("About ASPX", "AboutAspx", "Home")%></li>  
  8. Save both master pages.
  9. Open AboutAspx.aspx and change the text in body so you can recognize that ASPX-based view is shown.
  10. Save AboutAspx.aspx.

Now you can run your project and select About and About ASPX from main menu. If you select About you will see Razor-based view and if you select About Aspx you will see ASPX-based view.

Conclusion

Using views based on different view engines allows us to migrate ASP.NET MVC projects that are written using different view engines. As human mind is unlimited I have to suggest that it is not good idea to use different view engines in same project. Try to avoid pointless mess if you can and select view engine by trusting your common sense.

Posted: Jul 29 2010, 10:40 AM by DigiMortal | with 9 comment(s)
Filed under: ,
ASP.NET MVC 3: Creating HttpStatusCodeResult with view based body

My last posts described new action results in ASP.NET MVC 3 – HttpNotFoundResult and HttpStatusCodeResult. Unfortunately these result have no body to send to client but there are times we need it to inform our visitor about problems the way that we don’t go out of information context where visitor is. In this example I will show you how to write your own HttpStatusCodeResult that has also body.

We cannot use HttpStatusCodeResult because it doesn’t contain information about current view and there is no way how to attach views to this action result. Instead, I wrote my own implementation of HttpStatusCodeResult that extends ViewResult class and has therefore support for views. This is important thing because body of response is defined same way as other views in ASP.NET MVC framework.

Okay, here is my HttpStatusCodeWithBodyResult class in its very first form.


public class HttpStatusCodeWithBodyResult: ViewResult
{
    private int _statusCode;
    private string _description;

    public HttpStatusCodeWithBodyResult(int statusCode,
string description = null)
        : this(null, statusCode, description)
    {
           
    }
    public HttpStatusCodeWithBodyResult(string viewName, int statusCode,
string description = null)
    {
        _statusCode = statusCode;
        _description = description;
        ViewName = viewName;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var httpContext = context.HttpContext;
        var response = httpContext.Response;

        response.StatusCode = _statusCode;
        response.StatusDescription = _description;
           
        base.ExecuteResult(context);
    }
}

And here is how you can use it in you controller methods. The examples are given for 404 – Not Found and 410 – Gone responses.


public ActionResult NotFound()
{
    var msg = "I cannot find this resource!";

    // there must be view called NotFound.aspx or NotFound.cshtml
    var result = new HttpStatusCodeResultWithBody("NotFound", 404, msg);
    return result;
}

public ActionResult GoneForever()
{
    var msg = "This resource is dead and buried!";

    // there must be view called GoneForever.aspx or GoneForever.cshtml
    var result = new HttpStatusCodeResultWithBody(410, msg);
    return result;
}

You can read more about HttpNotFoundResult class from my posting ASP.NET MVC 3: Using HttpNotFoundResult action result and about HttpStatusCodeResult from my posting ASP.NET MVC 3: Using HttpStatusCodeResult.

Conclusion

In this posting I showed you how to create action result that works like HttpSthatusCodeResult but supports also body for result returned to browser. This way we can tell to both technical clients (browsers, search engine spiders etc) and visitors that there was problem and what one or another of them has to do now. Consider it also as good SEO and usability practices.

Posted: Jul 28 2010, 02:11 PM by DigiMortal | with 11 comment(s)
Filed under: ,
ASP.NET MVC 3: Using HttpStatusCodeResult

ASP.NET MVC 3 also introduces new action result HttpStatusCodeResult. This action result provides you way how to specify HTTP status code and status description in your controllers. In this posting I will show you how to use HttpStatusCodeResult in your real-world applications providing meaningful status code for products that were online once but are now gone and we don’t expect them to be back in future.

What is HTTP status code 410 – Gone?

In this example I will use HTTP code that you don’t hear often about. It is 410 – Gone. You may argue that stauts code 404 – Not Found is enough but there is one little gotcha – 410 is considered as permanent response. Cite from RFC 2616 Hypertext Transfer Protocol – HTTP/1.1 chapter 10. Status Code Definitions:

“The requested resource is no longer available at the server and no forwarding address is known. This condition is expected to be considered permanent. Clients with link editing capabilities SHOULD delete references to the Request-URI after user approval. If the server does not know, or has no facility to determine, whether or not the condition is permanent, the status code 404 (Not Found) SHOULD be used instead. This response is cacheable unless indicated otherwise.

The 410 response is primarily intended to assist the task of web maintenance by notifying the recipient that the resource is intentionally unavailable and that the server owners desire that remote links to that resource be removed. Such an event is common for limited-time, promotional services and for resources belonging to individuals no longer working at the server's site. It is not necessary to mark all permanently unavailable resources as "gone" or to keep the mark for any length of time -- that is left to the discretion of the server owner.”

In online e-commerce systems, by example, we have all products we have sold. So we can determine easily if there is product that was available once but it is sure it never comes back to our store (okay, wise men say: never say never).

Example

Let’s suppose we have online e-commerce system and we have detail pages for products. These pages are dynamic and we can check from database if product is available. We have some products we don’t plan to sell anymore and we can determine if request was made for some of those products.

This is fictional code and I added here some comments too so you have better understanding what is going on.


public ActionResult Details(int productId)
{
    // ask products from context that was injected by controller factory
    var product = (from p in _context.Products
                    where p.Id == productId
                    select p)
                    .FirstOrDefault();

    // if product is null then it has never been there - say it's not found
    if (product == null)
        return HttpNotFound();

    // product is out of sales and it never comes back - say it's gone
    if (product.SalesFinished == null)
        return new HttpStatusCodeResult(410);
           
    // product found - show details
    return View(product);
}

Now, when visitor asks product that was there once and for now it is gone forever his or her browser gets information from server that all links to this resource must be removed. This message also tells to search engine robots that given link must be removed from index and all pages having links to this page must be handled as pages with broken links.

Conclusion

Using HttpStatusCodeResult you can improve SEO of your pages and make your site more understandable to robots and other clients implemented in software. Status code 410 – Gone expects that you have some place where you can check if asked resource has been alive before or not. If your system doesn’t contain this data then you should use status code 404 – Not Found instead of 410 – Gone.

Posted: Jul 28 2010, 11:42 AM by DigiMortal | with 9 comment(s)
Filed under: , ,
Overview of my MVP year

MVP: Most Valuable ProfessionalAnother MVP year is over. Today I sent my activity report to my MVP lead and in October it should be clear if my MVP will be continued or not. I hope it will continued, of course. Now it is time to make one little overview about my MVP year that just ended in terms of public activities. It was year full of action and interesting people – something that is hard to forget. You should be proud too – without you there is no MVP program, this blog and many other things. So, feel yourselves as part of action!

MVP year in numbers

My MVP year in numbers was simple (but it was hard in actions):

276 postings to different forums,
255 blog postings to different blogs,
18 events visited (at 8 events I was speaker)
6 MCP/MCST exams passed
8 software development books read

Besides that active building of local community and development of local community portal in co-operation with Microsoft. Also I tested some new products and gave my feedback to Microsoft about my ideas and findings.

What was special for me?

For me my basic output to communities are this blog and events where I speaks and meet with people who are asking my advice. This year as the first one where I was speaker in events and I think I studies a lot of new things and I will be way better on that than before. I don’t consider myself as star ready for big stages but I think I still made a very good progress.

I prepared simple page here about Code Contracts. You can find there list of my postings about this topic and also PowerPoint presentation ready for session and Visual Studio 2010 solution with code examples and presentation guides. This is example of what kind of materials I prepare for local community events. After my sessions I usually make all these materials available to public.

This blog

The other special thing for me is this blog. We – yes, we, me and you – my readers – have made huge step during this year. The following Google Analytics screenshot shows how this hot summer is going in terms of visits. Twice better than year ago, guys! :)

My ASP.NET blog @ July 2010

Thanks guys!

I want to say thank you for everybody who is reading this blog and also to all guys who made this MVP year special for me otherwise. I will continue my public work as before and I hope I can be way better than on this year. Summer is over soon and it is time again to start with community events, certification and all other activities that help me to spread the word and help communities worldwide. Thanks again guys, you rock hard! :)

ASP.NET MVC 3: New ViewModel is dynamic ViewData

ASP.NET MVC 3 introduces new ViewModel property of Controller that you can use to assign different properties to the model of your view. ViewModel is dynamic by type. In this posting I will show you how to use ViewModel property in your ASP.NET MVC applications.

Suppose you have controller for products that has method Details() to show details of product requested by visitor. We want to use dynamic ViewModel to get data to details view.

ASP.NET MVC 3: ViewModel property

So, here is our controller that uses dynamic ViewModel.


public ActionResult Details(int productId)
{
    var product = _repository.GetProductById(productId);

    if (Request.IsAuthenticated)
        ViewModel.VisitorName = HttpContext.User.Identity.Name;
    else
        ViewModel.VisitorName = "visitor";

    ViewModel.ProductName = product.Name;
    ViewModel.ProductUnitPrice = product.UnitPrice;
    ViewModel.ProductDescription = product.Description;

    // ...

    return View();
}

And here is the fragment of view that shows product details.


<h2><%= ViewModel.ProductName  %> (<%= ViewModel.ProductPrice  %> EUR)</h2>
<p>
    <%= ViewModel.ProductDescription  %>
</p>

User can see besides other stuff the fragment like this.

ASP.NET MVC 3: Example output of view

Let’s try now what happens when we use good old ViewData instead of ViewModel.


public ActionResult Details(int productId)
{
    var product = _repository.GetProductById(productId);

    if (Request.IsAuthenticated)
        ViewData["VisitorName"] = HttpContext.User.Identity.Name;
    else
        ViewData["VisitorName"] = "visitor";

    ViewData["ProductName"] = product.Name;
    ViewData["ProductUnitPrice"] = product.UnitPrice;
    ViewData["ProductDescription"] = product.Description;

    // ...

    return View();
}

Don’t make any other changes to code. Compile your project and refresh product page. Guess what … the result is same as before! Why should ViewData and ViewModel be synchronized? Think about controller unit test and it should be clear.

Conclusion

ViewModel property of Controller is great addition to ASP.NET MVC and it makes our code and views more readable. Instead of using ViewData or strongly typed views we can use ViewModel to form our model objects dynamically and give them to views.

Posted: Jul 27 2010, 09:26 PM by DigiMortal | with 19 comment(s)
Filed under: ,
ASP.NET MVC 3: Using HttpNotFoundResult action result

ASP.NET MVC 3 introduces some new action results like HttpNotFoundResult that you can use to let browser know that resource was not found. In this posting I will show you how to use HttpNotFoundResult in real-world applications.

HttpNotFoundResult class and HttpNotFound() method

Let’s start with ASP.NET MVC 3 default application and let’s modify Index() method of Home controller so it returns HttpNotFoundResults for some path. Here is my code:


public ActionResult NotFound()
{
    var result = new HttpNotFoundResult();
    return result;
}

Now let’s run our application and point browser to address http://myserver/Home/NotFound. As you can expect then the result is empty result with HTTP status code 404.

There is also shortcut method in Controller class that does exactly the same work. This protected method is called HttpNoFound() and you can use it exactly same way as you used HttpNotFoundResult before.


public ActionResult NotFound()
{
    return HttpNotFound();
}

If you like to provide your own status message with error 404 then you can do it in constructor of HttpNotFoundResult. Also you can provide status description parameter for HttpNotFound method as shown in following example.


public ActionResult NotFound()
{
    return HttpNotFound("I cannot find this thing!");           
}

Page not found

I promised to give you some real-world example too. Here is example about controller method that is invoked when visitor requests some page (/Page/something-very-interesting). I hope comments in code are enough to make this method easy to understand.


public ActionResult Page(string urlName)
{
    // ask pages from context that was injected by controller factory
    var page = (from p in _context.Pages
                where p.UrlName == urlName
                select p)
                .FirstOrDefault();

    // if page is null then it has never been there - say it's not found
    if (page == null)
        return HttpNotFound();

    // page found - show details
    return View(page);
}

You can use similar code also for other types of systems like e-commerce, blogs, forums etc.

Conclusion

HttpNotFoundResult class and HttpNotFound() method are easy ways how to let server and browser know that resource asked by visitor is not found. It is also important information for search engine spiders because they are able to correct their indexes based on that information.

Posted: Jul 27 2010, 09:16 PM by DigiMortal | with 10 comment(s)
Filed under: ,
ASP.NET MVC 3 Preview 1 is released!

ASP.NET MVC 3 Preview 1 is launced and available for download. There are many cool features and I strongly suggest you to try the new version out. In this posting I will give you quick overview about what’s new in ASP.NET MVC 3.

New features:

  • add View dialog lets you select view engine,
  • ASP.NET MVC 3 has new view engine called Razor,
  • support for global action filters,
  • controllers and views support now new property called ViewModel that is dynamic,
  • new action result types,
  • some AJAX and JavaScript improvements,
  • model validation improvements,
  • dependency injection improvements.

You can read more about new stuff from ScottGu blog posting Introducing ASP.NET MVC 3 (Preview 1).

Posted: Jul 27 2010, 09:01 PM by DigiMortal | with 8 comment(s)
Filed under: ,
How to make AJAX-requests to ASP.NET MVC application using jQuery

I decided to write over long time one posting that is directed to beginners who start with jQuery and AJAX. One of the first things to study is how to make requests to server and how to retrieve objects. In this posting I will show you how to use jQuery to retrieve JSON data from ASP.NET MVC application and how to debug it.

Making AJAX-requests to server

This was one of first things I needed when I started with jQuery. If you are working on ASP.NET MVC there are some tricks but I tell about these later. Now let’s see how to make AJAX-request to server.


var url = '/contacts/ListPartiesByNameStart?nameStart=A';
$.ajax({ url: url, success: DataRetrieved, type: 'POST', dataType: 'json' });

Should be simple but let me still explain a little bit.

  • url – this is the URL where request is sent. In my case there is controller called contacts and it has action calles ListPartiesByNameStart(). This action method takes  parameter nameStart (first letter of person or company).
  • success – this is the JavaScript function that handles retrieved data. You can write there also anonymous function but I suggest you to use functions with names because otherwise your code may get messy when functions grow.
  • type – this is the type of request. It is either GET or POST. I suggest you to use POST because GET requests in JSON format are forbidden by ASP.NET MVC by default (I will show you later how to turn on GET requests to JSON returning actions).
  • dataType – this is the data format that is expected to be returned by server. If you don’t assign it to value then returned result is handled as string. If you set it to json then jQuery constructs you JavaScript object tree that corresponds to JSON retrieved from server.

If you are using POST requests then I suggest you to use parameter called data that is serialized as POST body. You can find more information about parameters from jQuery ajax() method documentation. And here you can find jQuery API documentation.

Here is the example of DataRetrieved function where I expected that server returned person object in JSON format.


function DataRetrieved(data) {
// Do something with data
alert(data.FirstName + ' ' + data.LastName);
}

The data that is given to this method is exactly the same thing you send from server. Now let’s see how to make your web application to output JSON.

Returning JSON from ASP.NET MVC actions

ASP.NET MVC is able to create JSON results for yourself automatically. You don’t have to write your own object transformers and anything else. Just use what ASP.NET MVC offers. Here is the example action that returns some data in JSON format.


public JsonResult ListCompanyNames(int id)
{
    var party = _partyRepository.GetCompanyById(id);
    var names = from n in party.Names
                select new 
                {
                    nameId = n.Id.ToString(),
                    name = n.Name.ToString(),
                    validTo = n.ValidTo.ToShortDateString(),
                    userdata = ""
                };
    var rows = names.ToArray();
    var data = new JqGridData
                {
                    total = rows.Count(),
                    page = 1,
                    records = rows.Count(),
                    rows = rows
                };
    return Json(data,JsonRequestBehavior.AllowGet);
}

I ask some data and form objects that I want to send as response to browser. All I have to do is to use Json() method of controller. In this case I allow also GET requests. If I omit second parameter then GET requests to this action are not allowed

How to debug

As a last thing let’s see how to debug AJAX-requests. One option is to use AllowGet as in previous code sample but I don’t suggest it. It makes direct data requests to JSON data too easy for users with browsers. Although you win practically nothing in security you still make life harder for not so educated bad guys.

My favorite choice is Firebug extension for Firefox. Firebug monitors requests and responses made by browser and gives you very good overview about data that is moving between browser and server. Firebug is also able to illustrate JSON data like shown on following screenshot fragment.

Firebug showing JSON objects retrieved from web server

Here you can see array of JSON objects that have Id and DisplayName properties.

Conclusion

Writing AJAX-based applications using ASP.NET MVC framework and jQuery is easy. You have two powerful tools that let you do more spending less time. ASP.NET MVC is very lightweight framework but in the same time extremely effective tool to build web applications. Same goes for jQuery that is client-side technology. Mixing two of them together it is fun to be web developer.

ASP.NET MVC: Using dynamic type to test controller actions returning JsonResult

I wrote unit tests for my ASP.NET MVC application that uses some jQuery AJAX-components. These components load data from server in JSON format. I needed to write tests for these methods to make sure that correct data is returned to client. In this posting I will show you how to use dynamic type to test JSON-based action results and therefore avoid creating DTO classes.

Example of controller action

To keep the code compact for reading I represent my controller action as one method without any fragmentation.


public JsonResult ListCompanyRepresentatives(int id)
{
    var party = _partyRepository.GetCompanyById(id);
    var names = from n in party.Representatives
                orderby n.ValidTo, n.RepresentativeParty.DisplayName
                select new 
                {
                    Id = n.Id.ToString(),
                    Name = n.RepresentativeParty.DisplayName,
                    Role = n.Role ?? string.Empty,
                    Context = n.Context ?? string.Empty,
                    ValidFrom = n.ValidFrom.ToShortDateString(),
                    ValidTo = n.ValidTo.ToShortDateString()
                };

    var rows = names.ToArray();
   
var data = new 
    {
        total = rows.Count(),
        page = 1,
        records = rows.Count(),
        rows = rows
    };

    return Json(data, JsonRequestBehavior.AllowGet);       
}

You see here two anonymous types. One of them is created for party representatives and the other one is data structure for JSON-based result. JSON-based result contains array of party representatives. End the end we have one anonymous type that is hosting array of another anonymous type objects. The question is how to write tests for the end result?

Problems with anonymous types

You can say that we can create one DTO class for type returned as array and the other DTO class (or maybe generic class) for JSON results. This would be easy solution but it may end up with large number of DTO classes. This is why I try to get work done with anonymous types.

Anonymous types are not very good to test because they are declared as internal. As we know types in internal scope are visible only to other classes in same assembly. Test are usually located in separate project and separate assembly and by default they don’t see those anonymous types.

There is one problem more. Take a look at the code in test that reads data from JSON result.


var result = _controller.ListCompanyNames(company.Id) as JsonResult;
var data = result.Data;

Data returns us object. To read properties we need to the type of object. The type is anonymous and we cannot cast to anonymous type. We can use reflection but for me it is not good solution because reflection may cause some overhead in performance and if we have many tests then reflection may slow down test runs.

Solution – using dynamic type

Here is the fragment of test that uses dynamics.


dynamic data = result.Data;
dynamic companyName = data.rows[0];
var name = company.Names[0];

Assert.AreEqual(name.Id.ToString(), companyName.nameId);

When we run tests we get errors that object has no property called rows. Well, that’s because anonymous types are internal. We have to make them visible to our tests library.

Open your ASP.NET MVC application project and find AssemblyInfo.cs from folder called Properties. Open AssemblyInfo.cs and add the following line to the end of this file.


[assembly: InternalsVisibleTo("MyProject.Tests.Unit")]

This line tells .NET Framework that internal types of our ASP.NET MVC project must be visible to our tests project. If you have more than one tests library for your ASP.NET MVC application you can make web application internals visible to these libraries exactly the same way. Now you can run your tests and everything should work fine.

Conclusion

Using anonymous types with JSON results may be painful. For previous versions of .NET there are some other solutions to consider: using DTO-s, string comparison or reflection to test JSON results. In .NET 4.0 we can use dynamic type and avoid possible problems related to string comparison (by example, order of properties changes) and reflection (messy code and possible performance overhead). For us dynamic was excellent solution here. This way you can test also other AJAX-based responses that use anonymous types.

Posted: Jul 24 2010, 03:26 PM by DigiMortal | with 12 comment(s) |
Filed under: , , ,
Solution Navigator: Killer replacement for Solution Explorer

Visual Studio 2010 Productivity Power Tools contains now Solution Navigator that merges many good features of Visual Studio 2010, Solution Explorer and some Power Tools features to single view. After playing shortly with Solution Navigator I found it to be very good replacement for Solution Explorer. In this posting I will show you some very cool features of Solution Navigator.

Solution Navigator: Extended Solution Explorer

Solution Navigator for Visual Studio 2010Solution Navigator looks similar to Solution Explorer and you can use it same way. If you like you can start using Solution Navigator instead of Solution Explorer because Solution Navigator has all features of Solution Explorer and it just extends it with many more cool features.

The screenshot on right shows you how Solution Navigator looks like. You can expand files to see classes and other code entities inside them and you can extend classes, their properties and methods etc.

Search

Search functionality is cool. You can search for different code units in your projects by just typing at least part of its name to search box. Solution Navigator looks for classes where code unit with given name exists and highlights part of this file. Results are shown as tree where non-matching parts of solution tree are hidden.

Filtering projects

Solution Navigator lets you easily filter projects if you have large solution opened in Visual Studio. There are quick filtering links on the upper part of Solution Navigator: All, Open, Unsaved, Edited. Clicking on some of these links you will see projects that match selected criteria. If you have some projects with opened files the clicking on Open link shows you only those projects in Solution Navigator that have at least one file opened in Visual Studio IDE.

Find out more

There are more things you can find useful in Solution Navigator like tooltips of code units, advanced navigation features (move forward and back between views), visualized relationships between classes etc. You can read more from The Visual Studio Blog posting Announcing the Solution Navigator.

More Posts Next page »