[Dev Tip] 10 Good Practices for ASP.NET MVC Apps

When you open up Visual Studio 2013 with the intent of building a new ASP.NET MVC 5 project, you find only one option: an ASP.NET Web Application. This is great, as it represents a moment of clarity in a whirlpool of similar-looking and confusing options. So you click and are presented with various options as to the type of project to create. You want ASP.NET MVC, right? So you pick up the MVC option. What you obtain is a no-op demo application that was probably meant to give you an idea of what it means to code for ASP.NET MVC. Even though the result does nothing, the resulting project is fairly overloaded.

You’ll also find several Nuget packages and assemblies referenced that are not required by the sample application, yet are already there to save time for when you need them in action. This is not a bad idea in theory, as nearly any ASP.NET website ends up using jQuery, Bootstrap, Modernizr, Web Optimization, and others. And if you don’t like it, you still have the option of starting with an empty project and adding MVC scaffolding. This is better, as it delivers a more nimble project even though there are many references that are useless at first. The truth is that any expert developer has his own favorite initial layout of the startup project, including must-have packages and scripts.

Although I may be tempted, I don’t want to push my own ideal project layout on you. My purpose, instead, is applying the Occam’s Razor to the ASP.NET MVC project templates that you get in Visual Studio 2013. I’ll start with the organization of project folders and proceed through startup code, bundling, HTML layout, controllers, layers, HTTP endpoints, and multi-device views. Overall, here are ten good practices for sane ASP.NET MVC 5 development.

Let’s say you used the Visual Studio 2013 project template to create a new project. It works, but it’s rather bloated. Figure 1 shows the list of unnecessary references detected by ReSharper.

Figure 1 : Unnecessary references in the ASP.NET MVC project built with the default Visual Studio 2013 template

It’s even more interesting to look at the remaining references. Figure 2 shows what you really need to have referenced in order to run a nearly dummy ASP.NET MVC application.

Figure 2 : Strictly required assemblies in a basic ASP.NET MVC 5 project

Here’s the minimal collection of Nuget packages you need in ASP.NET MVC.

<packages><packageid="Microsoft.AspNet.Mvc"version="5.0.0"targetFramework="net45"/><packageid="Microsoft.AspNet.Razor"version="3.0.0"targetFramework="net45"/><packageid="Microsoft.AspNet.WebPages"version="3.0.0"targetFramework="net45"/></packages>

The project contains the folders listed in Table 1.

When you start adding Nuget packages, some other conventions start appearing such as the Scripts folder for Modernizr and for jQuery and its plugins. You may also find a Content folder for Bootstrap style sheets and a separate Fonts folder for Bootstrap’s glyph icons.

I find such a project structure rather confusing and usually manage to clean it up a little bit. For example, I like to place all content (images, style sheets, scripts, fonts) under the same folder. I also don’t much like the name Models. (I don’t like the name App_Start either but I’ll return to that in a moment.) I sometimes rename Models to ViewModels and give it a structure similar to Views: one subfolder per controller. In really complex sites, I also do something even more sophisticated. The Models folder remains as is, except that two subfolders are addedLInput and View, as shown in Figure 3.

Figure 3 : Content and Models folder internal structure

Generally speaking, there are quite a few flavors of models. One is the collection of classes through which controllers receive data. Populated from the model binding layer, these classes are used as input parameters of controller methods. I collectively call them the input model and define them in the Input subfolder. Similarly, classes used to carry data into the Razor views collectively form the view model and are placed under the Models/View folder. Both input and view models are then split on a per-controller basis.

One more thing to note is the matching between project folders and namespaces. In ASP.NET it’s a choice rather than an enforced rule. So you can freely decide to ignore it and still be happy, as I did for years. At some point—but it was several years ago—I realized that maintaining the same structure between namespaces and physical folders was making a lot of things easier. And when I figured out that code assistant tools were making renaming and moving classes as easy as click-and-confirm, well, I turned it into enforcement for any of my successive projects.

#2 Initial Configuration

A lot of Web applications need some initialization code that runs upon startup. This code is usually invoked explicitly from the Application_Start event handler. An interesting convention introduced with ASP.NET MVC 4 is the use of xxxConfig classes. Here’s an example that configures MVC routes:

publicclassRouteConfig{publicstaticvoidRegisterRoutes(RouteCollection routes){
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
     routes.MapRoute(
            name:"Default",
            url:"{controller}/{action}/{id}",
            defaults:new{
                controller ="Home",
                action ="Index",
                id =UrlParameter.Optional});}}

The code in global_asax looks like this:

RouteConfig.RegisterRoutes(RouteTable.Routes);

For consistency, you can use the same pattern to add your own classes that take care of application-specific initialization tasks. More often than not, initialization tasks populate some ASP.NET MVC internal dictionaries, such as the RouteTable.Routes dictionary of the last snippet (just after the heading for #2).For testability purposes, I highly recommend that xxxConfig methods are publicly callable methods that get system collections injected. As an example, here’s how you can arrange unit tests on MVC routes.

[TestMethod]publicvoidTest_If_Given_Route_Works(){// Arrangevar routes =newRouteCollection();MvcApplication.RegisterRoutes(routes);RouteData routeData =null;// Act & Assert whether the right route was foundvar expectedRoute ="{controller}/{action}/{id}";
    routeData =GetRouteDataFor("~/product/id/123",
                                routes);Assert.AreEqual(((Route) routeData.Route).Url,
                    expectedRoute);}

Note that the code snippet doesn’t include the full details of the code for custom GetRouteDataFor method. Anyway, the method uses a mocking framework to mock HttpContextBase and then invokes method GetRouteData on RouteCollection passing the mocked context.

var routeData = routes.GetRouteData(httpContextMock);

Many developers just don’t like the underscore convention in the name of some ASP.NET folders, particularly the App_Start folder. Is it safe to rename this folder to something like Config? The answer is: it’s generally safe but it actually depends on what you do in the project.

The possible sore point is the use of the WebActivator Nuget package in the project, either direct or through packages that have dependencies on it. WebActivator is a package specifically created to let other Nuget packages easily add startup and shutdown code to a Web application without making any direct changes to global.asax. WebActivator was created only for the purposes of making Nuget packages seamlessly extend existing Web applications. As WebActivator relies on an App_Start folder, renaming it may cause you some headaches if you extensively add/refresh Nuget packages that depend on WebActivator. Except for this, there are no problems in renaming App_Start to whatever you like most.

#3 Bundling and Minifying CSS Files

Too many requests from a single HTML page may cause significant delays and affect the overall time-to-last-byte metrics for a site. Bundling is therefore the process of grouping distinct resources such as CSS files into a single downloadable resource. In this way, multiple and logically distinct CSS files can be downloaded through a single HTTP request.

Minification, on the other hand, is the process that removes all unnecessary characters from a text-based resource without altering the expected functionality. Minification involves shortening identifiers, renaming functions, removing comments and white-space characters. In general, minification refers to removing everything that’s been added mostly for readability purposes, including long descriptive member names.

Bundling requires the Microsoft ASP.NET Web Optimization Framework available as a Nuget package. Downloading the Optimization Framework also adds a few more references to the project. In particular, they are WebGrease and Microsoft Infrastructure. These, in turn, bring their own dependencies for the final graph, shown in Figure 4.

Figure 4 : Graph of Nuget dependencies for bundling and minification

Bundles are created programmatically during the application startup in global.asax. Also in this case, you can use the xxxConfig pattern and add some BundlesConfig class to the App_Startup folder. The BundleConfig class contains at least one method with code very close to the following snippet.

publicstaticvoidRegisterBundles(BundleCollection bundles){
   bundles.Add(newStyleBundle("~/Content/Styles").Include("~/Content/Styles/bootstrap.css","~/Content/Styles/myapp.css"));}

The code creates a new bundle object for CSS content and populates it with distinct CSS files defined within the project. Note that the Include method refers to physical paths within the project where the source code to bundle is located. The argument passed to the StyleBundle class constructor instead is the public name of the bundle and the URL through which it will be retrieved from pages. There are quite a few ways to indicate the CSS files to bundle. In addition to listing them explicitly, you can use a wildcard expression:

bundles.Add(newBundle("~/css").Include("~/content/styles/*.css");

Once CSS bundles are defined invoking them is as easy as using the Styles object:

@Styles.Render("~/Bundles/Css")

As you can figure from the last two snippets, ASP.NET optimization extensions come with two flavors of bundle classes: the Bundle class and the StyleBundle class. The former only does bundling; the latter does both bundling and minification. Minification occurs through the services of an additional class. The default CSS minifier class is CssMinify and it is based on some logic packaged in WebGrease. Switching to a different minifier is easy too. All you do is using a different constructor on the StyleBundle class. You use the constructor with two arguments, the second of which is your own implementation of IBundleTransform.

#4 Bundling and Minifying Script Files

Bundling and minification apply to script files in much the same way as bundling and minifying CSS files. The only minor difference is that for frequently used script files (such as jQuery) you might want to use a CDN for even better performance. In operational terms, bundling and minifying script files requires the same process and logic as CSS files. You use the Bundle class if you’re only concerned about packing multiple files together so that they are captured in a single download and cached on the client. Otherwise, if you also want minifying, you use the ScriptBundle class.

bundles.Add(newScriptBundle("~/Bundles/Core").Include("~/Content/Scripts/myapp-1.0.0.js","~/Content/Scripts/knockout-3.0.0.js"));

Like StyleBundle, ScriptBundle also features a constructor that accepts an IBundleTransform object as its second argument. This object is expected to bring in some custom logic for minifying script files. The default minifier comes from WebGrease and corresponds to the JsMinify class.

It’s very common today to arrange very complex and graphically rich Web templates that are responsive to changes in the browser’s window size and that update content on the client side through direct access to the local DOM. All this can happen if you have a lot of script files. It’s not, for the most part, JavaScript code that you write yourself. It’s general-purpose JavaScript that forms a framework or a library. In a nutshell, you often end up composing your client-side logic by sewing together multiple pieces, each of which represents a distinct download.

Considering the general recommendation of using as few script endpoints as possible—and bundling does help a lot in that regard—the optimal position of the <script> tags in the body of the HTML page is an open debate. For quite some time, the common practice was to put <script> elements at the end of the document body. This practice was promoted by Yahoo and aimed at avoiding roadblocks during the rendering of the page. By design, in fact, every time the browser encounters a <script> tag, it stops until the script has been downloaded (or recovered from the local cache) and processed.

It’s not mandatory that all script files belong at the bottom. It’s advisable that you distinguish the JavaScript that’s needed for the page to render from the JavaScript that serves other purposes. The second flavor of JavaScript can safely load at the bottom. Well, mostly at the bottom. Consider that as the page renders the user interface in the browser, users may start interacting with it. In doing so, users may trigger events that need some of the other JavaScript placed at the bottom of the page and possibly not yet downloaded and evaluated. If this is your situation, consider keeping input elements that the user can interact with disabled until it’s safe to use them. The ready event of jQuery is an excellent tool to synchronize user interfaces with downloaded scripts. Finally, consider some techniques to load scripts in parallel so that the overall download time becomes the longest of all instead of the sum of all downloads. The simplest way you can do this is through a programmatically created <script> element. You do this using code, as shown below.

var h = document.getElementsByTagName("HEAD")[0];var script = document.createElement("script");
script.type ="text/javascript";
script.onreadystatechange =function(){...};
script.onload =function(){...};
script.onerror =function(){...};
document.src ="...";
h.appendChild(script)

Script elements are appended to the HEAD element so that parallel download begins as soon as possible. Note that this is the approach that most social Web sites and Google Analytics use internally. The net effect is that all dynamically created elements are processed on different JavaScript threads. This approach is also employed by some popular JavaScript loader frameworks these days.

#5 The Structure of the _Layout File

In ASP.NET MVC, a layout file is what a master page was in classic Web Forms: the blueprint for multiple pages that are ultimately built out of the provided template. What should you have in a master view? And in which order?

With the exceptions and variations mentioned a moment ago for parallelizing the download of multiple scripts, there are two general rules that hold true for the vast majority of websites. The first rule says: Place all of your CSS in the HEAD element. The second rule says: Place all of your script elements right before the closing tag of the <body> element.

There are a few other little things you want to be careful about in the construction of the layout file(s) for your ASP.NET MVC application. First off, you might want to declare explicitly that the document contains HTML5 markup. You achieve this by having the following markup at the very beginning of the layout and subsequently at the beginning of each derived page.

<!DOCTYPE html>

The DOCTYPE instructs older browsers that don’t support specific parts of HTML5 to behave well and correctly interpret the common parts of HTML while ignoring the newest parts. Also, you might want to declare the character set in the HEAD block.

<metacharset="UTF-8">

The charset attribute is case-insensitive, meaning that you can indicate the character set name as UTF-8, utf-8 or otherwise. In general, you don’t use other character sets than UTF-8, as it’s the default encoding for Web documents since HTML4, which came out back in 1999. As far as IIS and ASP.NET are concerned, you have other ways to set the character set. For example, you can type it in the <globalization> section of the web.config file. Having it right in each page just adds clarity. An interesting consequence of clarifying the character set being used is that you can avoid using HTML entities and type special characters directly in the source. Canonical examples are the copyright (&copy;), trademark (&reg;), euro (&euro), dashes (&mdash;), and more. The only HTML entities you should use are those that provide the text version of reserved markup characters, such as less-than, greater-than, and ampersand.

Another rather important meta-tag you’ll want to have is the viewport meta-tag whose usage dates back to the early days of smartphones. Most mobile browsers can be assumed to have a rendering area that’s much larger than the physical width of the device. This virtual rendering area is just called the “viewport.” The real size of the internal viewport is browser-specific. However, for most smart phones, it’s around 900 pixels. Having such a large viewport allows browsers to host nearly any Web page, leaving users free to pan and zoom to view content, as illustrated in Figure 5.

Figure 5 : The viewport in a browser

The viewport meta-tag is a way for you to instruct the browser about the expected size of the viewport.

<metaname="viewport"content="width=device-width,
               initial-scale=1.0,
               maximum-scale=1.0,
               user-scalable=no"/>

In this example, you tell the browser to define a viewport that is the same width as the actual device. Furthermore, you specify that the page isn’t initially zoomed and worse, users can’t zoom in. Setting the width property to the device’s width is fairly common, but you can also indicate an explicit number of pixels.

In ASP.NET MVC, pay a lot of attention to keeping the layout file as thin as possible. This means that you should avoid referencing from the layout file CSS and script files that are referenced by all pages based on the layout. As developers, we certainly find it easier and quicker to reference resources used by most pages right from the layout file. But that only produces extra traffic and extra latency. Taken individually, these extra delays aren’t significant, except that they sum up and may add one or two extra seconds for the page to show and be usable.

<divclass="container">
    @RenderBody()
    <hr/><footer>
        © @DateTime.Now.Year - ASP.NET QuickUp
    </footer></div>

The markup above indicates that the entire body of the page replaces @RenderBody. You can define custom sections in a layout file using the following line:

@RenderSection("CustomScripts")

The name of the section is unique but arbitrary and you can have as many sections as you need with no significant impact on the rendering performance. You just place a @RenderSection call where you want the derived page to inject ad hoc content. The example above indicates a section where you expect the page to insert custom script blocks. However, there’s nothing that enforces a specific type of content in a section. A section may contain any valid HTML markup. If you want to force users to add, say, script blocks, you can proceed as follows:

<scripttype="text/javascript">@RenderSection("CustomScripts")</script>

In this case, overridden sections are expected to contain data that fits in the surrounding markup; otherwise, a parsing error will be raised. In a derived page, you override a section like this:

@sectionCustomScripts{
   alert("Hello");}

#6 (Don’t) Use Twitter Bootstrap

Twitter Bootstrap is quickly becoming the de-facto standard in modern Web development, especially now that Visual Studio 2013 incorporates it in the default template for ASP.NET MVC applications. Bootstrap essentially consists of a large collection of CSS classes that are applicable directly to HTML elements and in some cases to special chunks of HTML markup. Bootstrap also brings down a few KBs of script code that extends CSS classes to make changes to the current DOM.

As a matter of fact, with Bootstrap, you can easily arrange the user interface of Web pages to be responsive and provide advanced navigation and graphical features.

The use of Bootstrap is becoming common and, as popularity grows, also controversial. There are reasons to go for it and reasons for staying away from it. My gut feeling is that Bootstrap is just perfect for quick projects where aesthetics are important but not fundamental, and where you need to provide pages that can be decently viewed from different devices with the lowest possible costs. Key arguments in favor of Twitter Bootstrap are its native support for responsive Web design (RWD), deep customizability, and the not-secondary fact that it’s extremely fast to learn and use.

Bootstrap was created as an internal project at Twitter and then open-sourced and shared with the community. When things go this way, there are obvious pros and cons. For Web developers, it’s mostly about good things. Bootstrap offers a taxonomy of elements that you want to have in Web pages today: fluid blocks, navigation bars, breadcrumbs, tabs, accordions, rich buttons, composed input fields, badges and bubbles, lists, glyphs, and more advanced things, such as responsive images and media, auto-completion, and modal dialogs. It’s all there and definable through contracted pieces of HTML and CSS classes. Put another way, when you choose Bootstrap, you choose a higher level markup language than HTML. It’s much the same as when you use jQuery and call it JavaScript. The jQuery library is made of JavaScript but extensively using it raises the abstraction level of JavaScript.

By the same token, using Bootstrap extensively raises the abstraction level of the resulting HTML and makes it look like you’re writing Bootstrap pages instead of HTML pages. This is just great for developer-centric Web solutions. It’s not good for Web designers and for more sophisticated projects where Web designers are deeply involved.

When you choose Bootstrap. you choose a higher-level markup language than HTML. It’s much the same as when you use jQuery and call it JavaScript.

From a Web designer’s perspective, Twitter Bootstrap is just a Twitter solution and even theming it differently is perceived like work that takes little creativity. From a pure Web design perspective, Bootstrap violates accepted (best) practices. In particular, Bootstrap overrides the HTML semantic and subsequently, presentation is no longer separate from the content. Not surprisingly, when you change perspective, the same feature may turn from being a major strength to being a major weakness. Just because Bootstrap overrides the HTML semantic, it tends to favor an all-or-nothing approach. This may be problematic for a Web design team that joins an ongoing project where Bootstrap is being used. In a nutshell, Bootstrap is an architectural decision—and one that’s hard to change on the go. So, yes, it makes presentation tightly bound to content. Whether this is really an issue for you can’t be determined from the outside of the project.

Last but not least, the size of Twitter Bootstrap is an issue. Minified, it counts for about 100K of CSS, 29K of JavaScript plus fonts. You can cut this short by picking exactly the items you need. The size is not an issue for sites aimed at powerful devices such as a PC, but Bootstrap for sites aimed at mobile devices may be a bit too much. If you’re going to treat desktop devices differently from mobile devices, you might want to look into the mobile-only version of Bootstrap that you find at .

#7 Keep Controllers Thin

ASP.NET MVC is often demonstrated in the context of CRUD applications. CRUD is a very common typology for applications and it’s a very simple typology indeed. For CRUD applications, a fat controller that serves any request directly is sometimes acceptable. When you combine the controller with a repository class for each specific resource you handle, you get good layering and achieve nifty separation of concerns.

It’s essential to note that the Model-View-Controller pattern alone is not a guarantee of clean code and neatly separated layers. The controller simply ensures that any requests are routed to a specific method that’s responsible for creating the conditions for the response to be generated and returned. In itself, an action method on a controller class is the same as a postback event handler in old-fashioned Web Forms applications. It’s more than OK to keep the controller action method tightly coupled to the surrounding HTTP context and access it from within the controller method intrinsic objects such as Session, Server, and Request. A critical design goal is keeping the controller methods as thin as possible. In this way, the controller action methods implement nearly no logic or very simple workflows (hardly more than one IF or two) and there’s no need to test them.

Figure 6 : A multi-layer architecture for an ASP.NET MVC application

The extra layer is the application layer and it consists of classes that typically map to controllers. For example, if you have HomeController, you might also want to have some HomeService class. Each action in HomeController ends up calling one specific method in HomeService. Listing 1 shows some minimalistic code to illustrate the pattern.

The Index method invokes the associated worker service to execute any logic. The service returns a view model object that is passed down to the view engine for the actual rendering of the selected Razor view. Figure 7 shows instead a modified project structure that reflects worker services and the application layer of the ASP.NET MVC application.

Figure 7 : The new project infrastructure for worker services and view models

#8 Membership and Identity

To authenticate a user, you need some sort of a membership system that supplies methods to manage the account of a user. Building a membership system means writing the software and the related user interface to create a new account and update or delete existing accounts. It also means writing the software for editing any information associated with an account. Over the years, ASP.NET has offered a few different membership systems.

Historically, the first and still largely used membership system is centered on the Membership static class. The class doesn’t directly contain any logic for any of the methods it exposes. The actual logic for creating and editing accounts is supplied by a provider component that manages an internal data store. You select the membership in the configuration file. ASP.NET comes with a couple of predefined providers that use SQL Server or Active Directory as the persistence layer. Using predefined providers is fine, as it binds you to a predefined storage schema and doesn’t allow any reuse of existing membership tables. For this reason, it’s not unusual that you end up creating your own membership provider.

Defining a custom membership provider is not difficult at all. All you do is derive a new class from MembershipProvider and override all abstract methods. At a minimum, you override a few methods such as ValidateUser, GetUser, CreateUser, and ChangePassword. This is where things usually get a bit annoying.

The original interface of the Membership API is way too complicated with too many methods and too many quirks. People demanded a far simpler membership system. Microsoft first provided the SimpleMembership provider and with Visual Studio 2013, what appears to be the definitive solution: ASP.NET Identity.

In the ASP.NET Identity framework, all of the work is coordinated by the authentication manager. It takes the form of the UserManager<T> class, which basically provides a façade for signing users in and out.

publicclassUserManager<T>where T :IUser{:}

The type T identifies the account class to be managed. The IUser interface contains a very minimal definition of the user, limited to ID and name. The ASP.NET Identity API provides the predefined IdentityUser type that implements the IUser interface and adds a few extra properties such as PasswordHash and Roles. In custom applications, you typically derive your own user type inheriting from IdentityUser. It’s important to notice that getting a new class is not required; you can happily work with native IdentityUser if you find its structure appropriate.

User data storage happens via the UserStore<T> class. The user store class implements the IUserStore interface that summarizes the actions allowed on the user store:

publicinterfaceIUserStore<T>:where T:IUser{TaskCreateAsync(T user);TaskDeleteAsync(T user);Task<T>FindByIdAsync(string userId);Task<T>FindByNameAsync(string userName);TaskUpdateAsync(T user);}

As you can see, the user store interface looks a lot like a canonical repository interface, much like those you might build around a data access layer. The entire infrastructure is glued together in the account controller class. The skeleton of an ASP.NET MVC account controller class that is fully based on the ASP.NET Identity API is shown in Listing 2.

The controller holds a reference to the authentication identity manager. An instance of the authentication identity manager is injected in the controller. The link between the user store and the data store is established in the ApplicationDbContext class. You’ll find this class defined by the ASP.NET MVC 5 wizard if you enable authentication in the Visual Studio 2013 project template.

publicclassApplicationDbContext:IdentityDbContext<IdentityUser>{publicApplicationDbContext():base("DefaultConnection"){}}

The base IdentityDbContextclass inherits from DbContextand is dependent on Entity Framework. The class refers to an entry in the web.config file, where the actual connection string is read. The use of Entity Framework Code First makes the structure of the database a secondary point. You still need a well-known database structure, but you can have the code to create one based on existing classes instead of manual creation in SQL Server Management Studio. In addition, you can use Entity Framework Code First Migration tools to modify a previously created database as you make changes to the classes behind it.

Currently, ASP.NET Identity covers only the basic features of membership but its evolution is not bound to the core ASP.NET Framework. Features that the official interfaces don’t cover yet (such as enumerating users) must be coded manually, which brings you back to the handcrafted implementation of membership.

#9 Expose HTTP Endpoints

An architecture for Web applications that’s becoming increasingly popular is having a single set of HTTP endpoints—collectively known as Web services—consumed by all possible clients. Especially if you have multiple clients (like mobile applications and various Web frontends) a layer of HTTP endpoints is quite helpful to have. Even if you only have a single client frontend, a layer of HTTP endpoints is helpful as it allows you to have a bunch of Ajax-based functionalities integrated in HTML pages. The question is: How would you define such endpoints?

If you need an API—or even a simple set of HTTP endpoints—exposed out of anything but ASP.NET MVC (such as Web Forms or Windows services) using Web API is a no-brainer. But if all you have is an ASP.NET MVC application, and are tied to IIS anyway, you can simply use a separate ASP.NET MVC controller and make it return JSON.

With plain ASP.NET MVC, you can easily build an HTTP façade without learning new things. In ASP.NET MVC, the same controller class can serve JSON data or an HTML view. However, you can easily keep controllers that return HTML separate from controllers that only return data. A common practice consists in having an ApiController class in the project that exposes all endpoints expected to return data. In Web API, you have a system-provided ApiController class at the top of the hierarchy for controllers. From a practical perspective, the difference between ASP.NET MVC controllers and Web API controllers hosted within the same ASP.NET MVC is nearly non-existent. At the same time, as a developer, it’s essential that you reason about having some HTTP endpoints exposed in some way.

Web API and ASP.NET MVC have different purposes.

#10 Use Display Modes

One of the best-selling points of CSS is that it enables designers and developers to keep presentation and content neatly separated. Once the HTML skeleton is provided, the application of different CSS style sheets can produce even radically different results and views. With CSS, you can only hide, resize, and reflow elements. You can’t create new elements and you can add any new logic for new use-cases.

In ASP.NET MVC, a display mode is logically the same as a style sheet except that it deals with HTML views instead of CSS styles. A display mode is a query expression that selects a specific view for a given controller action. In much the same way, the Web browser on the client processes CSS media query expressions and applies the appropriate style sheet; a display mode in server-side ASP.NET MVC processes a context condition and selects the appropriate HTML view for a given controller action.

Display modes are extremely useful in any scenario where multiple views for the same action can be selected based on run-time conditions. The most compelling scenario, however, is associated with server-side device detection and view routing. By default, starting with ASP.NET MVC 4, any Razor view can be associated with a mobile-specific view. The default controller action invoker automatically picks up the mobile-specific view if the user agent of the current request is recognized as the user agent of a mobile device. This means that if you have a pair of Razor views such as index.cshtml and index.mobile.cshtml, the latter will be automatically selected and displayed in lieu of the former if the requesting device is a mobile device. This behavior occurs out of the box and leverages display modes. Display modes can be customized to a large extent. Here’s an example:

var tablet =newDefaultDisplayMode("tablet"){ContextCondition=(c =>IsTablet(c.Request))};var desktop =newDefaultDisplayMode("desktop"){ContextCondition=(c =>returntrue)};
displayModes.Clear();
displayModes.Add(tablet);
displayModes.Add(desktop);

The preceding code goes in the Application_Start event of global.asax and clears default existing display modes and then adds a couple of user-defined modes. A display mode is associated with a suffix and a context condition. Display modes are evaluated in the order in which they’re added until a match is found. If a match is found—that is, if the context condition holds true—then the suffix is used to complete the name of the view selected. For example, if the user agent identifies a tablet, then index.cshtml becomes index.tablet.cshtml. If no such Razor file exists, the view engine falls back to index.cshtml.

Display modes are an extremely powerful rendering mechanism but all this power fades without a strong mechanism to do good device detection on the server side. ASP.NET lacks such a mechanism. ASP.NET barely contains a method in the folds of the HttpRequest object to detect whether a given device is mobile or not. The method is not known to be reliable and work with just any old device out there. It lacks the ability to distinguish between smartphones, tablets, Google glasses, smart TVs, and legacy cell phones. Whether it works in your case is up to you.

If you’re looking for a really reliable device detection mechanism, I recommend WURFL, which comes through a handy Nuget package. For more information on WURFL, you can check out my article that appeared in the July 2013 issue of CODE Magazine, available at the following URL: .

Display modes are extremely useful in any scenario where multiple views for the same action can be selected based on run time conditions.

Summary

ASP.NET MVC 5 is the latest version of Microsoft’s popular flavor of the ASP.NET platform. It doesn’t come with a full bag of new goodies for developers but it remains a powerful platform for Web applications. ASP.NET is continuously catching up with trends and developments in the Web space and writing a successful ASP.NET MVC application is a moving target. This article presented ten common practices to build ASP.NET MVC applications with comfort and ease.

Listing 1: A layered controller class

publicinterfaceIHomeService{IndexViewModelGetModelForIndex();}publicclassHomeController:Controller{privatereadonlyIHomeService _service;publicHomeController():this(newHomeService()){}publicHomeController(IHomeService service){
        _service = service;}publicActionResultIndex(){var model = _service.GetModelForIndex();returnView(model);}}publicclassViewModelBase{publicStringTitle{get;set;}}publicclassIndexViewModel:ViewModelBase{// More members here}

Listing 2. Sample account controller class

publicclassAccountController:Controller{publicUserManager<IdentityUser>UserManager{get;set;}publicAccountController(UserManager<IdentityUser> manager){UserManager= manager;}publicAccountController():this(newUserManager<IdentityUser>(newUserStore<IdentityUser>(newApplicationDbContext()))){}// Other members here}

Table 1: Typical project folders.

Folder name Intended goal
App_Data Contains data used by the application, such as proprietary files (e.g., XML files) or local databases
App_Start Contains initialization code. By default, it simply stores static classes invoked from within global.asax.
Controllers Folder conventionally expected to group all controllers used by the application
Models Folder conventionally expected to contain classes representing the rather nebulous MVC concept of “model”
Views Folder conventionally expected to group all Razor views used by the application. The folder is articulated in subfolders,one per controller

[Startup] Vì sao nhà bán lẻ Việt Nam cần hiểu và chuyển mô hình phân phối theo Omni-channel?

Đây là bài viết được gửi đến từ Johnny Trí Dũng, Giám đốc Kinh doanh Khu vực của Catcha Digital Asia, công ty liên doanh của Catcha Investment GroupOPT, một trong những công ty hàng đầu hoạt động trong lĩnh vực e-marketing của Nhật Bản. Bạn có thể liên lạc với anh qua facebook.


omni channel

Mặc dù đã có khá nhiều nhà bán lẻ tại Việt Nam (VN) đã xây dựng mô hình thương mại điện tử cho chính mình, nhưng có không ít các nhà bán lẻ khác lại đang làm điều ngược lại, đó là rút lui khỏi cuộc chơi tốn kém này, với vô vàn lý do như sau:

  • Chúng tôi sợ việc đầu tư quá nhiều “công lực” vào thương mại điện tử, sẽ làm chúng tôi mất tập trung trong mô hình bán lẻ, vốn là thế mạnh của chúng tôi
  • Chúng tôi không đủ nhân lực và chuyên gia tốt để xây hệ thống thương mại điện tử hoàn chỉnh
  • Chúng tôi biết rõ về bán lẻ, và sẽ hiệu quả hơn là dùng tiền số tiền này để mở thêm các cửa hàng bán lẻ ngoài thực tế.
  • Các cửa hàng bán lẻ là những tài sản thật sự của chúng tôi, trong khi với thương mại điện tử, các định giá đều ở dạng …ảo?
  • Chúng tôi chưa sẵn sàng đầu tư (hoặc chưa có nguồn lực tài chính để đầu tư)
  • Chúng tôi muốn ngồi và chờ xem các bạn khác làm thế nào (kiểu làm ngư ông đắc lợi). Khi thuận lợi sẽ nhảy vào.

Mặc dù EPR (Ecommerce Penetration Rate – thước đo quan trọng nhất để định lượng được độ chín mùi của mô hình ecommerce 1 nước) của Vietnam trong năm 2016 sẽ chỉ là 0.71%, chỉ bằng 1 nửa so với Thái Lan (1,4%), và nhỏ hơn 5 lần so với Singapore (3,86%). Các nhà bán lẻ tại VN cần hiểu rõ rằng với các con số này, thị trường thương mại điện tử VN còn rất rộng mở, và người nhanh tay sẽ là người có nhiều lợi thế trong cuộc đua dài hơi này. Đồng thời, với việc bắt đầu mô hình Omni-channel, song song với sự chuyển dịch cán cân bán hàng lên online, họ sẽ có rất nhiều lợi thế với nhiều đối thủ khác! Nhưng Omni-channel retailing là gì?

Theo Wikipedia, nói ngắn gọn, Omni-Channel Retailing (OCR) là mô hình tiếp thị và bán lẻ tất cả trong 1, rằng khách hàng của bạn có thể đến từ rất nhiều nguồn, và xem thông tin bằng nhiều thiết bị khác nhau. Bạn luôn phải sẵn sàng để mang lại trải nghiệm tốt nhất cho họ, ở tất cả các kênh!

May mắn được nói chuyện và trao đổi với Darren Fifield từ eBay Enterprise, trong cuộc nói chuyện ngoài lề tại eTail Asia 2014, tôi xin được chia sẻ 1 số thông tin hay ho, cũng như tóm gọn bài chia sẻ của anh tại đây.

Các khách hàng ngày nay luôn trong trạng thái “online”

use smartphone in toilet

84% người dùng điện thoại không thể có 1 ngày sống thiếu chú dế yêu (dĩ nhiên là điện thoại thông minh (smart phone), xin lỗi khi bỏ qua các bạn đang dùng “điẹn thoại không thông minh Nokia (feature phone).

(Nguồn: Time, Mobility Poll).

76% trong số họ truy cập vào ít nhất 2 thiết bị có kết nối internet.

(Nguồn: eBay Enterprise Centre for Connected Commerce research).

8-10 giờ sáng: là thời gian 66% trong số họ sẽ thức dậy cùng với smartphone.

12-5 giờ chiều: Giờ cao điểm xài smartphone trong ngày.

6-10 giờ chiều: Giờ cao điểm xài tablet (máy tính bảng) trong ngày.

(Nguồn: Nielsen)

75% sử dụng điện thoại khi đang đi vệ sinh. Ai thấy chuẩn thì giơ tay nhé!

(Nguồn: Nielsen)

Khách hàng ngày càng đòi hỏi nhiều hơn!

81% các nhà bán lẻ chuyên nghiệp luôn biết cách tận dụng tối đa công nghệ để mang lại trải nghiệm mua sắm tốt nhất cho người dùng.

(Nguồn: eBay Enterprise Center for Connected Commerce research)

66% khách hàng mong muốn các nhà bán lẻ ngày nay mang lại cho họ 1 trải nghiệm mua hàng tốt trên smartphone.

75% khách hàng mong muốn các nhà bán lẻ ngày nay đưa đến cho họ 1 trải nghiệm mua hàng tốt trên máy tính bảng.

(Nguồn: comScore Device Essentials, January 2013, Europe)

84% khách hàng tin rằng các nhà bán lẻ cần làm tốt hơn trong việc “kết nối” kênh mua sắm offline và online.

(Nguồn: eBay Enterprise Center for Connected Commerce research)

Khách hàng đang thay đổi thói quen shopping của họ!

kate spade

Kate Spade và mô hình bán lẻ mới, tuyệt vời của eBay: “Chúng tôi cố gắng chuyển dịch kinh doanh của mình từ chuỗi của hàng bán lẻ offline sang mô hình bán lẻ đa kênh, việc eBay mua lại công ty GSI, thật sự là 1 bước ngoặt cho các công ty cùng lĩnh vực, trong đó có chúng tôi.” – Bill McComb, CEO của Fifth and Pacific Companies.

29% người Mỹ sẽ mua tất cả mọi thứ online nếu họ có thể.

(Nguồn: eBay Enterprise Center for Connected Commerce research)

48% các giao dịch trong năm 2014 sẽ chịu tác động của website, ngay cả khi khách hàng mua hàng online, hoặc tham khảo trước khi mua tại cửa tiệm offline.

(Nguồn: eBay Enterprise Center for Connected Commerce research)

Các khách hàng ngày nay đang thật sự chịu tác động của nhiều kênh quảng cáo khác nhau

Thật vậy, khách hàng ngày nay online mọi lúc mọi nơi, và phần lớn người tiêu dùng đều chịu tác động của “Omni-channel”, không phải chỉ của 1 kênh quảng cáo riêng biệt nào. Tất cả họ đều tiềm năng cả, vậy làm sao để “tận dụng” điều này và giúp họ mua hàng của bạn?

Cửa hàng bán lẻ của bạn là 1 tài sản, là 1 thứ vũ khí lợi hại, theo Darrel Rihby, tác của cuốn “The Future of Shopping”, được Harvard Business Review:

Nếu các nhà bán lẻ offline truyền thống muốn tồn tại, họ phải sử dụng chiến lược phủ sóng “omni-channel’ retailing, và biến thứ mà mọi mô hình bán lẻ B2C online đang thiếu (giao dịch thương mại trên Internet giữa doanh nghiệp với khách hàng)- cửa hàng offline – từ 1 của nợ tiêu tống nhiều tiền, trở thành 1 tài sản, 1 thứ vũ khí lợi hại giúp bạn đánh bại đối thủ.

Các cửa hàng có thể sẽ có cái nhìn khác trong tương lại, theo Sir Terry Leahy, cựu CEO của tập đoàn bán lẻ hàng đầu thế giới – Tesco:

Con người đang thay đổi thói quen 1 cách chóng mặt, trong khi các doanh nghiệp thì lại đang rất ù lì, di chuyển rất chậm, làm mất đi nhiều cơ hội. Khi xưa, nhắc đến đại gia trong ngành bán lẻ, người ta nghĩ ngay đến việc họ sở hữu nhiều của hàng to lớn, hoành tráng. Ngày nay, khi cuộc sống con người bận rộn hơn, có không ít khách hàng sẽ không còn đủ thời gian để shopping tại các cửa hàng offline đồ sộ đó nữa!

Phân phối sản phẩm bằng nhiều kênh – Mang sản phẩm đến tận tay người dùng

64% khách hàng sẽ thực hiện hành vi mua hàng tại các cửa hàng bán lẻ mới chỉ vì họ thấy dòng chữ ” Miẽn phí giao hàng.”

(Nguồn: eBay Enterprise Center for Connected Commerce research)

93% khách hàng mong đợi các nhà bán lẻ cho họ ít nhất 2 lựa chọn: Mua hàng trước và giao hàng tại cửa hàng, hay xài dịch vụ giao hàng tận nhà!

(Nguồn: eBay Enterprise Center for Connected Commerce research)

67% khách hàng sẽ huỷ bỏ giao dịch mua hàng nếu họ thấy khâu giao hàng có vấn đề!

(Nguồn: Comscore, Royal Mail Survey)

ship

35% khách hàng online sẽ click và collect (click mua sản phẩm, và sau đó đến lấy hàng sau)

18% trong số các khách hàng đó muốn mua thêm các sản phẩm khác, khi họ đến lấy hàng.

(Nguồn: Internet Retailer)

Các chương trình tiếp thị/ bán hàng/ giao hàng đa kênh sẽ giúp bạn tăng ít nhất 2% đến 20% doanh thu của shop! (Nguồn: eBay Enterprise internal client data)

Mô hình Omni-channel nào nên được bạn chú trọng?

Tất nhiên việc mang các sản phẩm đang có trong cửa hàng truyền thống lên cửa hàng trực tuyến là điều đầu tiên bạn phải làm, nhưng sau đó, bạn sẽ phải làm gì?

final

Bạn có thể xem qua hình trên và có 1 cái nhìn tương đối về kênh phân phối nào nên được bạn chú trọng, thông qua việc phân tích biểu đồ tăng trưởng của doanh thu, và mức độ dễ dàng trong việc thực hiện hình thức đó!

  1. Ship from store – Giao hàng chéo từ các cửa hàng khác nhau.
  2. Associate ordering in-store – Hỗ trợ đặt thêm sản phẩm cho khách khi họ đang mua hàng – Cross-sell.
  3. Buy online, ship to store – Mua hàng online, giao hàng tận nhà!
  4. Buy online, pick-up in-store – Mua hàng online, khách đến lấy hàng tại cửa hàng sau.

Đọc qua các mô hình trên, có thể bạn sẽ thầm hỏi rằng: Sao mô hình ship-from-store lại giúp tăng doanh thu được nhỉ? Đáng lẽ nó làm tăng chi phí chứ?

SAI LẦM bạn nhé! Với mô hình ship-from-store, bạn đã biến cửa hàng offline của bạn trở thành 1 trung tâm giao hàng ảo – “virtual distribution centers” (điều này có lợi hơn là việc bạn mở thêm các trung tâm giao hàng rải rác khắp nơi), nó cũng giúp bạn không phải trữ quá nhiều hàng, đồng thời giúp bạn “thanh toán” đống hàng đấy nhanh hơn. Ngoài ra, việc giữ hàng gần các khách hàng của mình cũng sẽ giúp giảm cost cho việc giao hàng.

Vẫn còn mù mờ ư? Hãy thử xem 2 ví dụ cụ thể nhé:

Ví dụ 1: Bạn có 1 đơn đặt hàng của khách tại Hà Nội (HN), nhưng cửa hàng tại HN của bạn không còn hàng, dĩ nhiên bạn sẽ chuyển hàng từ các cửa hàng tại miền trung, hoặc cửa hàng gần nhất với khu vực phía Bắc đến tận tay người dùng! Điều này giúp bạn tăng lượng hàng bán ra, tránh việc mất 1 lượng revenue kha khá từ việc ” Out of stock”- 1 lỗi phổ biến trong mô hình e-commerce hiện nay.

Ví dụ 2: Bạn có 1 đơn đặt hàng khác của KH tại TP. Hồ Chí Minh (HCM), bạn có hàng tại HCM, tuy nhiên các cửa hàng phía Bắc của bạn lại đang bị tồn kho mặt hàng này. Vậy, việc bạn chuyển hàng từ cửa hàng phía bắc vào tận tay cho khách sẽ giúp bạn thanh lý được số hàng tồn kho đấy, tốn 1 ít tiền shipping dù sao cũng tốt hơn là việc ngậm hàng mãi ko bán được, dẫn đến phải thanh lý với giá cực rẻ? Bạn nhỉ?

Giờ thì bạn đã hình dung ra được toàn bộ bức tranh chưa?

Ngoài ra, Associate ordering in-store cũng là 1 kênh bán hàng khác hết sức hiệu quả mà nhiều người đang bỏ qua. Chỉ cần đặt thêm 1 số món gợi ý trong quá trình check out của khách trên web, hoặc dựng thêm quầy bán các sản phẩm best-seller hoặc nhỏ gọn, tiện dùng, daily products… tại quầy thanh toán tiền, là những bước khởi đầu nhỏ trong việc tận dụng và tối đa doanh thu của bạn, cả offline lẫn online!

Nào, còn chờ gì nữa mà không mau chuyển cửa hàng offline của bạn từ 1 gánh nặng, thành 1 vũ khí lợi hại?

Biên tập bởi Quyen Quyen

[Startup] 10 câu nói hay về lãnh đạo và thành công của Tổng và phó tổng giám đốc VCCorp

VCCorp là một trong những ông lớn có tiếng trong làng công nghệ Việt Nam trong việc tạo ra được môi trường làm việc cuốn hút và kích thích sáng tạo. Không nhưng thế, với những triết lý mang đậm tính nhân văn cũng như tin tưởng vào con người, hai vị lãnh đạo cấp cao của VCCorp – anh Vương Vũ Thắng và anh Nguyễn Thế Tân – Tổng giám đốc và phó Tổng giám đốc của VCCorp có những quan niệm rất riêng để dẫn dắt và lãnh đạo công ty truyền thông số 1 Việt Nam hiện nay.

Và dưới đây 10 câu nói nổi tiếng của hai anh Vương Vũ Thắng, Nguyễn Thế Tân vừa thể hiện được quan điểm, tầm nhìn cũng như hướng đi trên con đường xây dựng VCCorp hiện nay và trong tương lai:

(Từ trái qua phải) Anh Nguyễn Thế Tân và anh Vương Vũ Thắng.

1. “Dụng nhân như dụng mộc”, nhà lãnh đạo không thể đòi hỏi nhân viên hoàn hảo. Nhưng nhiệm vụ của cấp trên là giao đúng người đúng việc để họ phát huy khả năng mình có. – Trích trong buổi tọa đàm “Làm thế nào để sếp hiểu nhân viên”. (12/2012)

2. Trong công việc, nhà lãnh đạo không thể đợi nhân viên tự hoàn hảo lên theo thời gian, mà hãy là người trực tiếp “gạn đục khơi trong”, giúp họ phát huy năng lực của mình. – Trích trong buổi tọa đàm “Làm thế nào để sếp hiểu nhân viên”. (12/2012)

3. Tư duy để tìm ra những người dưới quyền có điểm mạnh và điểm yếu ở đâu là kiểu nghĩ của những nhà lãnh đạo thành công. – Trích trong buổi tọa đàm “Làm thế nào để sếp hiểu nhân viên”. (12/2012)

4. Sếp thông minh phải biết nâng tầm nhân viên dần dần- Trích trong buổi tọa đàm “Làm thế nào để sếp hiểu nhân viên”. (12/2012)

5. Quan điểm của VC Corp là thành công không đến từ một cơ hội cụ thể mà từ một nền tảng tốt để có thể nhận ra, nắm bắt cơ hội và biến nó thành hiện thực. – Trả lời phỏng vấn của 5Desire về đầu tư và startup tại Việt Nam. (2/2012)

6. Tất cả mọi người đều là người tốt, ai cũng đến để làm được việc tốt. Vấn đề là tìm ra cho họ việc mà họ thực sự yêu thích và thực sự giỏi. – Trích trong bài phỏng vấn với Tech In Asia về văn hóa và môi trường làm việc tại VCCorp. (5/2014)

7. Ở VCCorp, có một khái niệm rất thú vị là “Tạm ứng niềm tin”. Giữa người với người, nếu chưa có thời gian tiếp xúc để hiểu tính cách, hiểu cách làm việc của nhau, thì có thể ứng trước lòng tin cho nhau, để cho và nhận sự hỗ trợ tối đa. – Trích trong bài phỏng vấn với Tech In Asia về văn hóa và môi trường làm việc tại VCCorp. (5/2014)

8. Thành công hay không chỉ đơn giản là đủ duyên. Khi hiểu thành công là đủ duyên, mỗi người sẽ quan tâm tạo ra những duyên phù hợp. Mình sẽ quan tâm đến tất cả những duyên xung quanh mình và tất cả những nhân mình đã gieo. Bởi mình hiểu rằng mọi việc đều vận hành theo luật nhân quả. Thành công cũng là do nhân quả. Không hẳn thành công là do cố gắng mặc dù sự cố gắng của mình cũng là một duyên trong hàng nghìn duyên ấy – Tại buổi chia sẻ sách “Quản lý nghiệp” do Câu lạc bộ Millionaire House. (6/2012)

9. Điểm đặc sắc nhất trong văn hóa ở VCCorp đó là VCCorp như là một “hợp chủng quốc các startup”. Bởi mỗi team đều được toàn quyền tự quyết vấn đề của mình nên mỗi team lại tự tạo ra được bản sắc riêng cũng như phong trào riêng của mình. – Trích trong bài phỏng vấn với Tech In Asia về văn hóa và môi trường làm việc tại VCCorp. (5/2014)

10. Nếu suy nghĩ bản thân là nguyên nhân đưa đến thành công của công ty và chỉ quan tâm đến những thứ của cá nhân mình, nhà lãnh đạo sẽ để mất nhiều nhân viên quan trọng. Nhiều khi, một nhân viên kế toán buồn bã hay một khách hàng nổi giận cũng ảnh hưởng đáng kể đến doanh nghiệp mình – Tại buổi chia sẻ sách “Quản lý nghiệp” do Câu lạc bộ Millionaire House. (6/2012)

(Biên tập bởi Sơn Trần)

[Discovery] Chế tạo loại vật liệu mới nhẹ hơn cả siêu vật liệu aerogel, nhưng cứng gấp 10.000 lần

Trước đây các nhà khoa học đã chế tạo thành công loại siêu vật liệu chỉ nặng hơn không khí 3 lần mà có độ cứng như thép, được gọi là aerogel. Tuy nhiên các nhà khoa học tại MIT và phòng thí nghiệm quốc gia Lawrence Livermore (LLNL) đã tạo ra một bước đột phá vĩ đại hơn trong công nghệ vật liệu, với một loại siêu vật liệu mới nhẹ như aerogel nhưng có độ cứng gấp 10.000 lần. Hứa hẹn sẽ tạo ra cuộc cách mạng mới trong việc chế tạo các phương tiện như ô tô, máy bay hay tàu vũ trụ.

Microscope image showing a single unit of the structure developed by the team, made from a...

Theo như mô tả của các nhà nghiên cứu thì vật liệu mà họ phát triển là một dạng siêu vật liệu (metamaterial) cấu trúc micro. Đây là vật liệu nhân tạo có các đặc tính mà không loại vật liệu thiên nhiên nào có được. Nó gần như vẫn giữ nguyên được độ cứng trên từng mật độ đơn vị, thậm chí ở mật độ rất thấp nó vẫn đảm bảo độ cứng.

Visualization showing a full array of the unit cells, which produces a material that is ex...

Với các đặc tính đó, các nhà nghiên cứu hy vọng trong tương lai nó sẽ được dùng để phát triển các bộ phận và linh kiện cho máy bay, xe hơi hay tàu vũ trụ nhờ vào công nghệ in 3D.

Loại siêu vật liệu mới này có thể tổng hợp được từ kim loại, gốm và nhựa. Một vật liệu làm từ các cấu trúc của polymer phủ lên một lớp gốm sẽ là một trong những loại nhẹ nhất thế giới. Nó có thể đỡ được khối trọng lượng nặng hơn 160.000 lần so với cân nặng của chính nó. LNLL cho biết nó cứng hơn 100 lần so với các vật liệu tương tự được tạo ra trong quá khứ.

Lawrence Livermore Engineer Xiaoyu Rayne Zheng studies a macroscale version of the unit ...

Nhóm nghiên cứu đã tạo ra vật liệu này nhờ một máy in stereolithographic. Đây là kỹ thuật dùng tia laser làm đông cứng nguyên liệu lỏng để tạo các lớp nối tiếp cho đến khi sản phẩm hoàn tất, độ dày mỗi lớp nhỏ nhất có thể đạt đến 0,06mm nên rất chính xác. Các máy in SLA làm cho nhu cầu gia đình sẽ không đủ chính xác để tạo ra loại siêu vật liệu mới như các nhà khoa học đã làm, bởi vì cấu trúc của nó phải được tạo thành một cách hoàn hảo ở mức độ kính hiển vi.​

Tham khảo: Gizmag

Video

[Life] Elon Musk: Tư duy đằng sau Tesla, SpaceX và SolarCity

elon-musk-and-chris-anderson. ​

 

Trước khi bắt đầu xem video mời các bạn xem lại bài viết “Elon Musk – Người muốn thay đổi tương lai”. Bài viết này có thể giúp bạn hiểu rõ hơn một chút về con người này và hiểu được những gì mà anh chia sẻ ở video bên dưới về những công việc mà anh đang làm, từ PayPalSpaceX, Tesla hay SolarCity.

Thật ra video này không mới, nó đã được đăng tải lên YouTube từ hơn một năm trước, tuy nhiên các bạn ở nhóm TEDVN đã thêm phụ đề tiếng Việt và đăng lại để chúng ta xem dễ hiểu hơn. Cảm ơn các bạn TEDVN nhiều.

Trong video này Elon Musk đã có buổi trò chuyện với Chris Anderson và chia sẻ về các dự án mà anh đang thực hiện, đó thực sự là những dự án phi thường. Elon Musk cũng chia sẻ về phương pháp tư duy để giải quyết mọi vấn đề một cách nghiêm túc và đơn giản nhất. Mời các bạn cùng xem video.​

 

[Discovery] Hải quân Mỹ chính thức áp dụng hệ thống phóng bằng điện từ cho siêu tàu sân bay Gerald R. Ford

electromagnetic-launcher.

Theo báo cáo mới nhất, hải quân Hoa Kỳ sẽ chính thức áp dụng hệ thống phóng máy bay bằng điện từ trường (EMALS) trên siêu tàu sân bay Gerald lớp Ford nhằm thay thế cho hệ thống phóng thủy lực vẫn được sử dụng từ trước tới nay. Đây là thành quả nghiên cứu hơn 25 năm không chỉ giúp tăng độ an toàn khi cất cánh máy bay từ tàu sân bay mà còn tiết giảm được chi phí duy tu bảo dưỡng cũng như tối thiểu hóa nhu cầu nhân lực để thực hiện cú phóng nhằm tăng cường tính cơ động, linh hoạt khi thực hiện tác chiến của tàu sân bay.

Trước đây, khi một chiếc máy bay tiêm kích cất cánh từ tàu sân bay luôn tạo ra một cảnh tượng ngoạn mục với làn hơi nước và khói mù mịt, những âm thanh chói tai mà còn có sự hiện diện của hàng loạt nhân viên hỗ trợ cất cánh. Trước khi máy bay cất cánh, một thanh giằng sẽ giữ hệ phóng đứng yên trong khi piston tích áp suất hơi. Đến khi áp suất trong piston đã đủ lớn, thanh giằng được giải phóng, piston đẩy máy bay gắn trên con thoi chạy dọc đường cất cánh với vận tốc cao từ 2 đến 4 giây trên đường chạy. Với vận tốc do hệ thống phóng cung cấp, máy bay có thể cất cánh khỏi tàu.

Cho đến hiện tại, phần lớn các tàu sân bay đều sử dụng hệ thống phóng bằng piston hơi để cung cấp sức đẩy cho máy bay. Tuy nhiên, không chỉ đòi hỏi nhiều nhân lực hỗ trợ, công tác bảo dưỡng gặp nhiều khó khăn với chi phí cao mà hệ thống phóng thủy lực còn tạo nên áp lực không tốt lên khung máy bay gián tiếp dẫn đến giảm tuổi thọ máy bay. Bên cạnh đó, do đã có tuổi đời hơn 50 năm nên công nghệ này còn bộc lộ sự yếu kém khi phóng những chiếc máy bay hiện đại ngày càng nặng hơn vốn cần nhiều lực đẩy hơn. Do đó, hải quân Mỹ đã sớm phát triển hệ thóng phóng bằng lực điện từ (EMALS) từ hơn 25 năm qua.

Video và hình ảnh thử nghiệm phóng máy bay với hệ thống phóng điện từ

Sau nhiều cuộc thử nghiệm mà gần đây nhất là phóng thành công một chiếc máy bay F/A-18E Super Hornet, cuối cùng thì hệ thống phóng điện từ EMALS cũng được chính thức trang bị cho siêu tàu sân bay Gerald lớp Ford, siêu tàu sân bay nguy hiểm nhất thế giới hiện nay sẽ xuất xưởng vào năm 2015. Đây cũng là công nghệ hỗ trợ phóng đầu tiên trong 60 năm qua được chính thức đưa vào thực tế. Thay vì sử dụng piston nén và con thoi trên đường rãnh gắn với máy bay để tạo lực đẩy, EMALS sử dụng lực từ điều khiển bằng máy tính để tạo gia tốc giúp đẩy máy bay tới phía trước.

Được áp dụng các công nghệ tối tân nhất, hệ thống phóng EMALS cho phép nâng cao hiệu quả hoạt động, tính ổn định, lực phóng máy bay, dễ dàng bảo trì, kiểm soát chính xác tốc độ và phóng máy bay một cách êm ái kể cả ở vận tốc cao hay thấp để không làm ảnh hướng đến độ ổn định chung của tàu. Ngoài ra, hệ thống EMALS hỗ trợ phóng nhiều loại máy bay từ cỡ nhỏ không người lái cho đến những chiếc chiến đấu cơ hạng nặng. Bên cạnh đó, EMALS chỉ thay thế công nghệ bên trong mà không hề thay đổi phương thức vận hành cũng như thao tác điều khiển nay nên phi công cũng không cần trải qua huấn luyện làm quen nhiều với hệ thống mới.

sieu_tau_san_bay_gerald_lop_ford.

Hình ảnh siêu hàng không mẫu hạm USS Gerald lớp Ford​

Đại úy Captain Frank Morley, thành viên ban quản lý dự án EMALS: “Đây thật sự là một khoảng khắc tuyệt vời và quan trong đói với ngành hàng không hải quân. 35 năm trước đây, người ta đều nghĩ rằng không có hệ thống phóng nào ngoài thủy lực có khả năng phóng những chiếc Hornet ra khỏi tàu sân bay. Tuy nhiên, giờ đây chúng ra đã may mắn chứng kiến được sự thay đổi lớn với hệ thống EMALS tiên tiến.”

Theo dự kiến, siêu tàu sân bay USS Gerald lớp Ford sẽ chính thức xuất xưởng vào khoảng cuối năm 2015 và chậm nhất là năm 2016 không chỉ với hệ thống phóng tối tân EMALS mà còn sở hữu nhiều công nghệ khoa học quân sự tối tân khác nhằm tăng cường sức mạnh của các hạm đội của Hoa Kỳ. Đồng thời, hệ thống EMALS cũng sẽ được áp dụng cho nhiêyf tàu sân bay khác trong biên chế hải quân Hoa Kỳ trong tương lai.