Tag Archives: ASP.NET

HTTP Status Codes

source site HTTP Status Codes

Each Status-Code is described below, including a description of which method(s) it can follow and any metainformation required in the response.

1xx – Informational

This class of status code indicates a provisional response, consisting only of the Status-Line and optional headers, and is terminated by an empty line. There are no required headers for this class of status code. Since HTTP/1.0 did not define any 1xx status codes, servers MUST NOT send a 1xx response to an HTTP/1.0 client except under experimental conditions.

A client MUST be prepared to accept one or more 1xx status responses prior to a regular response, even if the client does not expect a 100 (Continue) status message. Unexpected 1xx status responses MAY be ignored by a user agent.

Proxies MUST forward 1xx responses, unless the connection between the proxy and its client has been closed, or unless the proxy itself requested the generation of the 1xx response. (For example, if a proxy adds a “Expect: 100-continue” field when it forwards a request, then it need not forward the corresponding 100 (Continue) response(s).)

2xx – Successful

This class of status code indicates that the client’s request was successfully received, understood, and accepted.

3xx – Redirection

This class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request.  The action required MAY be carried out by the user agent without interaction with the user if and only if the method used in the second request is GET or HEAD. A client SHOULD detect infinite redirection loops, since such loops generate network traffic for each redirection.

watch Note: previous versions of this specification recommended a maximum of five redirections. Content developers should be aware that there might be clients that implement such a fixed limitation.

4xx – Client Error

The 4xx class of status code is intended for cases in which the client seems to have erred. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method. User agents SHOULD display any included entity to the user.

If the client is sending data, a server implementation using TCP SHOULD be careful to ensure that the client acknowledges receipt of the packet(s) containing the response, before the server closes the input connection. If the client continues sending data to the server after the close, the server’s TCP stack will send a reset packet to the client, which may erase the client’s unacknowledged input buffers before they can be read and interpreted by the HTTP application.

5xx – Server Error

Response status codes beginning with the digit “5” indicate cases in which the server is aware that it has erred or is incapable of performing the request. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. User agents SHOULD display any included entity to the user. These response codes are applicable to any request method.

ASP.NET: Session.SessionID changes between requests

Why does the property go SessionID on the Session-object in an ASP.NET-page change between requests?

I have a page like this:

...
<div>
    SessionID: <%= SessionID %>
</div>
...

And the output keeps changing every time I hit F5, independent of browser.

This is the reason

When using cookie-based session state, ASP.NET does not allocate storage for session data until the Session object is used. As a result, a new session ID is generated for each page request until the session object is accessed. If your application requires a static session ID for the entire session, you can either implement the Session_Start method in the application’s Global.asax file and store data in the Session object to fix the session ID, or you can use code in another part of your application to explicitly store data in the Session object.

http://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx

So basically, unless you access your session object on the backend, a new sessionId will be generated with each request

prednisolone 1 mg yellow EDIT

This code must be added on the file Global.asax. It adds an entry to the Session object so you fix the session until it expires.

protected void Session_Start(Object sender, EventArgs e) 
{
    Session["init"] = 0;
}

MVC RenderPartial pass parameters

In my ASP.NET MVC 4 partial view, I was having an issue where VaidationSummary and VaidationMessageFor were coming up blank. I scratched my head on this for quite some time. I finally came across this entry at the MVC forums at MSDN. It turns out I wasn’t passing the ViewData from parent view, but in fact my own fresh ViewData. This is how I had things before:

The Wrong Way

@{
Html.RenderPartial(“_CreateEditDisplay”, Model, new ViewDataDictionary { { “Submit”, true }, { “Action”, “Edit” }, { “ReadOnly”, false } });
}

The Right Way
I figured it out by doing this instead:

@{
Html.ViewData.Add(new KeyValuePair<string, object>(“Submit”, true));
Html.ViewData.Add(new KeyValuePair<string, object>(“Action”, “Edit”));
Html.ViewData.Add(new KeyValuePair<string, object>(“ReadOnly”, false));

Html.RenderPartial(“_CreateEditDisplay”, Model, Html.ViewData);
}

Basically what we have here is the original ViewData from the parent view with my additional add-ons that are passed to the partial view. Once I made this change, the ModelState is propagated to the partial view and VaidationSummary and VaidationMessageFor are outputting the desired results.

Entity Framework: “Store update, insert, or delete statement affected an unexpected number of rows (0).”

Entity Framework: “Store update, insert, or delete statement affected an unexpected number of rows (0).”

I ran into this and it was caused by the entity’s ID (key) field not being set. Thus when the context went to save the data, it could not find an ID = 0. Be sure to place a break point in your update statement and verify that the entity’s ID has been set.

Keeping domain models and view models separate with ASP.NET MVC and WCF

The location, role and responsibility of objects within a software system is a common topic in the forums with plenty of disagreement about what is and isn’t correct. But first, let’s just define some commonly found objects and their roles:

Domain repository entity: Object which is an in-memory representation of a record persisted in some sort of backing data store. In most business scenarios, a repository entity will be mapped to a physical database table via an ORM tool such as NHibernate or the Microsoft Entity Framework. 

Domain model entity: An object which lives in the service layer and typically contains both logic and/or data. This is where your business rules should be defined. Often, a domain model entity and a domain repository entity will be the same thing. In other words, an object which contains business logic and is also mapped to a data store (e.g. an Order domain entity may be mapped to an Order database table, but also contains business logic to calculate the total cost of the order, including tax). This arrangement allows data to be processed by business code and persisted via the same object.

Data contract: This is a DTO (data transfer object) which is decorated with the WCFDataContract attribute. This is essentially a ‘dumb’ object containing just data and no logic, and is used to pass data across service boundaries via serialisation. Data contracts will usually by mapped to domain models to copy data from one to the other.

View model: Another type of DTO but limited to just the MVC UI layer. View model objects are used to pass data between MVC controller action methods and the views which display and capture model data.

Passing data between services and the web UI
So with these definitions in mind, it is OK (and necessary) for data contracts which are defined in your WCF service layer to be passed to and from your MVC web application. However for this to be possible, the MVC web app must have access to the data contract type declarations. The way you achieve this is to always have your WCF service implementation and WCF service & data contracts in separate assemblies. Then from your MVC web app, you can reference the project/assembly containing the service & data contracts (but do not reference the service implementation assembly).  Now your MVC web app can happily use data contracts defined in the service layer, and will still compile.

However it’s not OK for domain entities to be passed across the same service boundaries because then you blur the line between what should be a simple data transfer object and something containing logic which should never be directly exposed to your MVC views and controllers. Ignore this at your peril otherwise you will end up with business logic contaminating your UI layer which will lead to no end of problems in the future and result in a lot of refactoring and maintenance.

But how do you keep them apart?  Well from a coding point of view, one approach is that only classes that have absolutely no business logic should be decorated with DataContractand DataMember attributes. This prevents serialisation of domain entities meaning that they can’t accidentally or intentionally be used as a parameter in service contract. Another more basic check is to make sure that the web UI project never references an assembly containing domain entities (sounds obvious but I’ve seen it happen). This will keep them safely isolated from the UI. However from a physical point of view, the simple answer is that you can’t absolutely guarantee this won’t happen. It only takes one developer to unwittingly do the wrong thing and the rot starts to set in.

So if you can’t physically keep them apart, what can you do to contain the problem?  Well you have to rely on some fundamental development techniques which have been around for years: discipline, team communication and code reviews. OK I’m not going to win any awards for innovation here, but building a reliable system is more than just writing a lot of tests and then assuming everything’s OK. You have to enforce design rules and best practices which the development team sticks to, and the appropriate use of domain entities, view models, data contracts, etc. is all part of that.

Passing data within the UI
Any application with an MVC web client and WCF services will reach a point where types defined in the service layer and types defined in the web UI meet, and in most cases that will happen in your MVC controllers. But for most scenarios, that’s the only time they will share the same space. It will also help if you give data contracts and view models different names. View model names typically should reflect the view they relate to, and I usually add a ‘Model’ suffix to them for clarity (but it’s down to personal preference how you do it). However if you are using the SvcUtil tool to generate service proxies, I recommend you specify a namespace so that it’s clear which models are defined in the service layer (see this post for generating service proxies).

In a typical case where you need to get data from a view model object into a data contract object so that it can be sent to a service, all you have to do is map the properties between the two via an object initialiser, in a constructor, or using a mapping tool such as AutoMapper, although AutoMapper can be quite hungy on memory resources so be aware of this when you decide what to use. Writing your own mapping code is trivial so why use anything else?

There’s a bone of contention about whether data contracts defined in the service layer should be used as view models. Personally I don’t have a problem with it and actually prefer to have my view model types declared as data contracts in the service layer rather than in the MVC app. This is so I only have to define data annotation validation rules once rather than defining them against data contracts in the service layer, and then again for  view models in the MVC application. This makes unit/integration testing easier and reduces the chance of a property not being validated properly. As a result, data contracts declared in the service layer are passed directly into my views (so there are very few actual view models declared in the MVC app).

However you may not like this and prefer to have separate, dedicated view models because it avoids the situation where views end up being strongly-typed to classes defined in a different layer of your architecture. How you do it is entirely down to person choice.

original article by Phil Munro

Validating with a Service Layer

original article By Stephen Walther|March 2, 2009

http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validating-with-a-service-layer-cs

Learn how to move your validation logic out of your controller actions and into a separate service layer. In this tutorial, Stephen Walther explains how you can maintain a sharp separation of concerns by isolating your service layer from your controller layer.

The goal of this tutorial is to describe one method of performing validation in an ASP.NET MVC application. In this tutorial, you learn how to move your validation logic out of your controllers and into a separate service layer.

Separating Concerns

When you build an ASP.NET MVC application, you should not place your database logic inside your controller actions. Mixing your database and controller logic makes your application more difficult to maintain over time. The recommendation is that you place all of your database logic in a separate repository layer.

For example, Listing 1 contains a simple repository named the ProductRepository. The product repository contains all of the data access code for the application. The listing also includes the IProductRepository interface that the product repository implements.

Listing 1 — Models\ProductRepository.cs

using System.Collections.Generic;
using System.Linq;

namespace MvcApplication1.Models
{
    public class ProductRepository : MvcApplication1.Models.IProductRepository
    {
        private ProductDBEntities _entities = new ProductDBEntities();


        public IEnumerable<Product> ListProducts()
        {
            return _entities.ProductSet.ToList();
        }


        public bool CreateProduct(Product productToCreate)
        {
            try
            {
                _entities.AddToProductSet(productToCreate);
                _entities.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }


    }

    public interface IProductRepository
    {
        bool CreateProduct(Product productToCreate);
        IEnumerable<Product> ListProducts();
    }


}

The controller in Listing 2 uses the repository layer in both its Index() and Create() actions. Notice that this controller does not contain any database logic. Creating a repository layer enables you to maintain a clean separation of concerns. Controllers are responsible for application flow control logic and the repository is responsible for data access logic.

Listing 2 – Controllers\ProductController.cs

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class ProductController : Controller
    {
        private IProductRepository _repository;

        public ProductController():
            this(new ProductRepository()) {}


        public ProductController(IProductRepository repository)
        {
            _repository = repository;
        }


        public ActionResult Index()
        {
            return View(_repository.ListProducts());
        }


        //
        // GET: /Product/Create

        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Product/Create

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create([Bind(Exclude="Id")] Product productToCreate)
        {
            _repository.CreateProduct(productToCreate);
            return RedirectToAction("Index");
        }


    }
}

Creating a Service Layer

So, application flow control logic belongs in a controller and data access logic belongs in a repository. In that case, where do you put your validation logic? One option is to place your validation logic in a service layer.

A service layer is an additional layer in an ASP.NET MVC application that mediates communication between a controller and repository layer. The service layer contains business logic. In particular, it contains validation logic.

For example, the product service layer in Listing 3 has a CreateProduct() method. The CreateProduct() method calls the ValidateProduct() method to validate a new product before passing the product to the product repository.

Listing 3 – Models\ProductService.cs

using System.Collections.Generic;
using System.Web.Mvc;

namespace MvcApplication1.Models
{
    public class ProductService : MvcApplication1.Models.IProductService
    {

        private ModelStateDictionary _modelState;
        private IProductRepository _repository;

        public ProductService(ModelStateDictionary modelState, IProductRepository repository)
        {
            _modelState = modelState;
            _repository = repository;
        }

        protected bool ValidateProduct(Product productToValidate)
        {
            if (productToValidate.Name.Trim().Length == 0)
                _modelState.AddModelError("Name", "Name is required.");
            if (productToValidate.Description.Trim().Length == 0)
                _modelState.AddModelError("Description", "Description is required.");
            if (productToValidate.UnitsInStock < 0)
                _modelState.AddModelError("UnitsInStock", "Units in stock cannot be less than zero.");
            return _modelState.IsValid;
        }

        public IEnumerable<Product> ListProducts()
        {
            return _repository.ListProducts();
        }

        public bool CreateProduct(Product productToCreate)
        {
            // Validation logic
            if (!ValidateProduct(productToCreate))
                return false;

            // Database logic
            try
            {
                _repository.CreateProduct(productToCreate);
            }
            catch
            {
                return false;
            }
            return true;
        }


    }

    public interface IProductService
    {
        bool CreateProduct(Product productToCreate);
        IEnumerable<Product> ListProducts();
    }
}

The Product controller has been updated in Listing 4 to use the service layer instead of the repository layer. The controller layer talks to the service layer. The service layer talks to the repository layer. Each layer has a separate responsibility.

Listing 4 – Controllers\ProductController.cs

Listing 4 – Controllers\ProductController.cs
using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class ProductController : Controller
    {
        private IProductService _service;

        public ProductController()
        {
            _service = new ProductService(this.ModelState, new ProductRepository());
        }

        public ProductController(IProductService service)
        {
            _service = service;
        }


        public ActionResult Index()
        {
            return View(_service.ListProducts());
        }


        //
        // GET: /Product/Create

        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Product/Create

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create([Bind(Exclude = "Id")] Product productToCreate)
        {
            if (!_service.CreateProduct(productToCreate))
                return View();
            return RedirectToAction("Index");
        }


    }
}

Notice that the product service is created in the product controller constructor. When the product service is created, the model state dictionary is passed to the service. The product service uses model state to pass validation error messages back to the controller.

Decoupling the Service Layer

We have failed to isolate the controller and service layers in one respect. The controller and service layers communicate through model state. In other words, the service layer has a dependency on a particular feature of the ASP.NET MVC framework.

We want to isolate the service layer from our controller layer as much as possible. In theory, we should be able to use the service layer with any type of application and not only an ASP.NET MVC application. For example, in the future, we might want to build a WPF front-end for our application. We should find a way to remove the dependency on ASP.NET MVC model state from our service layer.

In Listing 5, the service layer has been updated so that it no longer uses model state. Instead, it uses any class that implements the IValidationDictionary interface.

Listing 5 – Models\ProductService.cs (decoupled)

using System.Collections.Generic;

namespace MvcApplication1.Models
{
    public class ProductService : IProductService
    {

        private IValidationDictionary _validatonDictionary;
        private IProductRepository _repository;

        public ProductService(IValidationDictionary validationDictionary, IProductRepository repository)
        {
            _validatonDictionary = validationDictionary;
            _repository = repository;
        }

        protected bool ValidateProduct(Product productToValidate)
        {
            if (productToValidate.Name.Trim().Length == 0)
                _validatonDictionary.AddError("Name", "Name is required.");
            if (productToValidate.Description.Trim().Length == 0)
                _validatonDictionary.AddError("Description", "Description is required.");
            if (productToValidate.UnitsInStock < 0)
                _validatonDictionary.AddError("UnitsInStock", "Units in stock cannot be less than zero.");
            return _validatonDictionary.IsValid;
        }

        public IEnumerable<Product> ListProducts()
        {
            return _repository.ListProducts();
        }

        public bool CreateProduct(Product productToCreate)
        {
            // Validation logic
            if (!ValidateProduct(productToCreate))
                return false;

            // Database logic
            try
            {
                _repository.CreateProduct(productToCreate);
            }
            catch
            {
                return false;
            }
            return true;
        }


    }

    public interface IProductService
    {
        bool CreateProduct(Product productToCreate);
        System.Collections.Generic.IEnumerable<Product> ListProducts();
    }
}

The IValidationDictionary interface is defined in Listing 6. This simple interface has a single method and a single property.

Listing 6 – Models\IValidationDictionary.cs

namespace MvcApplication1.Models
{
    public interface IValidationDictionary
    {
        void AddError(string key, string errorMessage);
        bool IsValid { get; }
    }
}

The class in Listing 7, named the ModelStateWrapper class, implements the IValidationDictionary interface. You can instantiate the ModelStateWrapper class by passing a model state dictionary to the constructor.

Listing 7 – Models\ModelStateWrapper.cs

using System.Web.Mvc;

namespace MvcApplication1.Models
{
    public class ModelStateWrapper : IValidationDictionary
    {

        private ModelStateDictionary _modelState;

        public ModelStateWrapper(ModelStateDictionary modelState)
        {
            _modelState = modelState;
        }

        #region IValidationDictionary Members

        public void AddError(string key, string errorMessage)
        {
            _modelState.AddModelError(key, errorMessage);
        }

        public bool IsValid
        {
            get { return _modelState.IsValid; }
        }

        #endregion
    }
}

Finally, the updated controller in Listing 8 uses the ModelStateWrapper when creating the service layer in its constructor.

Listing 8 – Controllers\ProductController.cs

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class ProductController : Controller
    {
        private IProductService _service;

        public ProductController()
        {
            _service = new ProductService(new ModelStateWrapper(this.ModelState), new ProductRepository());
        }

        public ProductController(IProductService service)
        {
            _service = service;
        }


        public ActionResult Index()
        {
            return View(_service.ListProducts());
        }


        //
        // GET: /Product/Create

        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Product/Create

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create([Bind(Exclude = "Id")] Product productToCreate)
        {
            if (!_service.CreateProduct(productToCreate))
                return View();
            return RedirectToAction("Index");
        }


    }
}

Using the IValidationDictionary interface and the ModelStateWrapper class enables us to completely isolate our service layer from our controller layer. The service layer is no longer dependent on model state. You can pass any class that implements the IValidationDictionary interface to the service layer. For example, a WPF application might implement the IValidationDictionary interface with a simple collection class.

ASP.NET MVC 5 Internationalization · Date and Time

It would be nice if a web site can show times local to the region where the visitor is located instead of server location (web server, database, etc). For example, a user from Spain that is looking at their order summary on some web site expects that their order date and time 28/01/2014 14:32:26 to be a local (Spain) time, and not a web server time or database server time. Although it is not wrong to add a suffix denoting the region such as 28/01/2014 14:32:26 PST, it is much more readable for users to see times local to their region.

The .NET Framework has different types and methods that help deal with different time zones which can be quite complicated. The good news is that in general, time zones are not needed in order to display times based on the user’s location. It is simpler than you might think.

There are different ways of dealing with this problem. An easy and effective way is to store all times in the database as UTC (Coordinated Universal Time) and then adjust time (before display) based on where the user is located in the world. The most common .NET type is DateTime. ADateTime stores a date and optionally a time. It has a Kind property which determines if the value is one of three: local, UTC, or unspecified.

Another type is called DateTimeOffset. A DateTimeOffset stores a date and time relative to UTC. Additionally, it stores an offset from UTC as TimeSpan.

 

1
2
Console.WriteLine (DateTime.Now);         // 1/28/2014 2:53:50 PM
Console.WriteLine (DateTimeOffset.Now);   // 1/28/2014 2:53:50 PM -08:00

 

DateTime and DateTimeOffset differ in how they deal with time zones and in comparisons. For i18n, I prefer DateTimeOffset because it refers to a more precise point in time. Also, SQL Server 2008 and above support DateTimeOffset as a native data type.

How to capture the user’s time zone offset?

With the aid of the browser, the date time offset can be captured easily using javascript.

1
var timeZoneOffset = -new Date().getTimezoneOffset(); // In minutes.

The time zone offset value is also needed on the server side in order to adjust time values before displaying them to the end user. A good place to store this offset is in a cookie.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function cookieExists(name) {
    var nameToFind = name + "=";
    var cookies = document.cookie.split(';');
    for (var i = 0; i < cookies.length; i++) {
        if (cookies[i].trim().indexOf(nameToFind) === 0) return true;
    }
    return false;
}
if (!cookieExists("_timeZoneOffset")) {
    var now = new Date();
    var timeZoneOffset = -now.getTimezoneOffset();  // in minutes
    now.setTime(now.getTime() + 10*24*60*60*1000); // keep it for 10 days
    document.cookie = "_timeZoneOffset=" + timeZoneOffset.toString()
                  + ";expires=" + now.toGMTString() + ";path=/;" + document.cookie;
   
    // Uncomment the following line to force page refresh. 
    // window.location.reload();
    }

The previous javascript code should always be always executed, so it would be a good idea to put this code in a common place such as _Layout.cshtml

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!DOCTYPE HTML>
<html lang="@CultureHelper.GetCurrentNeutralCulture()" dir="@(CultureHelper.IsRightToLeft() ? " rtl"=rtl" = ="ltr" )"=)">
<head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewBag.Title - ASP.NET MVC Internationalization</title>
    @Styles.Render("~/Content/css" + (CultureHelper.IsRightToLeft() ? "-rtl" : ""))
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
        <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
        <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("ASP.NET MVC Internationalization", "Index", "Home", null, new { @class = "navbar-brand" })
            </div>
        <div class="navbar-collapse collapse">
        <ul class="nav navbar-nav">                   
                </ul>
                @Html.Partial("_LoginPartial")
            </div>
        </div>
    </div>
        <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>          
        </footer>
    </div>
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap" + (CultureHelper.IsRightToLeft() ? "-rtl" : ""))
    @RenderSection("scripts", required: false)
        <script type="text/javascript">
            function cookieExists(name) {
                var nameToFind = name + "=";
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    if (cookies[i].trim().indexOf(nameToFind) === 0) return true;
                }
                return false;
            }
            if (!cookieExists("_timeZoneOffset")) {
                var now = new Date();
                var timeZoneOffset = -now.getTimezoneOffset();  // in minutes
                now.setTime(now.getTime() + 10*24*60*60*1000); // keep it for 10 days
                document.cookie = "_timeZoneOffset=" + timeZoneOffset.toString() + ";expires=" + now.toGMTString() + ";path=/;" + document.cookie;
                @* Uncomment the following line to force page refresh.  *@
                // window.location.reload();
                }
    </script>
</body>
</html>

 

In order to convert a DateTime to the user local time, an extension method ToOffset is needed.ToOffset should accept the time zone offset value.

1
2
3
4
5
6
7
8
9
10
/// <summary>
/// Converts the value of the current DateTime object to the date and time specified by an offset value.
/// </summary>
/// <param name="dt" />DateTime value.</param>
/// <param name="offset" />The offset to convert the DateTime value to.</param>
/// <returns>DateTime value that is local to an offset.</returns>
public static DateTime ToOffset (this DateTime dt, TimeSpan offset)
{
    return dt.ToUniversalTime().Add(offset);
}

DateTimeOffset already provides a similar method, so there is no need to implement it.

Parse the time zone offset value from the cookie in the base controller, and store it somewhere so it can be used later on the server side.

 

1
2
3
4
5
6
7
8
9
10
11
// Parse TimeZoneOffset.
ViewBag.TimeZoneOffset = TimeSpan.FromMinutes(0); // Default offset (Utc) if cookie is missing.
var timeZoneCookie = Request.Cookies["_timeZoneOffset"];
if (timeZoneCookie != null) {
            
    double offsetMinutes = 0;
    if (double.TryParse(timeZoneCookie.Value, out offsetMinutes)) {
        // Store in ViewBag. You can use Session, TempData, or anything else.
        ViewBag.TimeZoneOffset = TimeSpan.FromMinutes(offsetMinutes);
    }
}

 

The following is a model that illustrates how the date and time display is affected by different time zones.

 

1
2
3
4
5
6
7
8
9
10
11
[HttpGet]
public ActionResult Index()
{
    // Sample data to show dates and times in different places in the world.
    var model = new Collection<DateTimeOffset> {
        DateTimeOffset.Parse("2014-04-04T20:30:00-7:00"),
        DateTimeOffset.Parse("2014-04-01T11:00:00-2:00"),
        DateTimeOffset.Parse("2014-04-02T00:00:00+2:00"),
    };
    return View(model);
}

 

I used DateTimeOffset for illustrative purpose only, DateTime would work just fine.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
@model IEnumerable<DateTimeOffset>
@using MvcInternationalization.Extensions
@{
    ViewBag.Title = "Date and Time";
    var culture = System.Threading.Thread.CurrentThread.CurrentUICulture.Name.ToLowerInvariant();
}
@helper selected(string c, string culture)
{
    if (c == culture)
    {
        @:checked="checked"
    }
}
 
@using(Html.BeginForm("SetCulture", "Home"))
{
    <fieldset>
        <legend>@Resources.ChooseYourLanguage</legend>
        <div class="control-group">
            <div class="controls">
                <label for="en-us">
                    <input name="culture" id="en-us" value="en-us" type="radio" @selected("en-us", culture) /> English
                </label>
            </div>
        </div>
        <div class="control-group">
            <div class="controls">
                <label for="es">
                    <input name="culture" id="es" value="es" type="radio" @selected("es", culture) /> Español
                </label>
            </div>
        </div>
        <div class="control-group">
            <div class="controls">
                <label for="ar">
                    <input name="culture" id="ar" value="ar" type="radio" @selected("ar", culture) /> العربية
                </label>
            </div>
        </div>
      
    </fieldset>
}
     <div>
         <table class="table table-bordered table-hover table-striped">
             <thead>
                 <tr>
                     <th>UTC</th>
                     <th>Server</th>
                     <th>Local <span style="color: lightgray;"> - Your browser: @ViewBag.TimeZoneOffset</span></th>
                 </tr>
             </thead>
             <tbody>
                 @foreach (DateTimeOffset dto in Model) {
                     <tr>
                         <td>@dto.ToUniversalTime().ToString("g")</td>
                         <td>@dto.ToLocalTime().ToString("g")</td> @* You might be surprised that this value is actually local to the machine currently running. *@
                         <td>@dto.ToOffset(ViewBag.TimeZoneOffset).ToString("g")  </td>
                     </tr>
                 }
             </tbody>
         </table>
     </div> 
    
    
 
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script type="text/javascript">
        (function ($) {
            $("input[type = 'radio']").click(function () {
                $(this).parents("form").submit(); // post form
            });           
            
        })(jQuery);
    </script>
}

original article at :http://afana.me/post/aspnet-mvc-internationalization-date-time.aspx

Attribute Routing in ASP.NET MVC 5

Why Attribute Routing?

For example, a socially enhanced e-commerce website could have the following routes:

  • {productId:int}/{productTitle}
    Mapped to ProductsController.Show(int id)
  • {username}
    Mapped to ProfilesController.Show(string username)
  • {username}/catalogs/{catalogId:int}/{catalogTitle}
    Mapped to CatalogsController.Show(string username, int catalogId)

(Don’t mind the specific syntax right now, we will touch on this later.)

In previous version of ASP.NET MVC, the rules would be set in the RouteConfig.cs file, and point to the actual controller actions, as such:

  • routes.MapRoute(
  •     name: “ProductPage”,
  •     url: “{productId}/{productTitle}”,
  •     defaults: new { controller = “Products”, action = “Show” },
  •     constraints: new { productId = “\\d+” }
  • );

When the route definitions are co-located with the actions, within the same source file rather than being declared on an external configuration class, it can make it easier to reason about the mapping between URIs and actions. The previous route definition would be set using the following, simple attribute:

  • [Route(“{productId:int}/{productTitle}”)]
  • public ActionResult Show(int productId) { … }

Enabling Attribute Routing

To enable attribute routing, call MapMvcAttributeRoutes during configuration.

  • public class RouteConfig
  • {
  •     public static void RegisterRoutes(RouteCollection routes)
  •     {
  •         routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);
  •         routes.MapMvcAttributeRoutes();
  •     }
  • }

You can also combine attribute routing with convention-based routing.

  • public static void RegisterRoutes(RouteCollection routes)
  • {
  •     routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);
  •     routes.MapMvcAttributeRoutes();
  •     routes.MapRoute(
  •         name: “Default”,
  •         url: “{controller}/{action}/{id}”,
  •         defaults: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional }
  •     );
  • }

Optional URI Parameters and Default Values

You can make a URI parameter optional by adding a question mark to the route parameter. You can also specify a default value by using the form parameter=value.

  • public class BooksController : Controller
  • {
  •     // eg: /books
  •     // eg: /books/1430210079
  •     [Route(“books/{isbn?}”)]
  •     public ActionResult View(string isbn)
  •     {
  •         if (!String.IsNullOrEmpty(isbn))
  •         {
  •             return View(“OneBook”, GetBook(isbn));
  •         }
  •         return View(“AllBooks”, GetBooks());
  •     }
  •     // eg: /books/lang
  •     // eg: /books/lang/en
  •     // eg: /books/lang/he
  •     [Route(“books/lang/{lang=en}”)]
  •     public ActionResult ViewByLanguage(string lang)
  •     {
  •         return View(“OneBook”, GetBooksByLanguage(lang));
  •     }
  • }

In this example, both /books and /books/1430210079 will route to the “View” action, the former will result with listing all books, and the latter will list the specific book. Both /books/lang and /books/lang/en will be treated the same.

Route Prefixes

Often, the routes in a controller all start with the same prefix. For example:

  • public class ReviewsController : Controller
  • {
  •     // eg: /reviews
  •     [Route(“reviews”)]
  •     public ActionResult Index() { … }
  •     // eg: /reviews/5
  •     [Route(“reviews/{reviewId}”)]
  •     public ActionResult Show(int reviewId) { … }
  •     // eg: /reviews/5/edit
  •     [Route(“reviews/{reviewId}/edit”)]
  •     public ActionResult Edit(int reviewId) { … }
  • }

You can set a common prefix for an entire controller by using the [RoutePrefix] attribute:

  • [RoutePrefix(“reviews”)]
  • public class ReviewsController : Controller
  • {
  •     // eg.: /reviews
  •     [Route]
  •     public ActionResult Index() { … }
  •     // eg.: /reviews/5
  •     [Route(“{reviewId}”)]
  •     public ActionResult Show(int reviewId) { … }
  •     // eg.: /reviews/5/edit
  •     [Route(“{reviewId}/edit”)]
  •     public ActionResult Edit(int reviewId) { … }
  • }

Use a tilde (~) on the method attribute to override the route prefix if needed:

  • [RoutePrefix(“reviews”)]
  • public class ReviewsController : Controller
  • {
  •     // eg.: /spotlight-review
  •     [Route(“~/spotlight-review”)]
  •     public ActionResult ShowSpotlight() { … }
  •     …
  • }

Default Route

You can also apply the [Route] attribute on the controller level, capturing the action as a parameter. That route would then be applied on all actions in the controller, unless a specific [Route] has been defined on a specific action, overriding the default set on the controller.

  • [RoutePrefix(“promotions”)]
  • [Route(“{action=index}”)]
  • public class ReviewsController : Controller
  • {
  •     // eg.: /promotions
  •     public ActionResult Index() { … }
  •     // eg.: /promotions/archive
  •     public ActionResult Archive() { … }
  •     // eg.: /promotions/new
  •     public ActionResult New() { … }
  •     // eg.: /promotions/edit/5
  •     [Route(“edit/{promoId:int}”)]
  •     public ActionResult Edit(int promoId) { … }
  • }

Route Constraints

Route constraints let you restrict how the parameters in the route template are matched. The general syntax is{parameter:constraint}. For example:

  • // eg: /users/5
  • [Route(“users/{id:int}”]
  • public ActionResult GetUserById(int id) { … }
  • // eg: users/ken
  • [Route(“users/{name}”]
  • public ActionResult GetUserByName(string name) { … }

Here, the first route will only be selected if the “id” segment of the URI is an integer. Otherwise, the second route will be chosen.

The following table lists the constraints that are supported.

 

Constraint Description Example
alpha Matches uppercase or lowercase Latin alphabet characters (a-z, A-Z) {x:alpha}
bool Matches a Boolean value. {x:bool}
datetime Matches a DateTime value. {x:datetime}
decimal Matches a decimal value. {x:decimal}
double Matches a 64-bit floating-point value. {x:double}
float Matches a 32-bit floating-point value. {x:float}
guid Matches a GUID value. {x:guid}
int Matches a 32-bit integer value. {x:int}
length Matches a string with the specified length or within a specified range of lengths. {x:length(6)}
{x:length(1,20)}
long Matches a 64-bit integer value. {x:long}
max Matches an integer with a maximum value. {x:max(10)}
maxlength Matches a string with a maximum length. {x:maxlength(10)}
min Matches an integer with a minimum value. {x:min(10)}
minlength Matches a string with a minimum length. {x:minlength(10)}
range Matches an integer within a range of values. {x:range(10,50)}
regex Matches a regular expression. {x:regex(^\d{3}-\d{3}-\d{4}$)}

Notice that some of the constraints, such as “min”, take arguments in parentheses.

You can apply multiple constraints to a parameter, separated by a colon, for example:

  • // eg: /users/5
    // but not /users/10000000000 because it is larger than int.MaxValue,
    // and not /users/0 because of the min(1) constraint.
  • [Route(“users/{id:int:min(1)}”)]
  • public ActionResult GetUserById(int id) { … }

 

Specifying that a parameter is Optional (via the ‘?’ modifier) should be done after inline constraints:

 

  • // eg: /greetings/bye
    // and /greetings because of the Optional modifier,
    // but not /greetings/see-you-tomorrow because of the maxlength(3) constraint.
    [Route(“greetings/{message:maxlength(3)?}”)]
  • public ActionResult Greet(string message) { … }
Custom Route Constraints

You can create custom route constraints by implementing the IRouteConstraint interface. For example, the following constraint restricts a parameter to set of valid values:

  • public class ValuesConstraint : IRouteConstraint
  • {
  •     private readonly string[] validOptions;
  •     public ValuesConstraint(string options)
  •     {
  •         validOptions = options.Split(‘|’);
  •     }
  •     public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
  •     {
  •         object value;
  •         if (values.TryGetValue(parameterName, out value) && value != null)
  •         {
  •             return validOptions.Contains(value.ToString(), StringComparer.OrdinalIgnoreCase);
  •         }
  •         return false;
  •     }
  • }

The following code shows how to register the constraint:

  • public class RouteConfig
  • {
  •     public static void RegisterRoutes(RouteCollection routes)
  •     {
  •         routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);
  •         var constraintsResolver = new DefaultInlineConstraintResolver();
  •         constraintsResolver.ConstraintMap.Add(“values”, typeof(ValuesConstraint));
  •         routes.MapMvcAttributeRoutes(constraintsResolver);
  •     }
  • }

Now you can apply the constraint in your routes:

  • public class TemperatureController : Controller
  • {
  •     // eg: temp/celsius and /temp/fahrenheit but not /temp/kelvin
  •     [Route(“temp/{scale:values(celsius|fahrenheit)}”)]
  •     public ActionResult Show(string scale)
  •     {
  •         return Content(“scale is ” + scale);
  •     }
  • }

Route Names

You can specify a name for a route, in order to easily allow URI generation for it. For example, for the following route:

  • [Route(“menu”, Name = “mainmenu”)]
  • public ActionResult MainMenu() { … }

you could generate a link using Url.RouteUrl:

  • <a href=”@Url.RouteUrl(“mainmenu”)”>Main menu</a>

Areas

You can define that a controller belongs to an area by using the [RouteArea] attribute. When doing so, you can safely remove the AreaRegistration class for that area.

  • [RouteArea(“Admin”)]
  • [RoutePrefix(“menu”)]
  • [Route(“{action}”)]
  • public class MenuController : Controller
  • {
  •     // eg: /admin/menu/login
  •     public ActionResult Login() { … }
  •     // eg: /admin/menu/show-options
  •     [Route(“show-options”)]
  •     public ActionResult Options() { … }
  •     // eg: /stats
  •     [Route(“~/stats”)]
  •     public ActionResult Stats() { … }
  • }

With this controller, the following link generation call will result with the string “/Admin/menu/show-options

  • Url.Action(“Options”, “Menu”, new { Area = “Admin” })

You can set up a custom prefix for the area that defer from the area name, by using the AreaPrefix named parameter, for example:

  • [RouteArea(“BackOffice”, AreaPrefix = “back-office”)]

If you are using both Areas with route attributes, and areas with convention based routes (set by an AreaRegistration class), then you need to make sure that area registration happen after MVC attribute routes are configured, however before the default convention-based route is set. The reason is that route registration should be ordered from the most specific (attributes) through more general (area registration) to the mist generic (the default route) to avoid generic routes from “hiding” more specific routes by matching incoming requests too early in the pipeline.

Example:

  • public static void RegisterRoutes(RouteCollection routes)
  • {
  •     routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);
  •     routes.MapMvcAttributeRoutes();
  •     AreaRegistration.RegisterAllAreas();
  •     routes.MapRoute(
  •         name: “Default”,
  •         url: “{controller}/{action}/{id}”,
  •         defaults: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional }
  •     );
  • }
  • taken from:http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx

Using Bootstrap Tooltips to display jQuery Validation error messages

Using Bootstrap Tooltips to display jQuery Validation error messages

I love jQuery Validation. I was recently putting together a screen which had a lot of different bits of validation going on. And the default jQuery Validation approach of displaying the validation messages next to the element being validated wasn’t working for me. That is to say, because of the amount of elements on the form, the appearance of validation messages was really making a mess of the presentation. So what to do?

<!DOCTYPE 2014-01-03_1355html>
<html lang=”en”>
<head>
<meta charset=”utf-8″ />
<link href=”//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css” rel=”stylesheet”>
<style>
form { padding: 10px; }
.error { border: 1px solid #b94a48!important; background-color: #fee!important; }
</style>
</head>
<body>
<form>
<div class=”row”>
<label for=”RequiredDateDemo”>A date is required (eg “15 June 2012”):</label>
<input
data-msg-date=”The field RequiredDateDemo must be a date.”
data-msg-required=”The RequiredDateDemo field is required.”
data-rule-date=”true”
data-rule-required=”true”
id=”RequiredDateDemo” name=”RequiredDateDemo” type=”text” value=”” />
</div>
<div class=”row”>
<label for=”StringLengthAndRequiredDemo”>A string is required between 5 and 10 characters long:</label>
<input
data-msg-maxlength=”The field StringLengthAndRequiredDemo must be a string with a minimum length of 5 and a maximum length of 10.”
data-msg-minlength=”The field StringLengthAndRequiredDemo must be a string with a minimum length of 5 and a maximum length of 10.”
data-msg-required=”The StringLengthAndRequiredDemo field is required.”
data-rule-maxlength=”10″
data-rule-minlength=”5″
data-rule-required=”true”
id=”StringLengthAndRequiredDemo” name=”StringLengthAndRequiredDemo” type=”text” value=”” />
</div>
<div class=”row”>
<label for=”RangeAndNumberDemo”>Must be a number between -20 and 40:</label>
<input
data-msg-number=”The field RangeAndNumberDemo must be a number.”
data-msg-range=”The field RangeAndNumberDemo must be between -20 and 40.”
data-rule-number=”true”
data-rule-range=”[-20,40]”
id=”RangeAndNumberDemo” name=”RangeAndNumberDemo” type=”text” value=”-21″ />
</div>
<div class=”row”>
<label for=”RangeAndNumberDemo”>An option must be selected:</label>
<select
data-msg-required=”The DropDownRequiredDemo field is required.”
data-rule-required=”true”
id=”DropDownRequiredDemo” name=”DropDownRequiredDemo”>
<option value=””>Please select</option>
<option value=”An Option”>An Option</option>
</select>
</div>
<div class=”row”>
<button type=”submit”>Validate</button>
</div>
</form>
<script src=”//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.js” type=”text/javascript”></script>
<script src=”//ajax.aspnetcdn.com/ajax/jQuery.validate/1.11.1/jquery.validate.js” type=”text/javascript”></script>
<script src=”//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js”></script>
<script type=”text/javascript”>
$(“form”).validate({
showErrors: function(errorMap, errorList) {
// Clean up any tooltips for valid elements
$.each(this.validElements(), function (index, element) {
var $element = $(element);
$element.data(“title”, “”) // Clear the title – there is no error associated anymore
.removeClass(“error”)
.tooltip(“destroy”);
});
// Create new tooltips for invalid elements
$.each(errorList, function (index, error) {
var $element = $(error.element);
$element.tooltip(“destroy”) // Destroy any pre-existing tooltip so we can repopulate with new tooltip content
.data(“title”, error.message)
.addClass(“error”)
.tooltip(); // Create a new tooltip based on the error messsage we just set in the title
});
},
submitHandler: function(form) {
alert(“This is a valid form!”);
}
});
</script>
</body>
</html>

ASP.Net MVC Validation Using Fluent Validation

This article explains how to implement ASP.NET MVC validation using Fluent Validation. Fluent validation is a small validation library for .NET that uses a Fluent interface and lambda expressions for building validation rules for your business objects.  Fluent validation is one way of setting up dedicated validator objects, that you would use when you want to treat validation logic as separate from business logic. The Aspect-Oriented Programming (AOP) paradigm enables separation of cross-cutting concerns within a system, and validation is one such concern. Separating validation helps clean up your domain code and make it more cohesive, as well as giving you a single place to look for validation logic.

I create a Customer model (Customer class under Models folder) that has two properties, one is “Email” and another is “Name” as in the following code snippet:

namespace MvcValidation.Models

{

    public class Customer

    {

        public string Name { get; set; }

        public string Email { get; set; }

    }

}

Now I install the Fluent validation Nuget package in the application so I can use Fluent validation rules.

Figure 1.1 Install FluentValidation NuGet package

After that I create a validator class for the Customer model under the “Validators” folder but you can create it anywhere in an application for validation rules on Customer properties. I used two rules, one is not empty and another validates an email address.

using FluentValidation;

using MvcValidation.Models;

 

namespace MvcValidation.Validators

{

    public class CustomerValidator : AbstractValidator<Customer>

    {

        public CustomerValidator()

        {

            RuleFor(x => x.Name).NotEmpty().WithMessage(“Name is required”);

            RuleFor(x => x.Email).NotEmpty().WithMessage(“Email is required”);

            RuleFor(x => x.Email).EmailAddress().WithMessage(“Email is not valid”);               

        }

    }

}

After that, you need to create a controller’s action methods; these render views on the UI and binds a model with the view. So let’s create a controller with two action methods; these handle both request types (GET and POST) respectively.

using System.Web.Mvc;

using FluentValidation.Results;

using MvcValidation.Models;

using MvcValidation.Validators;

 

namespace MvcValidation.Controllers

{

    public class CustomerController : Controller

    {

        public ActionResult Index()

        {

            return View();

        }

        [AcceptVerbs(HttpVerbs.Post)]

        public ActionResult Index(Customer model)

        {

            CustomerValidator validator = new CustomerValidator();

            ValidationResult result = validator.Validate(model);

            if (result.IsValid)

            {

                ViewBag.Name = model.Name;

                ViewBag.Email = model.Email;

            }

            else

            {

                foreach (ValidationFailure failer in result.Errors)

                {

                    ModelState.AddModelError(failer.PropertyName, failer.ErrorMessage);

                }               

            }

            return View(model);

        }

    }

}

Thereafter I create a view (Index.cshtml) for user input under the Customer folder.

@model MvcValidation.Models.Customer

@{

    ViewBag.Title = “Index”;

}

@if (ViewData.ModelState.IsValid)

{

    <b>Name : @ViewBag.Name<br />

        Email : @ViewBag.Email

    </b>       

}

@using (Html.BeginForm())

{    

    <fieldset>

        <legend>Customer</legend>

        <div class=”editor-label”>

            @Html.LabelFor(model => model.Name)

        </div>

        <div class=”editor-field”>

            @Html.EditorFor(model => model.Name)

            @Html.ValidationMessageFor(model => model.Name)

        </div>

        <div class=”editor-label”>

            @Html.LabelFor(model => model.Email)

        </div>

        <div class=”editor-field”>

            @Html.EditorFor(model => model.Email)

            @Html.ValidationMessageFor(model => model.Email)

        </div>

        <p>

            <input type=”submit” value=”Create” />

        </p>

    </fieldset>

}

@section Scripts {

    @Scripts.Render(“~/bundles/jqueryval”)

}


Let’s run the application and test the following scenario:

1. When all fields are empty:

Figure 1.2: Validation Message when both fields are empty

2. When the Name field is empty but Email is not valid:

Figure 1.3 : Validation Message when Email is not valid

3. When both fields are valid:

Figure 1.4 All fields are valid