Archive for the ‘C sharp’ Category
ASP.MVC 2 – How to migrate project from ASP.NET 2.0 .NET Framework 3.5 to ASP.NET 4.0 .NET Framework 4
So you have decided to move your ASP.NET MVC2 project from the Windows Server configured with ASP.NET 2.0 .NET Framework 3.5
to ASP.NET 4.0 .NET Framework 4.
Here is how I did it.
My old setup:
Windows Server 2008 R2
IIS 7.5
ASP.NET
Application Pool : .NET Framework v2.0.50727
.NET Framework installed: 3.5 SP1
My new setup:
Windows Server 2008 R2
IIS 7.5
ASP.NET
Application Pool : .NET Framework v4.0.30319
.NET Framework installed: 4.0
The good thing is that the ASP.NET is backward compatible. You shoud publish the website on the new setup and it should work straight away.
In my case I had to remove these from web.config:
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirepermission="false" allowdefinition="MachineToApplication"></section> <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirepermission="false" allowdefinition="Everywhere"></section><section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirepermission="false" allowdefinition="MachineToApplication"></section><section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirepermission="false" allowdefinition="MachineToApplication"></section><section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirepermission="false" allowdefinition="MachineToApplication"></section>
If it still gives you problems got to IIS Manager and click Error Pages:

Select 500 , right click and select Edit Feature Settings
Here select “Detailed errors”

Now you should get detailed error within your web.config. Also check Event Viewer under the section Administrative Events
ASP.NET MVC2 Visual Studio Error – The project type is not supported by this installation
If you get this error when opening a solution in Visual Studio, just go to the project file (YourProject.csproj) which fails to open and change the line
<ProjectTypeGuids>{Some_GUID}</ProjectTypeGuids>
to
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
ASP.NET MVC2 in the web farm – slow page load with high traffic – where is the bottleneck?
Recently I have implemented quite complex e-commerce web application using technologies such as: ASP.NET MVC2, Linq2SQL , .NET 3.5 , SQL Server 2008 R2.
We have the whole thing hosted in the web farm.
We have 4 x IIS7 + 1 SQL SERVER 2008 load balanced with MS NLB
Static content is cached by external cache provider – Akamai, which reduces 86% of the requests.
Each web server has 32 GB of RAM and 4 x quad core CPUs so there are 64 cores on the front-end.
We store session state in tables of SQL server.
It works prefectly with medium traffic (page load = 0.2 -0.3 s)

but the company does the tv ads and during those ads the traffic hits up to 20,000 -30,000 users within 20-30 seconds.
In this moment the page slows down to 39 seconds. However, the usage of CPU’s and the memory doesn’t even arrive to 40% on any machine.
![]()
The bandwidth of the data centre does not arrive to the half of its limits.
Pages which are slow generate data from simple SELECTs of maximum 10 records from 1-2 tables only.
I gone through all possible things: I already had my queries compiled but I also optimized selects, created additional indexes studied a lot the problems of storing session in tables that sql server 2005 had (temdb) and I couldn’t figure out what was going on.
You could reproduce the the problem by launching stress tools against the web. The worst thing was that we could freeze the web just by launching stress tools from only two pc’s located in our offices.
I have also posted the question on stackoverflow
http://stackoverflow.com/questions/7644339/asp-net-mvc2-in-the-web-farm-slow-page-load-with-high-traffic
where people suggested to check indexes and use CompiledQuery.
In practice 90% of the bottlenecks are caused by database. After the whole week of tests and studying the problem I have possibly found a bug in the ASP.NET MVC2 library.
It was incredible how silly the thing was:
Let’s have a look at this code:
public ActionResult Index(){
var model = new SomeModel();
// Get data
....
return View(model);
}
In this code the View is generated using file Index.aspx.
However, this View needs to be found in some way and I guess the search of the this View is causing the problem.
Unbelievable but true – adding the name of the View removed the problem:
public ActionResult Index() {
var model = new SomeModel();
// Get data
....
return View("Index",model);
}
I say it again, this problem does exists only when the web has a high number of users.
The MVC version I’m using is
Version: 2.0.0.0
Runtime: v2.0.50727
I have contacted the geeks responsible for the design and development of this great library to see what they say.
By all means I don’t want to discourage anyone to use this library as it is absolutely fantastic and I use it a lot and I will carry on using it.
How to remove Server, X-AspNet-Version, X-AspNetMvc-Version and X-Powered-By from the response header in IIS7
You can check your response headers by using Firebug add-on for Firefox or just hit Ctrl+J in Chrome.

Unwanted info:
Server Microsoft-IIS/7.5
X-AspNetMvc-Version 3.0
X-AspNet-Version 4.0.303319
X-Powered-By ASP.NET
1. Removing X-AspNet-Version
In web.config stick this line in
<system.web>
<httpRuntime enableVersionHeader="false"/>
...
2. Removing X-AspNetMvc-Version
In Global.asax.cs add this line:
protected void Application_Start()
{
MvcHandler.DisableMvcResponseHeader = true;
}
3. Removing or changing Server
Add this module class to your project.
using System;
using System.Web;
namespace Project.Infrastructure.Web.Modules.Http
{
public class CustomHeaderModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += OnPreSendRequestHeaders;
}
public void Dispose() { }
void OnPreSendRequestHeaders(object sender, EventArgs e)
{
//HttpContext.Current.Response.Headers.Remove("Server");
// Or you can set something funny
HttpContext.Current.Response.Headers.Set("Server", "CERN httpd");
}
}
}
And add set it in web config
<system.webServer>
<modules>
<add name="CustomHeaderModule" type="StrongNamespace.HttpModules.CustomHeaderModule" />
4. Removing or changing X-Powered-By
Go to IIS7 Management Console and open HTTP Response Headers

And that should be it!
How to Switch Between HTTP and HTTPS in ASP.NET MVC2 And Allow AJAX Requests From Site Master.
In order to serve the request throught SSL in ASP.NET MVC2 we can simple use Action attribute [RequireHttps]:
//LoginController
[RequireHttps]
public ActionResult Index()
{
return View();
}
Let’s say I served a login form here. Then the user logs in.
//LoginController
[RequireHttps]
[HttpPost]
public ActionResult Index(LoginModel model)
{
if (model != null && model.Username == "arturito")
return RedirectToAction("List", "Home");
else
return RedirectToAction("Login");
}
Note that the redirection ( RedirectToAction(“List”, “Home”) ) is taking us to HomeController List action.
However the action List in HomeController is not decorated in [RequireHttps] so it should return to HTTP.
//HomeController
public ActionResult List()
{
return View();
}
BUT IT DOESN’T!
You will remain in HTTPS.
Jeff Widmer worked out a great solution and posted it in his article.
In his solution we have BaseController and we are overriding OnAuthorization method
public class BaseController : Controller
{
protected override void OnAuthorization(AuthorizationContext filterContext)
{
//the RequireHttpsAttribute set on the Controller Action will handle redirecting to Https.
// We just need to handle any requests that are already under SSL but should not be.
if (Request.IsSecureConnection)
{
Boolean requireHttps = false;
requireHttps = filterContext.ActionDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), false).Count() >= 1;
//If this request is under ssl but yet the controller action
// does not require it, then redirect to the http version.
if (!requireHttps && !filterContext.IsChildAction)
{
UriBuilder uriBuilder = new UriBuilder(Request.Url);
//change the scheme
uriBuilder.Scheme = "http";
uriBuilder.Port = 80;
filterContext.Result = this.Redirect(uriBuilder.Uri.AbsoluteUri);
}
}
base.OnAuthorization(filterContext);
}
}
But there is one problem left!
Let’s say that all pages served through HTTP and HTTPS use the same site master page which contains a link or the form that creates ajax request.
As an example let’s look at this simple action:
// Home Controller
[HttpPost]
public ActionResult Ajax()
{
return Content("This is Ajax");
}
This works great from HTTP page!


….but when we call the same action from HTTPS page it doesn’t work!

Why? This is called crossdomain ajax request, which by default is not allowed for security reasons. There are some methods/libraries/proxies to achieve this but it is not very common yet.
If we decorate it with [RequireHttps] attribute:
// Home Controller
[RequireHttps]
[HttpPost]
public ActionResult Ajax()
{
return Content("This is Ajax");
}
This action becomes available only if requested from the page served through HTTPS. We can no longer call it from the page served through http.
Well then, let’s allow to perform all ajax request from pages served by both HTTP and HTTPS:
protected override void OnAuthorization(AuthorizationContext filterContext)
{
//the RequireHttpsAttribute set on the Controller Action will handle redirecting to Https.
// We just need to handle any requests that are already under SSL but should not be.
if (Request.IsSecureConnection)
{
Boolean requireHttps = false;
requireHttps = filterContext.ActionDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), false).Count() >= 1;
// Allow Ajax request from both http and https pages
if (Request.IsAjaxRequest())
{
base.OnAuthorization(filterContext);
return;
}
//If this request is under ssl but yet the controller action
// does not require it, then redirect to the http version.
if (!requireHttps && !filterContext.IsChildAction)
{
UriBuilder uriBuilder = new UriBuilder(Request.Url);
//change the scheme
uriBuilder.Scheme = "http";
uriBuilder.Port = 80;
filterContext.Result = this.Redirect(uriBuilder.Uri.AbsoluteUri);
}
}
base.OnAuthorization(filterContext);
}
}
Now whether we are on login page (HTTPS) or any other page (HTTP) we can create ajax requests in the site master without decorating ajax actions with additional attributes or messing around
with url scheme in the Views.
Here is a downloadable example: http://www.mediafire.com/?0d6dn6w489yalgo
GL
ASP.NET MVC 2 Highlight Selected Menu Item on the Site Master Without Session
ASP.NET MVC2 makes so many things so easy to program but there are some basic things that are just not there and they should be.
I will be talking about a basic functionality that is a must these days.
I am talking about a menu and highlighting selected menu item.
Let’s see the problem:
I have 3 links and with each click I would like to add apropiate css class to mark my menu item as selected.

I have follwed an article on bobby’s blog.
So with this great extension it does work really well:
public static class HtmlExtensions
{
public static MvcHtmlString ActionMenuItem(this HtmlHelper htmlHelper,
String linkText, String actionName, String controllerName)
{
var tag = new TagBuilder("li");
if (htmlHelper.ViewContext.RequestContext.IsCurrentRoute(
null, controllerName, actionName) ||
htmlHelper.ViewContext.RequestContext.IsParentRoute(
controllerName, actionName))
{
tag.AddCssClass("active");
}
tag.InnerHtml = htmlHelper.ActionLink(linkText, actionName, controllerName).ToString();
return MvcHtmlString.Create(tag.ToString());
}
}
In the place of menu we stick this:
<%= Html.ActionMenuItem("Home", "Index", "Home") %>
However, there was a one little thing missing in it that I needed to have on my web.

In the About link I have a link to Biography . (Biography controller and Index action)
Since the Biography page is a part of About section I would like the “About” menu item to remain highlighted.
The solution above doesn’t work in that case.
So I decided to modify it a bit.
Let’s start from the extension:
public static class HtmlExtensions
{
public static MvcHtmlString ActionMenuItem(this HtmlHelper htmlHelper, String linkText, String actionName, String controllerName)
{
var tag = new TagBuilder("li");
if (htmlHelper.ViewContext.RequestContext.IsCurrentRoute(null, controllerName, actionName) ||
htmlHelper.ViewContext.RequestContext.IsParentRoute(controllerName, actionName))
{
tag.AddCssClass("active"); // stick class active
}
else
{
tag.AddCssClass("inactive"); // stick class inactive
}
tag.InnerHtml = htmlHelper.ActionLink(linkText, actionName, controllerName).ToString();
return MvcHtmlString.Create(tag.ToString());
}
}
We also neeed Request Extensions:
public static class RequestExtensions
{
public static bool IsCurrentRoute(this RequestContext context, String areaName)
{
return context.IsCurrentRoute(areaName, null, null);
}
public static bool IsCurrentRoute(this RequestContext context, String areaName, String controllerName)
{
return context.IsCurrentRoute(areaName, controllerName, null);
}
public static bool IsCurrentRoute(this RequestContext context, String areaName, String controllerName, params String[] actionNames)
{
var routeData = context.RouteData;
var routeArea = routeData.DataTokens["area"] as String;
var current = false;
if (((String.IsNullOrEmpty(routeArea) && String.IsNullOrEmpty(areaName)) || (routeArea == areaName)) &&
((String.IsNullOrEmpty(controllerName)) || (routeData.GetRequiredString("controller") == controllerName)) &&
((actionNames == null) || actionNames.Contains(routeData.GetRequiredString("action"))))
{
current = true;
}
return current;
}
public static bool IsParentRoute(this RequestContext context, String controller, String action)
{
var routeData = context.RouteData;
UrlModel returnUrl = null;
UrlModel requestUrl = new UrlModel { Action = routeData.GetRequiredString("action"), Controller = routeData.GetRequiredString("controller") };
UrlModel linkUrl = new UrlModel { Action = action, Controller = controller };
var urls = UrlMap.GetDictionary();
urls.TryGetValue(requestUrl, out returnUrl);
if (returnUrl != null && returnUrl.Equals(linkUrl))
return true;
else
return false; ;
}
}
And now the important part the UrlMap
public static class UrlMap
{
public static Dictionary GetDictionary()
{
Dictionary urls = new Dictionary();
urls.Add(new UrlModel { Controller = "Biography", Action = "Index" }, new UrlModel { Controller = "About", Action = "Index" });
urls.Add(new UrlModel { Controller = "Contact", Action = "GetInTouch" }, new UrlModel { Controller = "Contact", Action = "Index" });
return urls;
}
}
Here I specify that if Biography/Index is called please mark it the same as About/Index.
Don’t forget to create UrlModel class
public class UrlModel
{
public string Action { get; set; }
public string Controller { get; set; }
public override bool Equals(object obj)
{
return Equals(obj as UrlModel);
}
public bool Equals(UrlModel obj)
{
return obj != null && obj.Action == this.Action && obj.Controller == this.Controller;
}
public override int GetHashCode()
{
return (Action + Controller).GetHashCode();
}
}
Now you can stick HtmlHelper with menu in any place on the site.
<ul id="menu">
<%= Html.ActionMenuItem("Home", "Index", "Home") %>
<%= Html.ActionMenuItem("About", "Index", "About") %>
<%= Html.ActionMenuItem("Contact", "Index", "Contact") %>
</ul>
and add as amny Url Mapsas you like:
public static Dictionary GetDictionary()
{
Dictionary urls = new Dictionary();
urls.Add(new UrlModel { Controller = "Biography", Action = "Index" }, new UrlModel { Controller = "About", Action = "Index" });
urls.Add(new UrlModel { Controller = "Contact", Action = "GetInTouch" }, new UrlModel { Controller = "Contact", Action = "Index" });
return urls;
}
Here is how it looks: 


Here is a complete solution to download: http://www.mediafire.com/?0xabi855suro2rl GL!
ASP.NET MVC2 jQuery Form Post with JSON Tutorial
In one of the previous post I covered how to post form with ASP.NET MVC2 using jQuery.
Today I will explain how to return data in JSON format. Why return data in JSON format. Well there are several reasons for it:
1. You can easily update several parts of the page without reloading entire page
Imagine that you have ajax login and after successful login the name of the user is updated in the header of the page and content of the saved cart in the right column.
2. It reduces the amount of data sent from the server to the browser.
In a lot of cases developers send data wrapped in html such as:
return Content(“
You submitted: “ “
or they send PartialView. But the idea of JSON is to send data only without html tags, which also reduces the traffic.
3. It separates application logic from design
Sending only data using JSON means data doesn’t have to be wrapped in html tags in your controller, you only send pure data. This way one developer can concentrate on developing logic and doesn’t have to think how it will be displayed, leaving web designer to handle presentation part.
Let’s start modifying previous project:
1. Open MVC2JQuery project that can be downloaded here MVC2JQuery at MediaFire
2. Open RegisterViewModel and modified it as below:
public class RegisterViewModel
{
public string FirstName { get set }
public string LastName { get set }
public int NumberOfPosts { get set }
public string LastPost { get set }
}
3. Open HomeController and make changes as shown below:
[HttpPost]
public ActionResult Index(RegisterViewModel data)
{
// here you can save data to database
// and return some feedback to the user
data.NumberOfPosts = 5;
data.LastPost = “This is my last post”
if(Request.IsAjaxRequest())
return Json(data); // here data object is being converted to JSON format
else
return Content(“Please enable JavaScript”);
}
4. Also modify Views/Index accordingly
In the
part:<script type=”text/javascript” src=”<%=Url.Content("~/Scripts/jquery-1.4.4.min.js")%>“>script>
<script type=”text/javascript” src=”<%=Url.Content("~/Scripts/jquery.form.js")%>“>script>
<script type=”text/javascript”>
$(document).ready(function() {
var options = {
beforeSubmit: showRequest, // call this function before sending data to the server
success: showResponse, // call this function once we have a response form the server
type: ‘post’,
dataType: ‘json’, // important! expecting data type is JSON
resetForm: true
};
$(‘#form-user’).ajaxForm(options);
});
function showRequest(formData, jqForm, options) {
$(“#result-user”).empty().html(‘Loading….’); // display loading
$(“#form-user :input”).attr(“disabled”, true); // disable inputs
}
function showResponse(data, statusText, xhr, $form) {
$(“#result-user”).empty();
$(“#form-user :input”).attr(“disabled”, false);
// here ‘data’ is an object. See below how it is used:
$(“#welcome”).html(“Hello, “ + data.FirstName + ” “ + data.LastName);
$(“#number”).html(“Number of posts: “ + data.NumberOfPosts);
$(“#lastpost”).html(data.LastPost);
}
script>
In the
part:
<body>
<% using (Html.BeginForm(“Index”,“Home”,FormMethod.Post, new { id=“form-user”, name=“form-user”})) {%>
<div style=”float:left” id=”welcome”>div>
<div style=”float:right” id=”number”>div>
<div style=”clear:both“>div>
<fieldset>
<legend>Fieldslegend>
<div class=”editor-label”>
<%= Html.LabelFor(model => model.FirstName) %>
div>
<div class=”editor-field”>
<%= Html.TextBoxFor(model => model.FirstName) %>
<%= Html.ValidationMessageFor(model => model.FirstName) %>
div>
<div class=”editor-label”>
<%= Html.LabelFor(model => model.LastName) %>
div>
<div class=”editor-field”>
<%= Html.TextBoxFor(model => model.LastName) %>
<%= Html.ValidationMessageFor(model => model.LastName) %>
div>
<p>
<input type=”submit” value=”Save” />
p>
fieldset>
<% } %>
<div id=”result-user”>div>
<div style=”border:solid 1px #cccmargin:10px“ id=”lastpost” >div>
body>
5. And we are done! Hit F5 and see result:


Here you can download complete source code: http://www.mediafire.com/?ul8wl6o2fe47qk4
Good Luck!
Publishing ASP.NET MVC2 Application on Windows Server 2008 IIS 7 with Visual Studio 2008 on platform .NET 3.5 SP1
Prepare you server:
1. Go to Server Manager and select Add Roles, and install Web Server



2. Mark ASP.NET and install



3. Confirm the CLR of ASP.NET has been installed

4. Install .NET Framework 3.5 and .NET Framework 3.5 SP1

5. Let’s create a directory where we stick our MVC2 application. In my case it is C:\www\windows.amk
6. Once you are done go to the Security properties of that directory and add read and write permissions for group IIS_IUSRS

7. Go back to IIS Manager and Add Site


8. In Application Pool double click pool of your site and make sure that Managed pipeline mode is Integrated


Now the server is prepared to run MVC2 web application!
Prepare your project to be published
1. Go to your project properties and mark Release

2. Go to References and and change Property Copy Local to true for
System.ComponentModel.DataAnnotations.dll
System.Web.Mvc.dll


If you are running .NET Framework 3.5 NOT .NET Framework 3.5 SP1 change properties for all these.
System.ComponentModel.DataAnnotations.dll
System.Web.Abstractions.dll
System.Web.Mvc.dll
System.Web.Routing.dll
6. In Web.config change lines
<compilation debug="true">
to
<compilation debug="false">
And uncomment this bit:
<customerrors mode="RemoteOnly" defaultredirect="GenericErrorPage.htm">
<error statuscode="403" redirect="NoAccess.htm" />
<error statuscode="404" redirect="FileNotFound.htm" />
</customerrors>
7. Generate and upload files to directory on the server in my case c:\www\windows.amk
* What we need:
- Configuration and settings files (e.g., Web.config and any *.settings files)
- Uncompiled view templates (*.aspx, *.ascx, and *.Master)
- Global.asax (this tells ASP.NET which compiled class represents your global HttpApplication)
- Any static files (e.g., images, CSS files, and JavaScript files)
- Optionally, the *.pdb files in your \bin folder, which enable extra debugging information (these are rarely deployed to production servers)
* We don’t need:
- C# code files (*.cs, including Global.asax.cs or any other ‘code behind’ files)
- Project and solution files (*.sln, *.suo, *.csproj, or *.csproj.user)
- The \obj folder
- Anything specific to your source control system (e.g., .svn folders if you use Subversion, or the .hg or .git folders if you use Mercurial or Git)

Good Luck!
Using Google Maps API to mark multiple addresses fetched from database ASP.NET MVC2 and Geocoder
This tutorial will cover marking multiple addresses stored in database on Google Maps. For example this can be useful for marking chain of shops or restaurants or others.
The idea is to get something like this:

Before starting it we have to obtain a key for using their API.
You can do it here:
http://code.google.com/apis/maps/signup.html
Generate your key and save it
1. Create new Empty MVC2 project
2. Insert new .ashx file call it Maps.ashx.
I placed mine the folder Services which I created before.

3. Insert this code
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Maps : IHttpHandler {
public void ProcessRequest(HttpContext context) {
context.Response.ContentType = "text/xml";
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
string sXml = createMarkers();
context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(600));
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Write(sXml);
}
public bool IsReusable {
get { return true; }
}
private string createMarkers() {
// Create the xml document container
XmlDocument doc = new XmlDocument();//
Create the XML Declaration, and append it to XML document
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
doc.AppendChild(dec);// Create the root element
XmlElement root = doc.CreateElement("markers");
doc.AppendChild(root);
// Here you can create a loop and fetching data from database like
/* while(rdr.Read()) {
XmlElement marker = doc.CreateElement("marker");
marker.SetAttribute("name", rdr["name"].ToString());
marker.SetAttribute("address", rdr["address"].ToString());
root.AppendChild(marker);
}
*/
// To retrieve data using a C# go here:
// http://www.akadia.com/services/dotnet_data_reader.html
// We will enter it manually
XmlElement marker = doc.CreateElement("marker");
marker.SetAttribute("name", "L'arruzz");
marker.SetAttribute("address", "C/ PORTUGAL, 35, 03003 ALICANTE");
root.AppendChild(marker);
XmlElement marker2 = doc.CreateElement("marker");
marker2.SetAttribute("name", "CERVECERIA VICTOR");
marker2.SetAttribute("address", "C/ SAN AGATÁNGELO, 37, 03007 ALICANTE");
root.AppendChild(marker2);
return doc.OuterXml;
}
}
4. Next step is to create HomeController and create Index View.
public ActionResult Index()
{ return View();
}
5. Now run your project and check if xml is being genrated by go to url of ashx file:
http://localhost:your_port_number/Services/Maps.ashx
For example in my case:http://localhost:1951/Services/Maps.ashx

6. Go back your HomeController and right click and create Index View. Your code should be the same as below:
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Index</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=here_we_enter_google_api_key" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
var map = null;
var geocoder = null;
function load() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
geocoder = new GClientGeocoder();
// Here enter your url of ashx file
GDownloadUrl("http://localhost:1951/Services/Maps.ashx", function(data) {
var xml = GXml.parse(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
showAddress(address,name);
}
});
}
}
function showAddress(address, name) {
if (geocoder) {
geocoder.getLatLng(
name+","+address,
function(point) {
if (!point) {
alert(address + " not found");
} else {
map.setCenter(point, 13);
var marker = createMarker(point, name, address);
map.addOverlay(marker);
}
});
}
}
function createMarker(point, name, address) {
var marker = new GMarker(point);
var html = "<b>" + name + "</b> <br/>" + address;
GEvent.addListener(marker, 'click', function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
//]]>
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div>
<div id="map" style="width: 1000px; height: 600px"></div>
</div>
</body>
</html>
Run it and there we go!

You can also do it without ashx and return xml as an ActionResult
public ActionResult PrintMarkers() {
XmlDocument doc = new XmlDocument();//
Create the XML Declaration, and append it to XML document
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
doc.AppendChild(dec);// Create the root element
XmlElement root = doc.CreateElement("markers");
doc.AppendChild(root);
XmlElement marker = doc.CreateElement("marker");
marker.SetAttribute("name", "L'arruzz");
marker.SetAttribute("address", "C/ PORTUGAL, 35, 03003 ALICANTE");
root.AppendChild(marker);
XmlElement marker2 = doc.CreateElement("marker");
marker2.SetAttribute("name", "CERVECERIA VICTOR");
marker2.SetAttribute("address", "C/ SAN AGATÁNGELO, 37, 03007 ALICANTE");
root.AppendChild(marker2);
return doc.OuterXml;
}
And simply call it from script of JavaScript:
GDownloadUrl("http://localhost:1951/Home/PrintMarkers/", function(data) {
var xml = GXml.parse(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
showAddress(address,name);
}
});
Will do the same.
Good luck!
ASP.NET MVC2 jQuery Form Post Tutorial
Here is a little tutorial that I wrote about posting form using jQuery and Form plugin.I’m using Visual Studio 2008.
If you want to see how to post form with JSON check my other post:
http://arturito.net/2011/01/25/asp-net-mvc2-jquery-form-post-with-json-tutorial/
1. Open Visual Studio
2. Create MVC2 Empty Web Application

3. Right click Controllers in Solution Explorer and select Add Controller
4. Name it HomeController

5. Right Click on Models in Solution Explorer and select Add Class…
6. Name it RegisterViewModel

Insert this piece of code:
namespace MVC2JQuery.Models
{
public class RegisterViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
7. In the Toolbar click Build->Build Solution
8. Go back to HomeController and right click on Index() and select Add View …
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index() // <-- right click here
{
return View();
}
}

9. You will be taken to your Index.aspx
10. Now run the application by hitting F5 (Click ok on “Debugging Not Enabled” with option “Modify…”)
11. Now, let’s make it do something. Stop Debugging and go back to Home Controller and add Action:
[HttpPost]
public ActionResult Index(RegisterViewModel data)
{
// here you can save data to database
// and return some feedback to the user
return Content("You submitted: " + data.FirstName + " " + data.LastName);
}
12. Your HomeController will look like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVC2JQuery.Models;
namespace MVC2JQuery.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(RegisterViewModel data)
{
// here you can save data to database
// and return some feedback to the user
return Content("You submitted: " + data.FirstName + " " + data.LastName);
}
}
}
Build project and Run it.


13. Now go to Scripts in Solution Explorer and remove all file that are in there. We won’t be using them.
14. Download:
jQuery:
http://code.jquery.com/jquery-1.4.4.min.js
jQuery Form Plugin:
https://github.com/malsup/form/raw/master/jquery.form.js
Save them in Scripts folder of your project.


15. Go to Views and chaage Index.aspx as below:
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<mvc2JQuery.Models.RegisterViewModel>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Index</title>
<script type="text/javascript" src="<%=Url.Content("~/Scripts/jquery-1.4.4.min.js")%>"></script>
<script type="text/javascript" src="<%=Url.Content("~/Scripts/jquery.form.js")%>"></script>
<script type="text/javascript">
$(document).ready(function() {
var options = {
target: '#result-user', // id of the div where we are going to display result
beforeSubmit: showRequest,
success: showResponse,
type: 'post',
resetForm: true
};
$('#form-user').ajaxForm(options); // id of the form we wish to submit
});
function showRequest(formData, jqForm, options) {
$("#result-user").empty().html('Loading....');
$("#form-user :input").attr("disabled", true); // disable all form inputs while loading
}
function showResponse(responseText, statusText, xhr, $form) {
$("#result-user").empty().html(responseText);
$("#form-user :input").attr("disabled", false);
}
</script>
</head>
<body>
<% using (Html.BeginForm("Index","Home",FormMethod.Post, new { id="form-user", name="form-user"})) {%>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%= Html.LabelFor(model => model.FirstName) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.FirstName) %>
<%= Html.ValidationMessageFor(model => model.FirstName) %>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.LastName) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.LastName) %>
<%= Html.ValidationMessageFor(model => model.LastName) %>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div id="result-user"></div>
</body>
</html>
16. Let’s go back to our HomeController and amend Index action:
[HttpPost]
public ActionResult Index(RegisterViewModel data)
{
// here you can save data to database
// and return some feedback to the user
if(Request.IsAjaxRequest())
return Content("You submitted: " + data.FirstName + " " + data.LastName + " using jQuery");
else
return Content("You submitted: " + data.FirstName + " " + data.LastName);
}
17. Build and Run


Here you can download working example
Note: If you are not getting the same result make sure that:
1.Ids are equal
$(‘#form-user‘).ajaxForm(options);
Html.BeginForm(“Index”,”Home”,FormMethod.Post, new { id=”form-user“, name=”form-user“})
$(“#result-user“).empty().html(responseText);
