среда, 2 мая 2012 г.

ASP.Net MVC4 Мобильный Учебник - Часть 3

Резюме
Продолжая нашу дискуссию вокруг ASP.Net MVC4 Mobile application, это окончательное сообщение будет обсуждать заключительную часть, пользовательского интерфейса и, как все это идет вместе.

Пользовательский интерфейс
По умолчанию проект использует JQuery Mobile плагин для таргетинг на мобильные устройства.Плагин JQuery Mobile сенсорный оптимизирован для смартфонов и планшетов и целей IOS, Android, Blackberry, Bada, Windows Phone, Palm WebOS, Symbian и MeeGo.
Начнем с логикой JavaScript, который будет осуществлять взаимодействие пользовательского интерфейса HTML и JSON веб сервиса.
  • В папке Scripts, добавить папку с именем com, в эту папку добавить папку sukul, и наконец, добавить папку babyfeeding в sukul.
  • В конечном папке babyfeeding, добавить файл JavaScript и назвать его proxy.js
  • Скопируйте и вставьте следующий код в файл JS
  • if (Sukul == undefined) var Sukul;
    if (!Sukul) Sukul = {};
    
    //Constructor
    Sukul.Proxy = function (siteBaseUrl) {
        // constructor
        Sukul.Proxy.prototype.baseUrl = siteBaseUrl;
        Sukul.Proxy.prototype.heartBeatUrl = 
    siteBaseUrl + "/Services/BabyMonitorService.svc/HeartBeat";
        Sukul.Proxy.prototype.FeeedingUrl = 
    siteBaseUrl + "/Services/BabyMonitorService.svc/AddFeedingEntry"
        Sukul.Proxy.prototype.DiaperingUrl = 
    siteBaseUrl + "/Services/BabyMonitorService.svc/AddDiaperingEntry"
    }
    
    Sukul.Proxy.prototype = {
        CallWebService: function (url, input, successCallBack, 
    errorCallBack) {
            //Uncomment the next line to support JSONP
            //url = url + "?callback=?";       
            $.ajax({
                async: false,
                cache: false,
                type: "GET",
                contentType: "application/json; charset=utf-8",
                url: url,
                dataType: "json",
                data: input,
                success: successCallBack,
                error: errorCallBack
            });
    
        },
    
        HeartBeat: function (successFunction, failFunction) {
            this.CallWebService(this.heartBeatUrl, ""
    successFunction, failFunction);
        },
        AddFeeding: function (UserId, FeedType, FeedAmount, 
    successFunction, failFunction) {
            var input = "UserId=" + UserId + "&FeedType="
    FeedType + "&FeedAmount=" + FeedAmount;
            this.CallWebService(this.FeeedingUrl, input, 
    successFunction, failFunction);
        },
        AddDiapering: function (UserId, DiaperType, 
    successFunction, failFunction) {
            var input = "UserId=" + UserId + "&DiaperType="
    DiaperType;
            this.CallWebService(this.DiaperingUrl, input, 
    successFunction, failFunction);
        }
    };
  • JavaScript структурирована для использования объектов и пространств имен. Каждый объект JavaScript содержит внутренний класс Prototype. Определяя методы этого внутреннего класса, мы можем инкапсулировать объект переменных и методов и обмениваться ими через конкретные экземпляры класса. В коде выше, объект Proxy определяет следующие методы:
    • CallWebService - вспомогательный метод для вызова службы JSON
    • HearBeat - вызывает метода Heat для диагностики
    • AddFeeding - создает канал вступление взяв ввод из формы и вызова веб-сервисов
    • AddDiapering - создает запись для смены пеленок, взяв ввод из формы и вызова веб-сервисов
  • Наконец, мы инкапсулировали объект Proxy внутри объекта Sukul для создания пространства имен, так что к объект Proxy можно ссылаться вот так: Sukul.Proxy
Просмотр Index.cshtml
Скопируйте и вставьте следующий код в страницу Index
@{
    ViewBag.Title = "Baby Log Home";
}

<script type="text/javascript">
    $(document).ready(function () {
        $("#btnSubmit").click(function () {

            $("#txtLastEntry").val("Last: ");

            // создание proxy class
            var proxy = new Sukul.Proxy("@Request.Url.GetLeftPart(
UriPartial.Authority)");
            // добавление заспис feeding
            if ($("#chkFeed").attr("checked") != undefined && 
$("#chkFeed").attr("checked") == "checked") {
                proxy.AddFeeding("@Membership.GetUser().UserName"
$("#drpType").val(), $("#drpAmount").val(),
                    function (result) {
                        // успешно
                        $("#txtLastEntry").val($("#txtLastEntry").val() + 
$("#drpAmount option:selected").text() +
                        " of " + $("#drpType option:selected").text());
                    },
                    function (jqXHR, textStatus, errorThrown) {
                        // безуспешно
                        var err = "Details: " + textStatus;
                        if (errorThrown != undefined) {
                            err += "\rMore details : " + errorThrown;
                        }
                        alert(err);
                    });
            }
            // добавление заспис diapering
            if ($("#chkDiaper").attr("checked") != undefined && 
$("#chkDiaper").attr("checked") == "checked") {
                proxy.AddDiapering("@Membership.GetUser().UserName"
$("#drpDiaper").val(),
                    function (result) {
                        // успешно
                        $("#txtLastEntry").val($("#txtLastEntry").val() 
+ ", " + $("#drpDiaper option:selected").text() + " diaper");
                    },
                    function (jqXHR, textStatus, errorThrown) {
                        // безуспешно
                        var err = "Details: " + textStatus;
                        if (errorThrown != undefined) {
                            err += "\rMore details : " + errorThrown;
                        }
                        alert(err);
                    });
            }
        });
    });
</script>
<div data-role="fieldcontain" data-inset="true">
    <fieldset data-role="controlgroup">
        <legend>Feed Details</legend>
        <input id='chkFeed' name='chkFeed-1' type="checkbox" 
checked="checked" class="custom" />
        <label for="chkFeed">
            Log Feed</label>
    </fieldset>
    <fieldset data-role="controlgroup">
        <legend>Feed Type:</legend>
        @Html.DropDownList("drpType", new List<SelectListItem> { 
            new SelectListItem { Text="Bottle", Value="Bottle"
Selected=true }, 
            new SelectListItem { Text="Left", Value="Left" }, 
            new SelectListItem { Text="Right", Value="Right" }, 
        })
    </fieldset>
    <fieldset data-role="controlgroup">
        <legend>Amount:</legend>
        @Html.DropDownList("drpAmount", new List<SelectListItem> { 
            new SelectListItem { Text="0.5 oz.", Value="0_5" }, 
            new SelectListItem { Text="1.0 oz.", Value="1_0" }, 
            new SelectListItem { Text="1.5 oz.", Value="1_5" }, 
            new SelectListItem { Text="2.0 oz.", Value="2_0" }, 
            new SelectListItem { Text="2.5 oz.", Value="2_5", Selected=true }, 
            new SelectListItem { Text="3.0 oz.", Value="3_0" }, 
            new SelectListItem { Text="3.5 oz.", Value="3_5" }, 
            new SelectListItem { Text="4.0 oz.", Value="4_0" }, 
            new SelectListItem { Text="4.5 oz.", Value="4_5" }, 
            new SelectListItem { Text="5.0 oz.", Value="5_0" }, 
            new SelectListItem { Text="5.5 oz.", Value="5_5" }, 
            new SelectListItem { Text="6.0 oz.", Value="6_0" }, 
            new SelectListItem { Text="6.5 oz.", Value="6_5" }, 
            new SelectListItem { Text="7.0 oz.", Value="7_0" }, 
            new SelectListItem { Text="7.5 oz.", Value="7_5" }, 
            new SelectListItem { Text="8.0 oz.", Value="8_0" }, 
            new SelectListItem { Text="8.5 oz.", Value="8_5" }, 
            new SelectListItem { Text="9.0 oz.", Value="9_0" } 
        })
    </fieldset>
</div>
<div data-role="fieldcontain" data-inset="true">
    <fieldset data-role="controlgroup">
        <legend>Diaper Details</legend>
        <input id='chkDiaper' name='chkDiaper-1' type="checkbox" 
class="custom" />
        <label for="chkDiaper">
            Log Diaper</label>
    </fieldset>
    <fieldset data-role="controlgroup">
        <legend>Diaper:</legend>
        @Html.DropDownList("drpDiaper", new List<SelectListItem> {
            new SelectListItem { Text="Wet", Value="wet", Selected=true },
            new SelectListItem { Text="Dirty", Value="dirty" },
            new SelectListItem { Text="Both", Value="both" }
        })
    </fieldset>
</div>
<div data-role="fieldcontain" data-inset="true">
    <input id="btnSubmit" type="submit" value="Submit" data-role="button" />
    <fieldset data-role="controlgroup">
        <input id="txtLastEntry" readonly="readonly" type="text" />
    </fieldset>
</div>
HTML код создает форму ввода для ввода питания и детали смены пеленок и код JavaScript, собирает входные, создает класс Proxy и вызывает его методы для вызова веб-службы.
 
Жду ваши комментарии...
 

воскресенье, 29 апреля 2012 г.

ASP.Net MVC4 Мобильный Учебник - Часть 2

Резюме
В последнее сообщение , мы рассмотрели проектирование баз данных и Entity Model для ASP.Net MVC4 Mobile application. Мы будем продолжать с уровня обслуживания в этой статье.

Service Layer
Мы определим некоторые методы в нашей класса обслуживания для ввода данных в таблицы SQL наш лог.
  • Щелкните правой кнопкой мыши проект, выберите Add-> New Folder и называем его Service.
  • Щелкните правой кнопкой мыши папку Service, выберите Add, New Item и нажмите на WCF службу. Имя службы
Новые службы WCF
  • Обновите system.serviceModel раздел в файле web.config, чтобы она выглядела следующим образом:

  • <system.serviceModel>
        <bindings>
          <webHttpBinding>
            <binding name="customWebHttpBinding">
              <security mode="None"></security>
            </binding>
          </webHttpBinding>
        </bindings>
        <behaviors>
          <endpointBehaviors>
            <behavior  
    name="JSLearning.Services.BabyMonitorServiceBehavior">
              <enableWebScript />
            </behavior>
          </endpointBehaviors>
          <serviceBehaviors>
            <behavior name="DebugBehavior">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug  
    includeExceptionDetailInFaults="true" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <services>
          <service name="JSLearning.Services.BabyMonitorService"  
    behaviorConfiguration="DebugBehavior">
            <endpoint address="" 
    behaviorConfiguration=
    "JSLearning.Services.BabyMonitorServiceBehavior" 
    binding="webHttpBinding"  
    contract="JSLearning.Services.IBabyMonitorService" 
    bindingConfiguration="customWebHttpBinding" />
            <endpoint address="mex" binding="mexHttpBinding"  
    contract="IMetadataExchange" />
          </service>
        </services>
        <serviceHostingEnvironment 
    multipleSiteBindingsEnabled="true" />
      </system.serviceModel>

  • В папке Service, добавить ServiceBase класса, а затем скопируйте и вставьте следующий код к ней. Класс ServiceBase предоставляет полезные методы для взаимодействия с моделью EDM
  •  
    public class ServiceBase
        {
            private BabyLogEntities _context = null;
            private string _connectionString = string.Empty;
    
            protected ServiceBase()
            {
                RenewContext();
            }
    
             protected ServiceBase(string connectionString) {
                 _connectionString = connectionString;
                 _context = new BabyLogEntities(_connectionString);
            }
    
            protected BabyLogEntities Context
            {
                get
                {
                    return _context;
                }
            }
    
            protected void RenewContext()
            {
                 if (_connectionString == string.Empty)
                 {
                     _connectionString = 
    System.Configuration.ConfigurationManager.
    ConnectionStrings["BabyLogEntities"].ConnectionString;
                 }
                 _context = new BabyLogEntities(_connectionString);
                return;
            }
    
        } 
    
    
     
  • Редактировать BabyMonitorService.svc.cs файл и он наследует от ServiceBase.cs 
public class BabyMonitorService : ServiceBase, IBabyMonitorService
  • Скопируйте и вставьте следующий код в ваш интерфейс IBabyMonitorService.cs

[ServiceContract]
    public interface IBabyMonitorService
    {
        [OperationContract]
        [WebMethod]
        [WebInvoke(Method = "GET", ResponseFormat = 
WebMessageFormat.Json, BodyStyle = 
WebMessageBodyStyle.WrappedRequest)]
        string HeartBeat();

        [OperationContract]
        [WebMethod]
        [WebInvoke(Method = "GET", ResponseFormat = 
WebMessageFormat.Json, BodyStyle = 
WebMessageBodyStyle.WrappedRequest)]
        string AddFeedingEntry(string UserId, 
string FeedType, string FeedAmount);

        [OperationContract]
        [WebMethod]
        [WebInvoke(Method = "GET", ResponseFormat = 
WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        string AddDiaperingEntry(string UserId, string DiaperType);
    }
  • Откройте BabyMonitorService.svc.cs файл и добавить следующий код:
public class BabyMonitorService : ServiceBase, IBabyMonitorService
    {
        public BabyMonitorService() : base()
        { }

        /// <summary>
        /// Check that the service is available
        /// </summary>
        /// <returns></returns>
        public string HeartBeat()
        {
            return "Service is alive";
        }

        /// <summary>
        /// Add a feed entry
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="FeedType"></param>
        /// <param name="FeedAmount"></param>
        /// <returns></returns>
        public string AddFeedingEntry(string UserId, string FeedType, 
string FeedAmount)
        {
            Models.WebServiceResponse response =  
new Models.WebServiceResponse();
            try
            {
                var log = new FeedingLog
                {
                    ID = Guid.NewGuid(),
                    DateCreated = DateTime.Now,
                    FeedType = FeedType,
                    // since IIS does not like the . 
                    // character, we are passing 
                    // decimals as x_y and converting to x.y
                    FeedAmount = 
Decimal.Parse(FeedAmount.Replace("_", ".")),
                    UserID = UserId
                };

                RenewContext();
                Context.AddToFeedingLogs(log);
                Context.SaveChanges();

                response.IsSuccess = true;
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.ErrorMessage = ex.Message;
            }
            return SerializeAsJSON(response);
        }

        /// <summary>
        /// Add an entry for a diaper change
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="DiaperType"></param>
        /// <returns></returns>
        public string AddDiaperingEntry(string UserId,  
string DiaperType)
        {
            Models.WebServiceResponse response =  
new Models.WebServiceResponse();
            try
            {
                var log = new DiaperLog
                {
                    ID = Guid.NewGuid(),
                    DateCreated = DateTime.Now,
                    DiaperType = DiaperType,
                    UserID = UserId
                };

                RenewContext();
                Context.AddToDiaperLogs(log);
                Context.SaveChanges();

                response.IsSuccess = true;
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.ErrorMessage = ex.Message;
            }
            return SerializeAsJSON(response);
        }

        /// <summary>
        /// Serializes an object to JSON
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        private string SerializeAsJSON(
Models.WebServiceResponse response)
        {
            using (MemoryStream s = new MemoryStream())
            {
                DataContractJsonSerializer ser =  
             new DataContractJsonSerializer( 
typeof(Models.WebServiceResponse));
                ser.WriteObject(s, response);
                s.Position = 0;
                using (StreamReader sr = new StreamReader(s))
                {
                    return sr.ReadToEnd();
                }
            }
        }
    }
  • Код очень прост, он использует Entity Model чтобы сделать запись в соответствующие таблицы и возвращает WebServiceResponse объект в формате JSON.
  • В папке модели, добавить класс WebServiceResponse и добавьте следующий код. WebServiceResponse это хороший способ, чтобы вернуть объект в качестве ответа JSON, и она может содержать много деталей из службы, а не просто сообщение об ошибке строки. Проверьте класса обслуживания чтобы видеть, как этот объект построен.
  •   [DataContract]
        public class WebServiceResponse
        {
            /// <summary>
            /// Indicates if the web service call was successful
            /// </summary>
            [DataMember]
            public bool IsSuccess = false;
            /// <summary>
            /// Contains the response message from the service
            /// </summary>
            [DataMember]
            public object Payload = "Object not assigned";
            /// <summary>
            /// Contains a friendly error message if the service 
            /// encountered an exception
            /// </summary>
            [DataMember]
            public string FriendlyErrorMessage = string.Empty;
            /// <summary>
            /// Contains the full text of the exception, 
            /// if one occurred
            /// </summary>
            [DataMember]
            public string ErrorMessage = string.Empty;
            /// <summary>
            /// Contains the exception trace, if one occurred
            /// </summary>
            [DataMember]
            public string ErrorStackTrace = string.Empty;
            /// <summary>
            /// Contains the date and time of the service
            /// response in UTC format.
            /// </summary>
            [DataMember]
            public string UTC_DateOfResponse = 
    DateTime.Now.ToUniversalTime().ToString("dd MMM yyyy hh:mm:ss tt");
        }
  • На данный момент мы должны быть в состоянии компиляции проекта и перейдите к службе.
  • Можно также вызвать метода HeartBeat от предыдущих, если ваш сервис работает корректно. Обратите внимание, вам нужно сохранить ответ JSON, а затем открыть его в блокноте, чтобы увидеть результаты
Ответ службы WCF

ASP.Net MVC4 Мобильный Учебник - Часть 1

Резюме
ASP.NET MVC 4 Developer Preview вводится новый шаблон для мобильных веб-приложений, которые используют JQuery Mobile  - специальную библиотеку JQuery для создания мобильных пользовательских интерфейсов.

Приступая к работе
Вам понадобится один из следующих эмуляторов для тестирования кода:
Построение решения
  • Установка ASP.Net MVC 4 от сюда 
 Запустите Visual Studio 2010, выберите новый проект, затем выберите Web и выберите "ASP.Net MVC 4 Web Application"

 В списке шаблонов проектов, выберите "Mobile Application", оставьте View engine как Razor, и оставить флажок для семантической разметки HTML5
Новый проект MVC
Вы получите по умолчанию мобильное приложение с проверкой подлинности.

База данных
Нам необходимо создать базу данных и схемы для этой демонстрации следующего.
  • На локальном, например, создайте SQL Server 2008 R2 (SQL Server 2005 + будет делать) базу данных и назовите его Babylog
  • Нам нужны две таблицы в базе данных для нашего приложения, одно для хранения записей для подачи бревен и другой для подгузников. Выполните следующую SQL для создания этих
     
    CREATE TABLE [dbo].[FeedingLog](
     [ID] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Log_ID]   
    DEFAULT (newid()),
        [UserID] [varchar](255) NOT NULL,
        [FeedType] [varchar](255) NOT NULL,
        [FeedAmount] [decimal](18, 1) NOT NULL,
        [DateCreated] [datetime] NOT NULL,
     CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC
    )WITH (STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF)
    )
    GO 
     
    CREATE TABLE [dbo].[DiaperLog](
     [ID] [uniqueidentifier] NOT NULL CONSTRAINT [DF_DiaperLog_ID]   
    DEFAULT (newid()),
        [UserID] [varchar](255) NOT NULL,
        [DiaperType] [varchar](255) NOT NULL,
        [DateCreated] [datetime] NOT NULL,
     CONSTRAINT [PK_DiaperLog] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC
    )WITH (STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF)
    )
    GO
      
    Далее нам нужно создать таблицы для поддержки проверки подлинности форм.  
    Откройте командную строку Visual Studio и введите: aspnet_regsql
     
  • Нажмите кнопку Далее, выберите пункт "Configure SQL Server for application services", введите поставщик имя сервера, учетных данных и имя базы данных и нажмите кнопку Далее.
  • После завершения работы мастера, вы увидите таблиц базы данныхBabylog таблицы
Модели базы данных
Далее мы создадим Entity модель для нашей базы данных, а также используем WCF, для ввода данных в базу данных.
  • В ASP.Net MVC проекта, щелкните правой кнопкой мыши на папке Models и выберите пункт "Add New Item"
  • Выберите шаблон данных и выберите "ADO.Net Entity Data Model
Шаблон Entity Framework
  • Выберите "Generate from Database", затем нажмите кнопку Далее
  • Укажите сведения о подключении к базе данных и имя строки подключения
  • Выберите FeedingLog и DiaperLog таблицы и оставить модель пространства имен, BabyLogModel
Выбор Entity таблицы

Теперь у вас есть модель с требуемой таблицыБаза данных моделей