Статьи

Советы по использованию мобильных сервисов Azure .NET

Я работал с мобильными службами Azure с момента его выпуска, и до недавнего времени был доступен только бэкэнд JavaScript, созданный с использованием node.js. Несмотря на то, что у него много вариантов, оно требовало .NET, и теперь оно доступно.

На первый взгляд, похожий на стандартный проект Web API / MVC, может быть несколько вещей, которые вы хотели бы использовать в этих типах проектов, которые бросают вас в тупик при использовании новой опции .NET. К ним относятся внедрение зависимостей, Entity Framework (миграции и отношения) и страница справки.

Начиная

У вас есть два варианта начала проекта.

1. Перейдите на портал Azure, создайте новую мобильную службу Azure и загрузите проект
( http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet -получил / )

2. Запустите новый проект из Visual Studio 2013 с пакетом обновления 2 (SP2) и выберите «Интернет» -> «Windows Azure Mobile Service»

Для этого примера я выбрал вариант № 1 и назвал его « mytodotips ». Загрузите решение и обязательно соберите его, чтобы получить все необходимые пакеты nuget и убедиться, что ваша среда настроена.

Entity Framework, Code First, Миграция и Проблемы Отношений

Здесь есть несколько вещей, которые могут привести к тому, что вы почесываете голову, расстраиваете себя и, в зависимости от вашего характера, возможно, бросаете вещи. Итак, дай мне посмотреть, смогу ли я держать твою мышь в целости и сохранности.

Миграции

Сделай это первым! Откройте Консоль диспетчера пакетов, Инструменты -> Диспетчер пакетов NuGet -> Консоль диспетчера пакетов и введите следующую команду> enable-migrations.
В результате в вашем решении будет создана новая папка с именем «Миграции», содержащая файл с именем «Configuration.cs», таким образом, разрешается миграция кода при изменении схемы. Чтобы завершить изменение, откройте файл WebApiConfig.cs в папке «App_Start».

Закомментируйте Database.SetInitializer (…); линии, и вы также можете закомментировать или удалить класс, который вызывается внутри метода. Этот метод удаляет и воссоздает базу данных при каждом запуске приложения.

Вставьте следующий код над SetInitializer (…);  строка для вызова класса Configurator, только что созданного с помощью «enable-migrations», и явного применения последней миграции, если она еще не была применена.

var migrator = new DbMigrator(new Configuration());  
migrator.Update(); 

Следующие пространства имен также должны быть добавлены в ваш импорт:

using System.Data.Entity.Migrations;  
using mytodotipsService.Migrations;  

Откройте Консоль диспетчера пакетов и запустите add-миграцию init , при этом установите начальную миграцию и создайте таблицу миграции.

Теперь, когда вы добавляете в свои модели, вы можете запустить одно и то же «имя миграции» Add-Migration  в консоли диспетчера пакетов, а затем нажать F5, чтобы обновить базу данных локального компьютера или опубликовать в Azure, и запустить службу для обновления базы данных Azure SQL Server. ,

Отношения

Отношения довольно просты, однако в методе * OnModelCreating * есть несколько элементов обслуживания, которые помогают мне избежать некоторых ошибок при запуске «update-database» или «add -igration».

Каждый класс в мобильных службах Azure, имеющий таблицу позади, наследуется от EntityData,  который реализует _ITableData. _При создании связей FK вы можете получить ошибки при создании / изменении индексов. Установив в поле Id значение PK на столе, иногда их можно уменьшить.

modelBuilder.Properties<string>()  
    .Where(p => p.Name == "Id")
    .Configure(p => p.IsKey());

Еще одна опция, которую я также добавляю во все новые классы модели, заключается в следующем: это говорит базе данных, что поле Id генерируется автоматически и его не требуется устанавливать при создании нового класса.

modelBuilder.Entity<entityname>()  
    .Property(m => m.Id)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

Теперь это просто личное предпочтение, с которым, я уверен, многие не согласятся, но мне нравится, когда мои столы единичны.

modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();  

Внедрение зависимости

Некоторое время моим любимым механизмом DI был AutoFac, и я случайно обнаружил, что он встроен в серверную часть Azure Mobile .NET.

Теперь, когда у меня есть контекст Entity Framework Code First, все настроено так, как мне нравится, теперь я могу убедиться, что мне не нужно обновляться в каждом контроллере.

В нашем классе WebApiConfig.cs есть ServiceConfig.Initialize(...)вызов, чтобы начать процесс настройки приложения. Он принимает класс ConfigBuilder, принимающий параметры для вашей службы, но также имеет перегрузку, чтобы принять Func для регистрации ваших собственных зависимостей, который оказывается контейнером автозапуска.

Вот как можно добавить контекст базы данных, например, с помощью AutoFac.

HttpConfiguration config = ServiceConfig.Initialize(  
    new ConfigBuilder(options, (configuration, builder) =>  
    {        
        mytodotipsContext context = new mytodotipsContext();
        builder.RegisterInstance(context).As<mytodotipscontext>().SingleInstance();  }));

И теперь в нашем ToDoItemController.cs мы можем добавить конструктор и изменить метод Initializer следующим образом.

public class TodoItemController : TableController<todoitem>  
{ 
    mytodotipsContext context; 
    public TodoItemController(mytodotipsContext myContext) 
    {  
        this.context = myContext; 
    } 

    protected override void Initialize(HttpControllerContext controllerContext) 
    {  
        base.Initialize(controllerContext);    
        // mytodotipsContext context = new mytodotipsContext();  
        DomainManager = new EntityDomainManager<todoitem>(context, Request, Services);             }
}

Страница справки

Итак, у вас есть настройка Entity Framework со связями, Dependency Injection и AutoFac, и теперь вы просматриваете страницу справки и ничего не получаете. Что произошло?

Здесь есть несколько вопросов, которые мы хотим решить.

  • Где модель данных?
  • Я только хочу показать JSON
  • и еще несколько, как мы исправляем верхнюю модель 2Data. Отсутствует. Это распространенная проблема с сериализаторами, когда существуют циклические свойства. В этом случае есть класс Profile, который имеет элементы ToDo и свойство Profile. См. Code First Mapping здесь:

    modelBuilder.Entity<todoitems>().HasRequired(t => t.Profile)  
        .WithMany(p => p.ToDoItems)                
        .HasForeignKey(t => t.ProfileId);

Здесь происходит, когда JsonSerializer и XmlSerlizer начинают обходить дерево свойств; они попадают в бесконечный цикл и в итоге исчерпывают максимум ошибок и выходят. Чтобы это исправить, мы добавим следующее в класс WebApiConfig.cs внутри метода Register. * обратите внимание, только добавляя это для JsonFormatters, но также можно обрабатывать и для Xml.

config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;  

Теперь мы можем F5, увидеть страницу справки и объектную модель, представленную в Json, но поля application / xml и text / xml по-прежнему отображаются с ошибкой. Как упоминалось в нашем списке дел выше, мы хотели поддержать только Json. Для этого добавьте следующее в конфигурацию сейчас.

// Remove default XML handler
var matches = config.Formatters  
    .Where(f => f.SupportedMediaTypes         
    .Where(m => m.MediaType.ToString() == "application/xml" ||
        m.MediaType.ToString() == "text/xml")         
        .Count() > 0)     
        .ToList();

foreach (var match in matches)  
    config.Formatters.Remove(match);

И, наконец, мне нравится, когда дело касается Джсона.

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();  

Эта единственная строка сделает разработчиков JavaScript счастливыми. Вместо того, чтобы видеть объекты как это:

[    {        "Text": "sample string 1",        "Complete": true,        "Id": "sample string 3",        "__version": "QEBA",        "__createdAt": "2014-06-02T16:40:40.641Z",        "__updatedAt": "2014-06-02T16:40:40.641Z",        "__deleted": true    },

они правильно расположены так:

[    {        "text": "sample string 1",        "complete": true,        "id": "sample string 3",        "__version": "QEBA",        "__createdAt": "2014-06-02T16:40:40.641Z",        "__updatedAt": "2014-06-02T16:40:40.641Z",        "__deleted": true    }

Есть и другие функции, такие как Notification Hubs и Scheduled Jobs, которые являются отличным дополнением к любому приложению. Обязательно ознакомьтесь с ними при использовании мобильных служб Azure, независимо от того, используете ли вы .NET или JavaScript в качестве серверной части.

Оставьте комментарий, если у вас есть совет или трюк, который вы хотели бы использовать или передать также.