Solving development problems  |  About this blog

Archive for the ‘ASP.NET MVC’ tag

So, you can not delete Cookie? Huh, something about headers or headache…

We wanted to delete cookie setting its expired date property to something in the past like this:

HttpCookie cookie = new HttpCookie(this.Name);
cookie.Expires = DateTime.UtcNow.AddMonths(-1);
HttpContext.Current.Response.Cookies.Add(cookie);
But we got an error:

Server cannot modify cookies after HTTP headers have been sent.

After searching and searching if we have somewhere Response.Write in or ASP.NET MVC code we found out that we don’t have such things.
Suddenly, we found out that we played with Session object (trying to clear it) before deleting Cookie and that was it. Reordering these operations solved our problem.

Conclusion
Session object also use cookies, we forgot.

Update on this case

This “solution” didn’t helped… Everything is so simple and was done with JQuery cookie plugin. One line of code from Javascript!

Create random web hex color in C# / ASP.NET MVC

Random random = new Random();
int red = random.Next(0, 255);
int green = random.Next(0, 255);
int blue = random.Next(0, 255);
string hexColour = String.Format("#{0:X2}{1:X2}{2:X2}", red, green, blue);

Written by Avivo

April 22nd, 2011 at 11:46 pm

How to copy validation message from one element to another in ASP.NET MVC 2?

Just create an extension to ModelStateDictionary like this:
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Web.Mvc;

namespace Avivo.Web.Common
{
  public static class ModelStateDictionaryExtensions
  {
    /// <summary>
    /// Copy validation message from one field to another
    /// </summary>
    /// <param name="modelState">model state</param>
    /// <param name="source">field to copy from</param>
    /// <param name="target">field to copy to</param>
    public static void CopyMessage(this ModelStateDictionary modelState, string source,
      string target)
    {
      if (modelState.ContainsKey(source) && modelState.Errors.Count > 0)
      {
        modelState.AddModelError(target, modelState.Errors[0].ErrorMessage);
      }
    }
  }
}

Written by Avivo

April 4th, 2011 at 3:47 pm

How to show compiler errors in ASP.NET MVC Views?

Just open your csproj project file in notepad and find MvcBuildViews and set value to True.

<MvcBuildViews>true</MvcBuildViews>

Written by Avivo

February 7th, 2011 at 4:21 pm

How to create custom error 404 in ASP.NET MVC

Introduction

So, whenever an error occurs, you would like to show a custom 404 error page in ASP.NET MVC? This blog post describes how to techically handle and display error page effectively. Reader should have some basic knowledge of setting IIS and ASP .NET MVC project.

Error page is displayed when something goes wrong. Page should inform user about what happened and what he or she should do next. Page should also inform bots, crawlers, spiders not to search any relevent content in there, e.g. Google won’t display error page as search result. This is handled with HTTP status code known as 404. There are also other HTTP status codes for specific problems, e.g. for maintenance, for restricted access…

Create action and view

First, create a friendly page for user and set indicator for bots not to handle this page as obvious page. In this case “Main” controller with “Error” action. Note for IE 5,6: error page should have content larger than 512 bytes otherwise IE will display its own content.

public class MainController
{
  public ActionResult Error()
  {
    //404 - Tell search engine not to display this page on search results
    Response.StatusCode = 404;
    Response.StatusDescription = "Not Found";
    return View();
  }
}

Register route that eats anything

Open Global.asax(.cs) in the MVC project and register error page route. Rule should be designed to capture all requests that do not fit in previous route rules. Simple solution: {*anything} rule captures any path including slashes, e.g. /shop/mushrooms-123.

//Somewhere in Global.asax
public static void RegisterRoutes(RouteCollection routes)
{
  //Registered routes
  //...

  //Error route should be registered last
  routes.MapRoute
  (
    "ErrorPage",
    "{*anything}",
    new { controller = "Main", action = "Error" }
  );
}

Advantage: no redirects, requested URL string should be kept in browser’s location bar. For example, when
user requests /shop/mushrooms-123 in browser the error page content will be display but the URL will remain original.
The opposite of redirecting and displaying /error in location bar.

How to handle other errors?

Other errors in ASP .NET can be handled in Application_Error method in Global.asax.

//Somewhere in Global.asax
protected void Application_Error()
{
  //Useful for debugging to get error details
  Exception ex = Server.GetLastError();

  //Redirect to error page
  //Can be "/Main/Error" or "/error" or other route as "ErrorPage" rule eats all
  Response.Redirect(Request.ApplicationPath + "/error/500");
}

Configuration in IIS 7.5

1. Open IIS Manager. Shortcut: click Start in Windows, type “inetmgr” in search box then press Enter.
2. Click on a website on the left side.
3. Select Error Pages on the right side.
4. Configure scenarios for specific status codes, as displayed on screenshots.

Troubleshooting

Q: Browser displays system error page when I expect custom error page.
A: Configure Error Pages for the website in IIS. Error Pages may differ between websites.

Q: Error handling is defined in web.config but does not work in Windows Server 2008.
A: Try to edit Error Pages directly in IIS (IIS Manager -> Sites -> (website name) -> Error Pages)

Q: Status code 200 OK displays a custom error page but 404 Not Found displays generic IIS error page (yellow box with techical message)
A: Configure Error Pages (see above). “customErrors” in web.config may not work as expected.

Q: Can I keep status 200 OK to display error page?
A: It will do the job for users who visually see and understand the content, but may not work for bots (i.e. displaying error page in search result)