Best asp.net-mvc-3 questions in January 2012

13 votes

I am building a MVC 3 application where the users may not be in the same time zone, so my intent was to store everything in UTC and convert from UTC to local time in the views and localtime to UTC on submissions.

Doing some browsing though there doesn't seem to be a lot of good solutions to this. To be honest, I sort of expected an attribute to be available to auto convert UTC time into local time at least, but it seems not to exist.

I feel like just trying to be diligent about manually converting every input to UTC and manually converting every view to local time display will be very error prone and lead to difficult to detect bugs where the time is not converted to or from.

Any suggestions on how to deal with this as a general strategy?

EDIT Everyone seems very stuck on the "how do I get the client timezone" piece, which as I mention in one of the comments is not my concern. I am fine with a user setting that determines their timezone, so assume I already know what the client time zone is...that doesn't address my problem.

Right now, on each view when I render a date, I would need to call a method to render it in the local time zone from utc. Every time I send a date for submission to the server I need to convert it from the local timezone to UTC. If I forget to do this there will be problems...either a submitted date will be wrong or client side reports and filters will be wrong.

What I was hoping existed was a more automated method, especially since the view model is strongly typed in MVC 3 I was hoping for sum magic to be able to at least automatically render in a time zone, if not handle the submission, just like the date format or range can be controlled by an attribute.

So like

[DateRange]
Public DateTime MyDate

I could have something like

[ConvertToUTC(offset)]
Public DateTime MyDate

Anyway, I guess it look like my only approach would be to write a custom data annotation to render it in a time zone, and a override on the MVC 3 model binder so incoming dates are converted unless I want to wrap ever date in a method call. So unless anyone has further comments or suggestions it will be one of those two options, I'm just surprised something doesn't exist already to do this.

If I do implement a solution I will be sure to post it.

Edit 2 Something like This http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx for MVC 3 views and view models is what I am looking for.

Final Edit I marked epignosisx answer as correct, but also have a few comments to add. I found something similar here: http://dalldorf.com/blog/2011/06/mvc3-timezones-1/ With an implementation of getting the timezone from the client by placing it in the cookie for people that want that in part 2 (link below since the link on the first part of the article to part 2 doesn't work) http://dalldorf.com/blog/2011/09/mvc3-timezones-2/

Its important to note with these approaches that you MUST you Editfor and Displayfor instead of things like TextForFor as only EditFor and DisplayFor make use of the metadata providers used to tell MVC how to display the property of that type on the model. If you access the model values directly in the view (@Model.MyDate) no conversion will take place.

You could handle the problem of converting UTC to user local time by using website-wide DisplayTemplate for DateTime.

From your Views you would use @Html.DisplayFor(n => n.MyDateTimeProperty)

The second problem is tougher to tackle. To convert from user local time to UTC you could override the DefaultModelBinder. Specifically the method SetProperty. Here is a naive implementation that demonstrates the point. It only applies for DateTime but could easily be extended to DateTime?. Then set it up as your Default binder in the Global.asax

public class MyDefaultModelBinder : DefaultModelBinder
{
    protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, object value)
    {
        //special case for DateTime
        if(propertyDescriptor.PropertyType == typeof(DateTime))
        {
            if (propertyDescriptor.IsReadOnly)
            {
                return;
            }

            try
            {
                if(value != null)
                {
                    DateTime dt = (DateTime)value;
                    propertyDescriptor.SetValue(bindingContext.Model, dt.ToUniversalTime());
                }
            }
            catch (Exception ex)
            {
                string modelStateKey = CreateSubPropertyName(bindingContext.ModelName, propertyDescriptor.Name);
                bindingContext.ModelState.AddModelError(modelStateKey, ex);
            }
        }
        else
        {
            //handles all other types
            base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);
        }
    }
}

comment between else and {

10 votes

I just started using Razor instead of the WebForms-ViewEngine. Now in my Razor-View i have something like this:

@{
  int i = 42;
  string text;
  if (i == 42)
  {
    text = "i is 42!";
  }
  else //i is not 42 //<- Error here
  {
    text = "i is something else";
  }
}

I get a warning and at runtime it get an exception in the else line:

Expected a "{" but found a "/". Block statements must be enclosed in "{" and "}". You cannot use single-statement control-flow statements in CSHTML pages.

Apparently the compiler doesn't like comments between the else and the {. I also tried commenting with @* and /*, which gave similar error-messages.

Is there anyway to make a comment in razor like I want it?


Disclaimer:

Yes i know i could fix it simply like this:

@{
  int i = 42;
  string text;
  if (i == 42)
  {
    text = "i is 42!";
  }
  else
  { //i is not 42
    text = "i is something else";
  }
}

However it doesn't fit our coding guidelines and having the comment on the same line makes my intentions more clear.

That's how the Razor parser is built. You could always submit a bug/feature request on MS connect if you don't like the way it is and hope that people will vote for it and it will be fixed/implemented in a future version of the parser. Personally I wouldn't because I don't care (see below why).

This being said, why care? I mean you are not supposed to write code in a Razor page. A Razor page is intended to be used as a view. In ASP.NET MVC a view is used to display some information from the view model that is passed to it from the controller action. Markup primary, mixed with HTML helpers and displaying information from the view model. But C# code is a no no. So what you call code and what you have shown in your question has strictly nothing to do in a Razor view.

Do asynchronous operations in ASP.NET MVC use a thread from ThreadPool on .NET 4

8 votes

I have too many misunderstandings in my mind about asynchronous operations on ASP.NET MVC.

I always hear this sentence: Application can scale better if operations run asynchronously

And I heard this kind of sentences a lot as well: if you have a huge volume of traffic, you may be better off not performing your queries asynchronously - consuming 2 extra threads to service one request takes resources away from other incoming requests.

I think those two sentences are inconsistent.

I do not have much information about how threadpool works on ASP.NET but I know that threadpool has a limited size for threads. So, the second sentence has to be related to this issue.

And I would like to know if asynchronous operations in ASP.NET MVC uses a thread from ThreadPool on .NET 4?

For example, when we implement a AsyncController, how does the app structures? If I get huge traffic, is it a good idea to implement AsyncController?

Is there anybody out there who can take this black curtain away in front of my eyes and explain me the deal about asynchrony on ASP.NET MVC 3 (NET 4)?

Edit:

I have read this below document nearly hundreds of times and I understand the main deal but still I have confusion because there are too much inconsistent comment out there.

Using an Asynchronous Controller in ASP.NET MVC

Edit:

Let's assume I have controller action like below (not an implementation of AsyncController though):

public ViewResult Index() { 

    Task.Factory.StartNew(() => { 
        //Do an advanced looging here which takes a while
    });

    return View();
}

As you see here, I fire an operation and forget about it. Then, I return immediately without waiting it be completed.

In this case, does this have to use a thread from threadpool? If so, after it completes, what happens to that thread? Does GC comes in and clean up just after it completes?

Edit:

For the @Darin's answer, here is a sample of async code which talks to database:

public class FooController : AsyncController {

    //EF 4.2 DbContext instance
    MyContext _context = new MyContext();

    public void IndexAsync() { 

        AsyncManager.OutstandingOperations.Increment(3);

        Task<IEnumerable<Foo>>.Factory.StartNew(() => { 

           return 
                _context.Foos;
        }).ContinueWith(t => {

            AsyncManager.Parameters["foos"] = t.Result;
            AsyncManager.OutstandingOperations.Decrement();
        });

        Task<IEnumerable<Bars>>.Factory.StartNew(() => { 

           return 
                _context.Bars;
        }).ContinueWith(t => {

            AsyncManager.Parameters["bars"] = t.Result;
            AsyncManager.OutstandingOperations.Decrement();
        });

        Task<IEnumerable<FooBar>>.Factory.StartNew(() => { 

           return 
                _context.FooBars;
        }).ContinueWith(t => {

            AsyncManager.Parameters["foobars"] = t.Result;
            AsyncManager.OutstandingOperations.Decrement();
        });
    }

    public ViewResult IndexCompleted(
        IEnumerable<Foo> foos, 
        IEnumerable<Bar> bars,
        IEnumerable<FooBar> foobars) {

        //Do the regular stuff and return

    }
}

Here's an excellent article I would recommend you reading to better understand asynchronous processing in ASP.NET (which is what asynchronous controllers basically represent).

Let's first consider a standard synchronous action:

public ActionResult Index()
{
    // some processing
    return View();
}

When a request is made to this action a thread is drawn from the thread pool and the body of this action is executed on this thread. So if the processing inside this action is slow you are blocking this thread for the entire processing, so this thread cannot be reused to process other requests. At the end of the request execution the thread is returned to the thread pool.

Now let's take an example of the asynchronous pattern

public void IndexAsync()
{
    // perform some processing
}

public ActionResult IndexCompleted(object result)
{
    return View();
}

When a request is sent to the Index action, a thread is drawn from the thread pool and the body of the IndexAsync method is executed. Once the body of this method finishes executing, the thread is returned to the thread pool. Then using the standard AsyncManager.OutstandingOperations once you signal the completion of the async operation, another thread is drawn from the thread pool and the body of the IndexCompleted action is executed on it and the result rendered to the client.

So what we can see in this pattern is that a single client HTTP request could be executed by two different threads.

Now the interesting part happens inside the IndexAsync method. If you have a blocking operation inside it, you are totally wasting the whole purpose of the asynchronous controllers because you are blocking the worked thread (remember that the body of this action is executed on a thread drawn from the thread pool).

So when can we take real advantage of asynchronous controllers you might ask?

IMHO we can gain most when we have I/O intensive operations (such as database and network calls to remote services). If you have a CPU intensive operation, asynchronous actions won't bring you much benefit.

So why can we gain benefit from I/O intensive operations? Because we could use I/O Completion Ports. IOCP are extremely powerful because you do not consume any thread or resource on the server during the execution of the entire operation.

How they work?

Suppose that we want to download the contents of a remote web page using the WebClient.DownloadStringAsync method. You call this method which will register an IOCP within the operating system and return immediately. During the processing of the entire request, no threads are consumed on your server. Everything happens on the remote server. This could take lots of time but you don't care as you are not jeopardizing your worker threads. Once a response is received the IOCP is signaled, a thread is drawn from the thread pool and the callback is executed on this thread. But as you can see during the entire processing we have not monopolized any thread.

Same stands true with methods such as FileStream.BeginRead, SqlCommand.BeginExecute, ...

What about parallelizing multiple database calls? Suppose that you had a synchronous controller action in which you performed 4 blocking database calls in sequence. It's easy to calculate that if each database call takes 200ms your controller action will take roughly 800ms to execute.

If you don't need to run those calls sequentially would parallelizing them improve performance?

That's the big question which is not easy to answer. Maybe yes, maybe not. It will entirely depend on how you implement those database calls. If you use async controllers and I/O Completion ports as discussed previously you will boost the performance of this controller action and on other actions as well as you won't be monopolizing worker threads.

On the other hand if you implement them poorly (with a blocking database call performed on a thread from the thread pool), you will basically lower the total time of execution of this action to roughly 200ms but you would have consumed 4 worker threads so you might have degraded the performance of other requests which might become starving because of missing threads in the pool to process them.

So it is very difficult and you don't feel ready to perform extensive tests on your application do not implement asynchronous controllers as chances are that you will do more damage than benefit. Implement them only if you have a reason to do so: for example you have identified that standard synchronous controller actions are a bottleneck to your application (after performing extensive load tests and measurements of course).

Now let's consider your example:

public ViewResult Index() { 

    Task.Factory.StartNew(() => { 
        //Do an advanced looging here which takes a while
    });

    return View();
}

When a request is received for the Index action a thread is drawn from the thread pool to executed its body. Bit its body only schedules a new task using TPL. So the action execution ends and the thread is returned to the thread pool. Except that, TPL uses threads from the thread pool to perform their processing. So even if the original thread was returned to the thread pool, you have drawn another thread from this pool to execute the body of the task. So you have jeopardized 2 threads from your precious pool.

Now let's consider the following:

public ViewResult Index() { 

    new Thread(() => { 
        //Do an advanced looging here which takes a while
    }).Start();

    return View();
}

In this case we are manually spawning a thread. In this case the execution of the body of the Index action might take slightly longer (because spawning a new thread is more expensive than drawing one from an existing pool). But the execution of the advanced logging operation will be done on a thread which is not part of the pool. So we are not jeopardizing threads from the pool which remain free for serving another requests.

Is is bad practice to write a method that does nothing except throw an exception?

5 votes

The title pretty much says it but here is some background:

I have an ASP.Net MVC application where I need to check a list of file paths for existence. If any of the paths do not exist then an error is returned.

Presently, I have a base controller where the OnException event is implemented. Here, any unhanded exceptions are dealt with and an error page is returned to the user with the exception's message.

The simplest way for me to do the above check is to write a method that checks each path for existence and if any of them fail, I simply throw (and log) an exception. This exception is then handled by the base controller and the appropriate message is returned to the user.

My problem is that doing this feels like bad practice. I am writing a method that returns void and its only purpose is to throw an exception in the rare case that one of the paths does not exist, in most cases it does nothing. Is this a bad idea?

There is nothing wrong with that.

The .NET framework does this too: for example, CancellationToken has a method ThrowIfCancellationRequested which does nothing but throw or not throw depending on some condition.

Another example: Dispatcher's VerifyAccess method, which checks if the caller is on the same thread as the control is supposed to be accessed on, and throws if not.

How does Internationalization in ASP.NET work?

4 votes

I wonder if it is possible to make your application multilingual by simply creating resource files for every required language
Like

Resource.resx for English      //string abc(name)=xyz(value)
Resource.zh.resx for Chinese   //string abc(name)=zh(value)

And simply placing a string in your view(single view only that support multilingual) string like

@appName.Resource.abc

and

<globalization culture="en-GB" uiCulture="auto:en-GB" />

in Web.Config

Now my question is

Is this enough to get started with multilingual sites i.e if I change the preferred language in my browser to Chinese the content of page is changing? But how does this work?

What I know is

  • Browser returns preferred culture list

Need to know - How mapping to particular resource file take place. I mean both resource files (Resource.resx and Resource.zh.resx) in my example have an 'abc' property with different value. How does asp.net figure out which value to render? Is there any naming convention?

At run time, ASP.NET uses the resource file that is the best match for the setting of the CurrentUICulture property. The UI culture for the thread is set according to the UI culture of the page. For example, if the current UI culture is Spanish, ASP.NET uses the compiled version of the WebResources.es.resx file. If there is no match for the current UI culture, ASP.NET uses resource fallback. It starts by searching for resources for a specific culture. If those are not available, it searches for the resources for a neutral culture. If these are not found, ASP.NET loads the default resource file. In this example, the default resource file is WebResource.resx.

Ref: ASP.NET Web Page Resources Overview

Microsoft .NET Internationalization

Data passing between the ASP.NET MVC 3 view hierarchy

4 votes

Motivation

I want to be able to build up a tree-like object hierarchy in Javascript that corresponds to the ASP.NET MVC 3 Razor views on a page. The plan is to have a one-to-one correspondence between a Razor view and a Javascript file where its logic is defined (in form of a constructor function that will accept some initialization parameters). Simple example could look like this :

  • _Layout.cshtml <-> Global.js
    • SplitterPane.cshtml <-> SplitterPane.js
      • Grid.cshtml <-> Grid.js
      • Tree.cshtml <-> Tree.js

I would use the constructors to build a hierarchy, e.g.

var page = new Global(global_options);
var splitter = new SplitterPane(splitter_options);
var grid = new Grid(grid_options);
var tree = new Tree(tree_options);

page.addChild(splitter);
splitter.addChild(grid);
splitter.addChild(tree);

All of this code should be of course constructed automatically in the context of the root (layout) view from metadata collected from the partial views. Metadata provided by a view contains the options necessary to initialize its Javascript object and the Javascript files to load.

Problem

Unlike WebForms, MVC views do not have any natural hierarchy I would know of and passing information between a view and its partial (sub)views seems rather tricky. In case of using helpers like Html.Action in the view the whole processing of a "subview" happens independently, so they don't even share the Page object. What I need is some kind of a central place where the views can deposit their metadata as they are rendered so that it can be used in the layout view to combine and output the complete script.

Solution ?

One way I could think of was to use the HttpContext.Current.Items to temporarily store a collection of view metadata objects. All the views would deposit the metadata there and layout view would use it. The order of execution seems to match my expectation, however I'm still unable to reconstruct the tree hierarchy of views. To be able to do that, I would need to use a stack where a view would register on start of its rendering and unregister on the end, so that the parent can be found on the top.

  1. Is there a way to have some pre-/post-render hooks where I could put this logic ?
  2. Is this even a good idea in the first place ?
  3. Is there a completely different solution that I don't see ?

You could write a custom view engine:

public class MyViewEngine : RazorViewEngine
{
    private class MyRazorView : RazorView
    {
        public MyRazorView(ControllerContext controllerContext, string viewPath, string layoutPath, bool runViewStartPages, IEnumerable<string> viewStartFileExtensions, IViewPageActivator viewPageActivator)
            : base(controllerContext, viewPath, layoutPath, runViewStartPages, viewStartFileExtensions)
        {
        }

        protected override void RenderView(ViewContext viewContext, System.IO.TextWriter writer, object instance)
        {
            var stack = viewContext.HttpContext.Items["stack"] as Stack<string>;
            if (stack == null)
            {
                stack = new Stack<string>();
                viewContext.HttpContext.Items["stack"] = stack;
            }
            // depending on the required logic you could
            // use a stack of some model and push some additional
            // information about the view (see below)
            stack.Push(this.ViewPath);
            base.RenderView(viewContext, writer, instance);
        }
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        return new MyRazorView(controllerContext, viewPath, masterPath, true, base.FileExtensions, base.ViewPageActivator);
    }

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        return new MyRazorView(controllerContext, partialPath, null, false, base.FileExtensions, base.ViewPageActivator);
    }
}

that you would register in Application_Start:

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new MyViewEngine());

and now you can write a custom HTML helper that will pick the stack that was stored in the HttpContext and do something useful:

public static class HtmlExtensions
{
    public static IHtmlString BuildTree(this HtmlHelper htmlHelper)
    {
        var stack = htmlHelper.ViewContext.HttpContext.Items["stack"] as Stack<string>;
        if (stack == null)
        {
            return MvcHtmlString.Empty;
        }


        // TODO: your custom logic to build the tree
        ...
    }
}

and in the end of your _Layout:

    ...
    <script type="text/javascript">
        @Html.BuildTree()
    </script>
</body>

Why can't I use server controls in ASP.net MVC?

4 votes

I'm getting ready to be responsible for leading the development of a small ASP.net MVC application. This is my first time creating an MVC application, so I am excited!

I've carefully read over the documentation and I feel like I have the general idea of how MVC works. However, if I understand correctly, server controls (like GridView, for instance) are not part of MVC.

My question is: Why? At my development shop, I'm so used to using controls like GridView and the MS Chart Controls that I'm almost at a complete loss as to developing without them. It seems almost like starting over.

Why are the server controls unavailable? How does Microsoft expect me to work without them? What are the alternatives?

My question is: Why?

Because most of them depend on things like ViewState and the Postback models which are part of the classic WebForms model and no longer exist in ASP.NET MVC. Those server side controls rely on events that will perform postbacks to the server persisting their state in hidden fields (ViewState). In ASP.NET MVC you no longer work with events such as Button1_Click. In ASP.NET MVC you work with a Model, a Controller and View. The Controller is responsible for receiving user requests, querying the Model, translating the results into a view model and passing this view model to the View whose responsibility is to display it under some form.

In ASP.NET MVC there are HTML helpers that could be used to generate some reusable HTML fragments between views. You may take a look for example at the Telerik ASP.NET MVC suite of such helpers. They call them controls but they have nothing to do with classic WebForms server side controls. They are just HTML helpers.

Basically classic WebForms are a leaky abstraction of the web. What Microsoft did back in the time when they designed this framework was to bring existing Windows developer skills to the web which was getting more and more momentum. But since the web was still a new technology that most developers weren't yet familiar with, they created this abstraction to hide away the way that the www works. Those developers were accustomed to drag and dropping controls on their Windows Forms, double clicking on buttons that was generating some code for them in which they put their data access logic and so on. This model was transposed to web application development thanks to WebForms. The HTTP protocol was successfully hidden behind this abstraction called WebForms. For example you don't need to know HTML, nor Javascript, not even CSS in order to create a website using WebForms which is really great because the framework abstracts all those things for you. Unfortunately by doing so it prevents you from easily utilizing the full power of lower level web technologies which some people might need when developing web applications.

What ASP.NET MVC does is basically remove this leaky abstraction and bring the www to the developers the way it was intended to be by its creators. ASP.NET MVC is not mature enough compared to classic WebForms so you cannot expect to find the same range of available controls and widgets but things are slowly shifting.

I would recommend you start here with ASP.NET MVC: http://asp.net/mvc. Go ahead, watch the videos, play around with the samples and see if ASP.NET MVC is for you or not. And of course if you encounter some specific difficulty or question don't hesitate to come back here and ask it.