Solving development problems  |  About this blog

Archive for the ‘ASP.NET MVC’ Category

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 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)


How to trim leading and trailing HTML spaces in C#

Some HTML WYSIWYG editors create ‘br’ tags or leave ‘&nbsp;’ garbage spaces when no content is entered. Described TrimWhiteSpaces method is useful when you need to determine if user left blank content in WYSIWYG editor or if you just want to clean HTML code.

TrimWhiteSpaces accepts raw HTML content and removes white spaces, tabs, new line characters, ‘br’ tags and ‘&nbsp;’ chunks from before and after the actual content.

public static string TrimWhiteSpaces(string html)
{
  string result = html;

  //Remove leading spaces
  result = Regex.Replace(result, @"^(?<leading>(\s|\r|\n|\<br\s*/?\>|&nbsp;)*)", "",
RegexOptions.IgnoreCase);

  //Remove trailing spaces
  result = Regex.Replace(result, @"(?<trailing>(\s|\r|\n|\<br\s*/?\>|&nbsp;)*)$", "",
RegexOptions.IgnoreCase);

  return result;
}
Example:
Input:

&nbsp;<br /><BR   ><BR> &nbsp;
&nbsp;&nbsp;<br />
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
&nbsp;&nbsp;<br />
<p>Pellentesque lorem neque, accumsan eget euismod ut, tristique et odio.</p>
&nbsp;<br /> <br>
&nbsp;
Output:


<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
&nbsp;&nbsp;<br />
<p>Pellentesque lorem neque, accumsan eget euismod ut, tristique et odio.</p>

Written by developer

December 13th, 2010 at 1:27 pm

Parsing URL query string into key-value pairs in C#

Imagine you have URL something like this:

http://www.yourdomain.com?param1=value1&param2=value2&param3=value3&param4=value4

and you want to get key-value pairs such as

  • {“param1″, “param2″, “param3″, “param4″}
  • {“value1″, “value2″, “value3″, “value4″}

It is easy to do using system function:

using System.Collections.Specialized;
NameValueCollection query = HttpUtility.ParseQueryString(queryString);
Response.Write(query["param1"]);

Written by Avivo

December 3rd, 2010 at 1:08 pm

Compiler Error Message: CS0016: Could not write to output file – Temporary ASP.NET Files – Access is denied

Everything was working perfectly and then suddenly during ASP.NET (MVC) development you got this error from your IIS 7 server (in our case from Windows 7 64-bit):
Compiler Error Message: CS0016: Could not write to output file ‘c:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\myapp\xxxxx\xxxxx\App_GlobalResources.xxxxxxx.dll’ — ‘Access is denied.’
So, what goes wrong? You don’t know because it was working perfectly previous day, it is also compiles OK but not working anymore on your IIS webserver and, all you got, is yellow screen with this error message.

We searched a little bit and found that the problem appeared because the permission were lost on following Temporary folders:

C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\

C:\Windows\Temp

Recipe

  • Gave a full permission to NETWORK SERVICE user to these folders (extreme case is to give full permission to Everyone user to these folders – do this only it doesn’t work)
  • Restart IIS using iisreset command

IIS started to serve pages again….