With the release of the new version of ASP.NET, I want to try what it is in practice. And in order not to write another chat \ social. network \ blog ..., for the pilot project, we will choose a logical quest - and we'll look at the framework, and we can play.
Result:
-
sorts on githaba for those who are interested to play with the new ASP.NET
-
Link to the quest for those who are interested in what happened or spend their time on another logical quest.

Prerequisites
To work with the new version of ASP.NET, you need Visual Studio 2015 - at the moment a preview version is available, you can download it here:
www.visualstudio.com/en-us/downloads/visual-studio-2015-downloads-vs.aspxThere should be no problems with the installation in parallel with other versions of the studio.
In fact, no other software besides the studio is needed for basic development on the .NET stack.
Create a project
To create a new ASP.NET application, we use, as always, File-> New-> Project (by the way, the menu in the new studio was again made with normal font, and not ALL CAPSOM, and personally it seems unusual to me now)
Select the type of project ASP.NET Web Application. The structure of project templates and pictures are again confused - the fact that there is no vNext icon on our type of project does not mean that our project will not be on a new version. Perhaps in the final version of 2015 this will be fixed.

If you want to add your project to the version control system - you can put a tick at the bottom (Add to source control).
')
In the next window, you can select the starting template for web applications of the new version, where there will already be several standard pages and authorization, as well as MVC is already connected, the basic framework of the project is created.

When creating a project, if a mark was added to add to the version control system - you can specify which system the version interests us. TFS and Git supported.

When you first push (if you use Git, you can immediately specify an external repository)

What's new in the template project
Probably for a .NET programmer that for the first time created ASP.NET 5 a new project will be quite a lot. Even if you look at the structure of the launch project:

Go through the innovations.
- Any xml-configs. Now all the configuration in json. Even for those who are not familiar with the syntax, this change will be absolutely comfortable - the configuration has become shorter and clearer. The project file remained in xml, now the project file extension is * .kporj if this is a project that is being executed on a new runtime - K runtime.
- global.json - configuration file for the whole solution. Initially, it has one line - “sources”: [“src”, “test”]
Which indicates where the weights are. You can also specify a specific path to nuget packages. - debugSettings.json - Run / Debug settings for a single project.
- wwwroot is the root folder of the site, intended for static files (html, css, img, js).
- Dependencies - to be honest, I didn’t understand until the end, it seems that NPM and Bower dependencies are highlighted separately in this folder.
- References - now the libraries are not reference libraries, rather convenient for navigation and search.
- bower.json - Bower packages (front-end packages).
- config.json is something like the past Web.config, only now is short and straightforward.
- gruntfile.js - configuration for Grunt (javascript build tool).
- package.json - NPM packages.
- project.json is one of the main project files, includes nuget packages and project settings.
First impression - sketched all that is possible in a heap. Perhaps somewhere the way it is. On the other hand, you can simply and quickly add any package, see all the dependencies. Although it is not yet completely clear, for example, that besides Grunt it is worthwhile to include NPM in packages. And, again, maybe in the final version everything will be somehow neater, while it is quite interesting to see web development tools from other platforms inside Visual Studio.
Begin to code. Architecture, front-end.
The structure of the project is logical to do the following: all static files (one-page website on AngularJs) are placed in the wwwroot folder, and for the back-up we will create a new controller that will act as an API for the site. By the way, in the new version of ASP.NET, the MVC and WebAPI controllers no longer differ.
Out of habit, I create in wwwroot the index.html page and the app folder. In the app, I have all the views, controllers, angular services. And in index.html - links to all js files and layout.
Since our main page is index.html, then the default route (route) in Startup.cs needs to be removed (so that when we go to the site, we visit index.html, and not Home / Index).
Add a standard bootstrap page and a set of scripts to index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.12/angular.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular-animate.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular-resource.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular-route.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-loading-bar/0.6.0/loading-bar.min.js"></script> <script src="app/app.js"></script> <script src="app/config.route.js"></script> <script src="app/start/start.js"></script> <script src="app/home/home.js"></script> <script src="app/services/mainquest.js"></script>
as well as the starting view - home.html and the start.html "working" page.
More
details can be found in
commit .
Back-end Model
First we need to store our data somewhere. Our project has already created a context for working with the database - ApplicationDbContext. Let's add to it the model of our application.
First of all, we need the tasks themselves - let's call them QuestTask. It will store information about the task - number, title, content, answer.
namespace HabraQuest.Models { public class QuestTask { public int Id { get; set; } public string Title { get; set; } public string Content { get; set; } public int Number { get; set; } public string Answer { get; set; } } }
Well, in order for the information about the user’s levels passed, add the Progress table where the user's token and the number of his last completed task will be stored. Tokens will be issued at the first access to the page and stored in cookies.
namespace HabraQuest.Models { public class Progress { public int Id { get; set; } public string Token { get; set; } public int TaskNumber { get; set; } } }
In general, our model is ready - we will add these properties to the context.
public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public DbSet<QuestTask> Tasks { get; set; } public DbSet<Progress> Progress { get; set; } ...
And then I realized that the new EntityFramework does not yet support migration, and in the code for creating the database there is a crutch.
(Then I learned that there are still migrations and you can try them through the k ef migration commands, which will be described below)
But since there are already some migrations there, you can try to add your tables to the database through the same crutch. And for one thing and find out whether backward compatibility works for migrations. So, quickly create an application in Studio 2013, add migrations, add the same classes to the model. We are copying the migration file to the studio in 2015. It turned out that it is impossible to copy it in its pure form, since some class names and methods have changed. But for 2 simple tables, this is fixed in 2 minutes. Launched, earned nothing
There is no need for a relational store to use.
Googled, looked at the code, I realized that now for migrations I still have to implement IMigrationMetadata. Sketched implementation. Error again.
I looked at the code again ...
After 5 such iterations, I realized that in one place I have a table called dbo.Progress in another just Progress. I wrote the same name and it all worked. It's nice that you can actually write migrations yourself, although, of course, such things are better done with standard tools.
The result of the game with migrations can be viewed on the
githaba .
So we have a front-end model. It remains to create an API.
Back-end Controllers
! The code does not carry any practical value, not refactored, written on the knee.
! basically I wanted to try C # 6 innovations, such as property initialization, an operator? ..
Let's call our controller for working with quests of the quest - QuestController and implement the method on a get request to check the answer and post a request for the functionality “start from the beginning”.
[AllowAnonymous] [Route("api/[controller]")] public class QuestController : Controller {
and a controller for statistics (get - how many people viewed the current task passed, post - add your name to the table of the finishers):
[AllowAnonymous] [Route("api/[controller]")] public class StatisticsController : Controller {
In order for the data from the server to come in a convenient javascript camelCase you need to add the following code to Startup.ConfigureServices:
services.AddMvc().Configure<MvcOptions>(options => { options.OutputFormatters .Where(f => f.Instance is JsonOutputFormatter) .Select(f => f.Instance as JsonOutputFormatter) .First() .SerializerSettings .ContractResolver = new CamelCasePropertyNamesContractResolver(); });
Change the model. EF teams.
After I learned about the new approach for migrations, of course I wanted to try it. Add another model - a list of people that have completed the quest and left their name at the end. The model is quite simple:
namespace HabraQuest.Models { public class Finisher { public int Id { get; set; } public string Token { get; set; } public string Name { get; set; } } }
EF commands can be run from the console if connected
"EntityFramework.SqlServer": "7.0.0-beta2",
"EntityFramework.Commands": "7.0.0-beta2",
This is what the command window looks like:

I'm not sure why yet, but I failed to create the migration the first time, perhaps due to my configuration changes. In order for it to work, you had to inherit the context from DbContext and create a configuration object inside the OnConfiguring context.
protected override void OnConfiguring(DbContextOptions options) { var efConfiguration = new Microsoft.Framework.ConfigurationModel.Configuration() .AddJsonFile("config.json") .AddEnvironmentVariables(); options.UseSqlServer(efConfiguration.Get("Data:DefaultConnection:ConnectionString")); }
But this way the previous migrations didn’t catch up, it’s time to delete a part of the generated code.
By the way, it’s time to get into azure from 10. It’s still not clear what the problems were.
Host in Azure ... 3 days
It would seem that everything is simple. Create a site in Azure, download a profile for publication, 2 clicks in the studio and that's it. Not here it was ... I guess these attempts I will remember for a lifetime. I spent 5 times more time than anything else to kill a site in Azure. An internal error (500) took off at some very early stage and could not even see because of what. At first I decided that some kind of functional is not yet supported. Began to try to host as basic functionality as possible. But all the other examples turned out well. I thought maybe some kind of problem with the base or migrations, but again, with simple examples, everything worked. In the end, began to look for a method of adding functionality a little bit. It turned out that everything falls due to:
Array.Empty<Finisher>()
I still do not understand - is (Empty <>) a new method from Core .NET or from somewhere else? And why Azure cannot work with it (most likely the version of the framework on Azure just does not know what it is).
Findings.
In general, I liked it. Of course there are moments that are damp. But I expected this. Also, instead of the expected several hours, it took much longer to write. Quite a bit has been written and documented what and how to use. There are a number of open questions:
- Will the migration work with the nuget manager console, and not with a regular console like this?
- What is logical to add to NPM packages, except grunt?
- What could be in Dependencies other than NPM and Bower packages?
- Why does Array.Empty <> work locally, but not work in Azure?
Maybe someone will help with the answers.
All innovations seem logical and enjoyable to develop. So let's hope that before the release all the little things will be finalized.
The sorts on the githaba.Link to the demo.UPDI will write again:
! The code does not carry any practical value, not refactored, written on the knee.