1 марта в 10:31

WCF REST сервисы и UWP приложения


Довольно частый вопрос, который возникает у тех кто пробует разрабатывать под UWP это «Как UWP приложению получить данные из базы данных SQL Server?». Напрямую данные получить нельзя. Работа с базами данных у UWP приложений требует настроенного веб-сервиса.

Разработчики клиентских приложений как правило далеки от созданий серверных бэкендов, но им необходимо иметь хотя бы представление о сервисах.

Под катом описание того как создать локальный WCF REST сервис и получить от него данные приложением UWP. Сервис сможет получать данные из базы данных SQL Server, созданной в Azure (но аналогично можно получить данные и из любой локальной базы). Дополнительно, чтобы все не выглядело сильно банально, будет рассмотрена возможность размещения самого сервиса в Azure для работы с ним из все того же клиентского UWP приложения.

Создание REST сервиса


Для того чтобы тестировать наши приложения UWP создадим простой сервис. Я опишу создание WCF, а не Web API 2 сервиса, так как последний раз интересовался написанием бэкенда несколько лет назад (а не потому что у него есть преимущества).



Удаляем код примера, который будет создан для нас автоматически

Код, который удаляется
Из IService1.cs
  [OperationContract]
        string GetData(int value);

        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);

        // TODO: Add your service operations here

  // Use a data contract as illustrated in the sample below to add composite types to service operations.
    [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }

Из Service1.svc.cs

       public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }


Добавляем в IService1.cs следующую операцию контракта и код класса:

    [ServiceContract]
    public interface IService1
    {
        [WebGet(UriTemplate = "/GetScheduleJson",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare)]
        List<Timetable> GetScheduleJson();
    }

    [DataContract]
    public class Timetable
    {
        [DataMember]
        public int id { get; set; }

        [DataMember]
        public DateTime arrivaltime { get; set; }

        [DataMember]
        public Int16 busnumber { get; set; }

        [DataMember]
        public string busstation { get; set; }
    }

Поле arrivaltime можно было бы сделать типа TimeSpan, но с типом DateTime гораздо удобнее впоследствии работать в JSON. В операции контракта можно указать и формат WebMessageFormat.Xml. Сама операция помечена атрибутом WebGet, а значит возвращает результат. При необходимости только выполнить код можно пометить операцию WebInvoke.

А в Service1.svc.cs добавляем следующий код:

        public List<Timetable> GetScheduleJson()
        {
            return GetSchedule();
        }

        private List<Timetable> GetSchedule()
        {
            List<Timetable> Schedule = new List<Timetable>
          {
            new Timetable
            {
                id=1, arrivaltime=DateTime.Parse("12:05:00"), busnumber=5, busstation ="Березка"
            },
            new Timetable
            {
                id=2, arrivaltime =DateTime.Parse("12:10:00"), busnumber=5, busstation ="Детский мир"
            }
          };
            return Schedule;
        }

Упрощенно сконфигурируем Web.config. Добавим endpointBehavior в раздел behaviors:

      <endpointBehaviors>
        <behavior name="restBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>

И ниже в уже существующий код в тэг behavior добавим атрибут name со значением «servicebehavior»:

     <serviceBehaviors>
        <behavior name="servicebehavior"> 
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>

Теперь в корень тега system.serviceModel можем добавить сервис и endpoint:

    <services>
      <service name ="ServiceForUWP.Service1" behaviorConfiguration ="servicebehavior" >
      <endpoint name ="RESTEndPoint" contract ="ServiceForUWP.IService1" binding ="webHttpBinding"
        address ="" behaviorConfiguration ="restBehavior"/>
      </service>
    </services>


Получаем готовый сервис.

Запустив отладку (при этом необходимо чтобы в Solution Explorer был выделен проект) и открыв в браузере (в моем случае порт 64870)
http://localhost:64870/Service1.svc/GetScheduleJson
получим результат в виде JSON:
[{«arrivaltime»:"\/Date(1487408400000+0300)\/",«busnumber»:5,«busstation»:«Березка»,«id»:1},{«arrivaltime»:"\/Date(1487408700000+0300)\/",«busnumber»:5,«busstation»:«Детский мир»,«id»:2}]

Если мы захотим возвращать данные отфильтрованные по какому-либо параметру, то можем изменить операцию на подобную:

        [WebGet(UriTemplate = "/GetScheduleJson/{id}",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare)]
        List<Timetable> GetScheduleJson(int id);

Теперь реализовав метод
List<Timetable> GetScheduleJson(int id)
мы получим результат зайдя по адресу http://localhost:64870/Service1.svc/GetScheduleJson/1. В данном случае 1 – это параметр, передаваемый методу.

Создание клиентского UWP приложения


Получить данные из приложения UWP проще простого. Есть 2 варианта: использовать Windows.Web.Http.HttpClient или же System.Net.Http.HttpClient.

Оба клиента могут быть использованы в UWP приложениях. Web чуть более новый (он вышел в 8.1), и он больше подходит для нативной разработки под UWP. Если же вы планируете использовать код в ASP.NET приложениях или в приложениях Xamarin под другие мобильные платформы, то вам лучше взять Net клиента. Кроме того на данный момент у Web клиента больше настроек и возможностей (например, возможность использования особого SSL сертификата для аутентификации).

Собственно, в .NET Core для приложений UWP, System.Net.Http это обертка над компонентом Windows.Web.Http. Но эта обертка поддерживает те же API, что и пространство System.Net.Http из .NET.

Далее два простых примера получения данных от сервиса:

var uri = new Uri("http://localhost:64870/service1.svc/GetScheduleJson");
            var client = new Windows.Web.Http.HttpClient();
            var json = await client.GetStringAsync(uri);

var uri = new Uri("http://localhost:64870/service1.svc/GetScheduleJson");
            System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
            System.Net.Http.HttpResponseMessage responseGet = await client.GetAsync(uri);
            string json = await responseGet.Content.ReadAsStringAsync();

Для того, чтобы десериализовать данные можно использовать NuGet пакет Newtonsoft.Json:

   
       List<Timetable> appsdata = JsonConvert.DeserializeObject<Timetable>(json);

Конечно, необходимо добавить еще и код класса Timetable (точно такой же как и в приложении сервиса).

Создание базы данных SQL Server в Azure


Создать базу данных в Azure несложно. Нужно зайти на портал и заполнить следующие поля:



Останется только выбрать ценовую категорию. Цены начинаются от 5 USD за месяц. Эту сумму вполне себе покроет бонус, получаемый от бесплатной регистрации в Dev Essentials (25 USD дается каждый месяц в течение года). При регистрации необходимо привязывать карточку. Для подобных регистраций, как правило, создается дополнительная карточка, лимит которой можно регулировать.

Строка подключения ASP.NET (проверка подлинности SQL) к базе данных в таком случае будет:

Server=tcp:timetableserverok.database.windows.net,1433;Initial Catalog=timetabledb;Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;

Ее можно посмотреть, зайдя в свойства базы данных на портале Azure. Для того чтобы получить возможность доступа к базе данных с текущей машины необходимо добавить ее IP в список брандмауэра.



Редактирование возможно из окна Server Explorer Visual Studio





Создадим какую-нибудь таблицу



И внесем любые тестовые данные.

Получение сервисом данных из базы SQL Server-а


Для того чтобы «вытянуть» данные из базы нам необходимо внести небольшие изменения в проект нашего сервиса. Добавить два пространства имен:

using System.Data;
using System.Data.SqlClient;

Переменную содержащую текст строки подключения к базе SQL Server:

public string ConnectionString = "Server=tcp:timetableserverok.database.windows.net,1433;Initial Catalog=timetabledb;Persist Security Info=False;User ID=alexej;Password=ЗДЕСЬ_ПАРОЛЬ;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;";

Я использую только что созданную базу в Azure, но, как уже упоминал, можно подключаться к любым базам данных в том числе и локальным (строку подключения в таком случае, конечно, необходимо будет заменить).

Теперь, чтобы «вытянуть» данные из базы, необходимо изменить код метода GetSchedule на следующий:

         private List<Timetable> GetSchedule()
        {
            using (DataSet ds = new DataSet())
            {
                using (SqlConnection sqlCon = new SqlConnection(ConnectionString))
                {
                    try
                    {
                        sqlCon.Open();
                        string sqlStr = "select * from Timetable";
                        using (SqlDataAdapter sqlDa = new SqlDataAdapter(sqlStr, sqlCon))
                        {
                            sqlDa.Fill(ds);
                        }
                    }
                    catch
                    {
                        return null;
                    }
                    finally
                    {
                        sqlCon.Close();
                    }
                }

                List<Timetable> Schedule = new List<Timetable>();

                using (DataTable dt = ds.Tables[0])
                {
                    foreach (DataRow dr in dt.Rows)
                    {
                        Schedule.Add(new Timetable()
                        {
                            id = Convert.ToInt16((dr["ID"])),
                            arrivaltime = DateTime.Parse(dr["arrivaltime"].ToString()),
                            busnumber = Convert.ToInt16((dr["busnumber"] ?? 0)),
                            busstation = dr["busstation"].ToString()
                        });
                    }
                }
                return Schedule;
            }
        }

Создание облачного сервиса


Для того чтобы разместить сервис в Azure необходимо скачать и установить Azure SDK for .NET (приблизительно 450 Мб) и создать новый проект особого типа Cloud Service.



Выбираем роль и переименовываем на свой вкус



В результате у нас будет создано два проекта: AzureCloudServiceTimetable и TimetableService
В второй (TimetableService) мы можем скопировать код из нашего локального сервиса. А именно – содержимое файлов IService1.cs, Service1.svc.cs, Web.config. После этого проект можно протестировать. В файле Web.config перед публикацией можно сделать изменения. В теге

<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>

изменить значения на false

Для публикации на Azure необходимо создать пакеты. На проекте AzureCloudServiceTimetable нужно вызвать контекстное меню и выбрать Package.



После окончания процесса будет открыта директория с пакетом и конфигурационным файлом.
Опубликовать на Azure можно с помощью веб интерфейса портала. Заходим на портал. Выбираем пункт Облачные службы (классические), создаем новый и заполняем поля



Необходимо установить 2 флажка: «Развернуть, даже если одна или несколько ролей содержат отдельный экземпляр» и «Запустить развертывание». После развертывания и запуска (запуск может занять некоторое время) можно будет делать запрос по URI:

http://servicetimetable.cloudapp.net/Service1.svc/GetScheduleJson

Этот адрес можно использовать в приложении UWP. Подробнее о развертывании: Создание и развертывание облачной службы

PS: Спасибо пользователю dmitry_dvm за уточнения/правки
Алексей Соммер @asommer
карма
49,2
рейтинг 12,0
разработка универсальных приложений Windows
Похожие публикации
Самое читаемое Разработка

Комментарии (34)

  • +2
    1. Какие преимущества у wcf-сервиса перед приложением Web API?
    2. Как-то длинно десериализуете json. Можно же же примерно так:
    List appsdata = JsonConvert.DeserializeObject<List>(jsonString);
    • 0
      1. Сравнение доступно здесь: WCF и ASP.NET Web API
      2. А если есть что-то невалидное?
      • 0
        1. Спасибо за ссылку.
        Там как раз написано «Хотя WCF предоставляет некоторую поддержку написания служб в стиле REST, поддержка REST в ASP.NET Web API более полная и все последующие улучшения функций REST будут вноситься в ASP.NET Web API».
        Значит Web API всё-таки больше подходит.

        2. Парсер съел немного кода. А как вам такой вариант вспомогательного метода? Тогда в списке гарантированно будут только объекты Timetable.

        public static List<T> DeserializeToList<T>(string jsonString)
        {
            var array = Newtonsoft.Json.Linq.JArray.Parse(jsonString);
        
            return array.OfType<Timetable>().ToList();  
        }
        
        • 0
          По поводу того что ASP.NET API больше подходит я согласен (и с вами и с документацией). Но мне по старой памяти знаком WCF, потому и написал о нем.
          Касательно сниппета, да, пожалуй длинноват, но он в оригинальном виде пропускал ошибочные элементы.

          Спасибо за уточнения/дополнения/исправления!
          • 0
            В любом случае спасибо за статью, буду знать, что из UWP можно к wcf цепляться и как именно это делать.
    • +1
      // ironic mode on

      WebApi Client в .Net — это слишком просто.
      Twitter — норм, но не для хабра статья :)
      var user = new
      {    
          UniqUserId = "fsfdsfdsfdsfds",
          PlatformId = 2,    
          Culture_Code = 1033
      };
      var h = new HttpClient();
      var task = h.PostAsJsonAsync("http://hostname.com/api/users", user);
      

      • 0
        user — анонимная структура? Сомневаюсь, что вы в реальных проектах так пишете.
  • –1
    UWP маздай
    • 0
      А что взамен? Или вы просто решили испортить воздух и уйти?
      • 0
        Взамен — для кого? Для пользователя обычное win32 или .net приложение, суть бинарник+ресурсы, файлы то бишь — самое то. UWP — это из разряда «я на айфон скидываю песни, а не файлы»
        • 0
          Вы в пещере живете? Интерфейс win32-приложений как минимум неудобен на тач-экранах. У UWP куча преимуществ, начиная от жизненного цикла и заканчивая поддержкой пушей. Уж не говоря про самую суть UWP — универсальность.
          • 0

            А вы видимо на луне. Так вот у нас тут на земле win32/winforms приложение работает в разы быстрее и жрёт на два порядка меньше мозгов, а доля этого вашего UWP что на десктопе что на тачскринах до смешного мала


            UWP — универсальность.

            вы о чём сейчас? мстите таким образом за порчу воздуха?

            • 0
              Абсолютно также я думал про Java в начале 2000-х.
              • 0

                Ну так Майкрософт в отличие от Оракла прославились тотальным забиванием на такого рода проекты — WPF, Silverlight, WinRT и COM как бы намекают на будущее UWP. Тем более что выстрелил Electron, который уже сейчас поимел UWP по стоимости разработки, производительности и уровню инструментов. И это при том что Electron действительно кросплатформенный и универсальный, а не только в фантазиях хипстеров, находящихся в плену религиозного дурмана от хайпа, поднятого евангелистами Майкрософт

                • 0
                  UWP, вроде, на кроссплатформенность и не претендовал, зачем в одну кучу-то. Так что если сравнивать, то уже, например, Xamarin с Electron'ом…

                  А можно цифры какие-нибудь про то, куда Electron «выстрелил» и кого «поимел»?
                  • 0

                    ну так там выше было — "Уж не говоря про самую суть UWP — универсальность." А кросплатформенность — это как бы в довесок, такой нокаут для UWP от конкурента.


                    Хамарин — это вы вообще не в тему, он не про десктоп совсем.


                    У меня в W10 разница ощущается и без цифр. Электронвские виджеты и аппы ещё туда сюда, uwp-шные стоят раком. Ну и да, для своих задач я таки тестировал FPS и потребление памяти на виртулизированном GridView с кастомным контентом ячеек для UWP и аналогичное с таблицами на Electron + react. На 90% кэйсах электрон был лучше на 15-20%. И это при том, что uwp нагинает проц на 100% и жрёт под гиг оперативки, электрон ничего подобного и близко не делает. Результат как бы предсказуем, если принять во внимание, что UWP унаследовала все врождённые уродства WPF, а именно MVVM через Data Binding через INotifyPropertyChanged (дыры в типизации, невозможно нормально отлаживать, тормоза) и хамл (неизбежные утечки памяти на темплейтной разметке). Иммутабельный вью? — не, не слышали. Реактивность? — а зачем? и так схавают.

                    • +3
                      Я как-то радости с Elecron'а, как юзер, не разделяю совсем. Слак у меня на маке частенько сливается в жутчайшую тормозню после недельного аптайма, да и VSCode как-то стабильностью не радует, но это частный случай, конечно. Потому так заинтересовали цифры

                      А про универсальность вы по-моему недопоняли — имеется ввиду универсальность для любой инкарнации Windows 10: от телефонов и IoT, до Xbox и десктопов. То есть одна аппка на любую Windows 10 среду. Universal Windows Platform. Сравнивать такую универсальность, на мой взгляд, на данный момент, не с чем особо… Андроид, возможно?
                      Для кроссплатформенности есть Xamarin — macOS-таки десктопная ось
                      Для линуксей и всяких Unity3D есть .NET Core, который, как правильно заметили ниже, очень близок к UWP. Нам, по-крайне мере, в проектах неплохо получается шарить очень много кода между WPF, Xamarin и и UWP. В принципе, большая часть логики подходит всему (про дотнет отлично здесь расписано (частенько всем подкидываю) — http://www.hanselman.com/blog/WhatNETDevelopersOughtToKnowToStartIn2017.aspx)

                      UWP и WPF, конечно, прожорливей веба.
                      И про типизацию, пожалуй, соглашусь. Но это плата за отделение View'ов от логики, которую мы с радостью платим.
                      А остальное, по ощущениям, основывается у вас либо на опыте с WPF и Silverlight'ом трехлетней давности (там все уже совсем не так плохо и с каждой новой студией становится лучше и лучше), либо на точно таком же новомодном хайпе о реактивности и иммьютабл вьювов, то есть, холиварной теме
                      • –1

                        да вроде как на маке какие то проблемы с самим хромиумом, по крайней мере очень много issues именно для макоси.


                        Не, я понимаю что они имели сказать под U. Но тут поинт в том, что майкрософтские телефоны, иксбоксы и железки никому нафик не нужны, их и доля на рынке изначально мизерна и постоянно уменьшается. то есть универсальность у них сводится к десктопной W10, что конечно есть обман чистой воды. Такой банальный комерческий булшэт, которым майкрософтцы постоянно злоупотребляют.


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


                        Так и я тоже шарю, чего уж. Отсюда и негативные впечатления от опыта с UWP. Там, где у меня перформанс упирался в дно на WPF (и приходилось даунгрейдится в winforms/MFC), там же он упирается на UWP в то же дно.


                        Силверлайт ушёл в небытие уже боле чем три года тому. А WPF разве что то поменялось за это время? Что там становится лучше, я например в упор не вижу. Оптимизация отрисовки через DirectX как была хуже некуда так и осталась ( https://jeremiahmorrill.wordpress.com/2011/02/14/a-critical-deep-dive-into-the-wpf-rendering-system/ ), memory leaks при разворачивании темплейтов в хамл тоже на месте.


                        Ну как на хайпе, если я регулярно в рамках борьбы с тормознутостью WPF залажу внутрь её компонентов и наблюдаю там тяжёлые вычисления, тупо повторяющиеся многократно в пределах одной итерации отрисовки? Реактивность — это отнюдь не блажь)


                        про саппорт net core я пока не понел вообще в чём прикол. Что это даёт, если тулинг там пока ещё на уровне пререлизов и сам net core в новорождённом состоянии? и вообще не понятно что там будет поддерживаться в будущем. К примеру F#-пные сборки под net core UWP отказывается линковать

                        • +1
                          У вас явно проблемы с проектированием интерфейсов или их реализацией, раз вы всё время куда-то упираетесь. Про виртуализацию списков, асинхронность, x:Bind что-нибудь слышали? Даунгрейдьтесь в дос, чего уж там.
                          • –1

                            Да, майкрософт непогрешим, их архитектурные решения идеальны, а если что-то пошло не так, разбей зеркало, алилуйа!


                            Про виртуализацию списков, асинхронность, x:Bind что-нибудь слышали?

                            что именно даёт вам основание полагать будто бы не слышал кроме спеси?


                            Даунгрейдьтесь в дос, чего уж там.

                            обоснуйте

                            • +1
                              Чтобы упереться в перфоманс нужны тысячи элементов на экране. По моему опыту это могут дать только списки со сложными шаблонами и без виртуализации. Ну или совсем уж кривая верстка с кучами наслоений. Уменьшить пожирание памяти позволяют как раз таки компилируемые байндинги. Покажите пример, который расставит все по местам. Пока я вижу лишь брызганье слюной. Про выстреливший электрон вообще смешно читать. Он выстрелил не больше чем Adobe Air в свое время. Это ваше заявление, кстати, иллюстрирует как минимум вашу профдеформацию, а как максимум — некомпетентность.
                              • 0
                                Чтобы упереться в перфоманс нужны тысячи элементов на экране

                                Да-да. Именно так всё и происходит в глазах хипстоты. А чего не 500 или не 100500? Ну и где ваши цифры, отражающие, что именно вы в данном случае понимаете под критической производительностью?


                                Покажите пример, который расставит все по местам.

                                VS2010+, MS Oficce


                                Пока я вижу лишь брызганье слюной.

                                так и я от вас ничего не вижу кроме раздутого ЧСВ и агрессии


                                Он выстрелил не больше чем Adobe Air в свое время.

                                Мы с вами видимо в разных параллельных вселенных живём. В моей на Adobe Air не написана ни одна IDE

                        • 0
                          У рефита есть одна странная, но серьезная проблема. Во-первых он не работает искаропки с queryStrings, а во-вторых он урлэнкодит гет-параметры и с этим походу ничего не сделать. Там где надо ¶m=blabla он заменяет на "%**", который сервер, к сожалению не может распознать. Да, возможно это проблема сервера, но гибкости в клиенте мне не хватило. Ковырялся несколько дней и вернулся на рестшарп.
                          • 0
                            Спасибо. Я в свое время поигрался. Проблем не было.
        • 0
          По сути UWP тот же .NET, но с некоторыми ограничениями. Это как минус привычному для разработчиков функционалу, так и плюс безопасности и масштабируемости. Зато платформа определенно гораздо более современна и близка кроссплатформенной .NET Core.
          • 0
            плюс безопасности и масштабируемости

            в чём именно проявляется этот плюс?


            близка кроссплатформенной .NET Core.

            на основании чего вы пришли к такому выводу?

            • 0
              1. Попробуйте получить из приложения UWP доступ к системным файлам. Да к любым файлам на диске, которые не выбраны пользователем лично и не относятся с самому приложению.

              2. Обратите внимание на пакет Microsoft.NETCore.UniversalWindowsPlatform который устанавливается автоматически с каждым приложением.
              • 0
                ну так uwp с большого .net на .net core перевели уже
            • 0
              http://ru.stackoverflow.com/questions/514358/%d0%92-%d1%87%d0%b5%d0%bc-%d1%80%d0%b0%d0%b7%d0%bd%d0%b8%d1%86%d0%b0-%d0%bc%d0%b5%d0%b6%d0%b4%d1%83-netframework-%d0%b8-netcore/592758#592758

              Наконец, .NET Core — это нижележащая инфраструктура, от которой зависит .NET Native. Когда проектировали .NET Native, стало понятно, что .NET Framework не подойдет в качестве фундамента для библиотек классов этой инфраструктуры. Дело в том, что .NET Native статически связывает инфраструктуру с приложением, а затем удаляет все лишнее, что не нужно приложению. (Здесь я сильно упрощаю общую картину, но идею вы уловили. Подробнее на эту тему см. «Inside .NET Native» по ссылке bit.ly/1UR7ChW.)
  • –1

    И в чём тут цимес? что здесь есть по вашему полезного или познавательного чтобы вчитываться в приведенный вами бойлерплейт с унылыми конфигами?


    Напрямую данные получить нельзя. Работа с базами данных у UWP приложений требует настроенного REST сервиса.

    Кто вам такое сказал? Элементарно можно получить без WCF, Azure и прочих костылей .

    • 0
      Расскажите как, а лучше статью напишите.
  • 0
    https://marketplace.visualstudio.com/items?itemName=FrankTvandeVen.VenturaSqlServerforWindows10UWPApps и не мучайтесь.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.