lunes, abril 28, 2014

Mini-CRM en ASP.Net (II)

 

Creación del proyecto

Desde VS Express 2013 para Web he creado un nuevo proyecto de tipo aplicación ASP.Net MVC con autenticación de tipo cuentas de usuario individuales (es el defecto).

image

Al crear el proyecto se muestra una página con información sobre los siguientes pasos a realizar en el proyecto. A tener en cuenta en mi proyecto:

Si clicamos cualquiera de los 2 primeros nos redirige a:

[…]

This topic explains the options for creating ASP.NET web projects in Visual Studio 2013 with Update 2.

The new dialogs and templates include the following new features compared to earlier versions of Visual Studio:

[…]

En este momento nos centraremos en el apartado ASP.Net Identity.

 

Autenticación mediante ASP.Net Identity

ASP.Net Identity es el nuevo sistema de autenticación para ASP.Net, tal como se explica en ASP.Net Identity. Para añadirlo a mi proyecto sigo los pasos que se explican en el link:

Adding ASP.NET Identity to an Empty or Existing Web Forms Project

A modo de resumen:

  • Para añadir ASP.Net Identity al proyecto, se puede utilizar NuGet tal como muestra la siguiente figura:

image

  • Para mi proyecto cambio la conexión que viene por defecto por una a mi propia base de datos lo cual hace que se generen automáticamente en ella las tablas necesarias.

  • De momento no necesito utilizar proveedores externos (facebook, gmail…)

 

Bootstrap (responsive web)

Las plantillas de proyecto de Visual Studio 2013 utilizan Bootstrap para proporcionar un diseño responsive, lo que significa que los diseños pueden adaptarse dinámicamente a los diferentes tamaños de ventana del navegador, y por tanto, al tamaño de los diferentes dispositivos consumidores.

En bootswatch.com podemos encontrar temas alternativos al que aparece por defecto en nuestra nueva aplicación (aquí se explica en detalle cómo proceder). Además de los temas free también existen otros mucho más elaborados de pago (rondan los 8$ a 18$). Es el caso de los que podemos encontrar en {wrap}bootstrap. Para nuestro mini-CRM hemos comprado la plantilla denominada Ace.

WB0B30DGR[1]

Aquí hemos tenido que dedicar unas cuantas horas a encajar la nueva plantilla.

  1. Descomprimir el paquete descargado y añadirlo al proyecto

    image
  2. A partir de index.html de la nueva plantilla, crear una nueva vista _LayoutAce.cshtml con la que reemplazar la actual _Layout.cshtml. Para que el proyecto use la nueva plantilla, cambiar la una por la otra en _ViewStart.cshtml.
    @{
    Layout = "~/Views/Shared/_LayoutAce.cshtml"
    ;
    }



  3. Crear los bundles de la nueva plantilla (ver bundling and minification). Para ello en AppStart/BundleConfig.cs añadir las siguientes líneas:
    // Bundles de wrapbootstrap-Ace
    bundles.Add(new ScriptBundle("~/bundles/wrapbootstrap-ace/js").Include(
    "~/templates/wrapbootstrap_ace/assets/js/*.js", "~/templates/wrapbootstrap_ace/assets/js/uncompressed/*.js"));

    bundles.Add(
    new StyleBundle("~/bundles/wrapbootstrap-ace/css").Include(
    "~/templates/wrapbootstrap_ace/assets/css/*.css", "~/templates/wrapbootstrap_ace/assets/css/ace.min.css"));




  4. Adaptar _LayoutAce.cshtml. Cambios principales:

  5. […]
    <head>
    <
    meta charset="utf-8" />
    <
    title>Mi CRM</title>

    <
    meta name="description" content="Common form elements and layouts" />
    <
    meta name="viewport" content="width=device-width, initial-scale=1.0" />

    @Styles.Render("~/bundles/wrapbootstrap-ace/css")

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/modernizr")
    @Scripts.Render("~/bundles/bootstrap")
    @Scripts.Render("~/bundles/wrapbootstrap-ace/js")

    […]



         <li class="light-blue">
      @Html.Partial("_LoginPartial"
      )
      </li><!—login-->




    […]

       <div class="page-content">
    @
    RenderBody()
    </div>
    <!-- /.page-content -->





  6. Adaptar la pantalla de inicio de sesión Account/Login.cshtml:

    @model NeumaliaCRM.Models.LoginViewModel

    @{
    Layout = null
    ;
    }
    @{
    ViewBag.Title = "Inicio de sesión"
    ;
    }

    <!DOCTYPE html
    >
    <
    html lang
    ="es">
    <
    head
    >
    <
    meta charset
    ="utf-8" />
    <
    title>CRM Neumalia - @ViewBag.Title</title
    >

    <
    meta name="description" content
    ="User login page" />
    <
    meta name="viewport" content
    ="width=device-width, initial-scale=1.0" />

    <!-- basic styles -->

    <link href="~/templates/wrapbootstrap_ace/assets/css/bootstrap.min.css" rel
    ="stylesheet" />
    <
    link rel="stylesheet" href
    ="~/templates/wrapbootstrap_ace/assets/css/font-awesome.min.css" />

    <!--[if IE 7]>
    <link rel="stylesheet" href="~/templates/wrapbootstrap_ace/assets/css/font-awesome-ie7.min.css" />
    <![endif]-->
    <!-- page specific plugin styles -->
    <!-- fonts -->

    <link rel="stylesheet" href
    ="~/templates/wrapbootstrap_ace/assets/css/ace-fonts.css" />

    <!-- ace styles -->

    <link rel="stylesheet" href
    ="~/templates/wrapbootstrap_ace/assets/css/ace.min.css" />
    <
    link rel="stylesheet" href
    ="~/templates/wrapbootstrap_ace/assets/css/ace-rtl.min.css" />

    <!--[if lte IE 8]>
    <link rel="stylesheet" href="~/templates/wrapbootstrap_ace/assets/css/ace-ie.min.css" />
    <![endif]-->
    <!-- inline styles related to this page -->
    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="~/templates/wrapbootstrap_ace/assets/js/html5shiv.js"></script>
    <script src="~/templates/wrapbootstrap_ace/assets/js/respond.min.js"></script>
    <![endif]-->

    @*extraído de site.css...
    *@
    <style
    >
    /* styles for validation helpers */
    .field-validation-error
    {
    color: #b94a48
    ;
    font-size:small
    ;
    }

    .field-validation-valid
    {
    display: none
    ;
    }

    input.input-validation-error
    {
    border: 1px solid #b94a48
    ;
    }

    input[type="checkbox"].input-validation-error
    {
    border: 0 none
    ;
    }

    .validation-summary-errors
    {
    color: #b94a48
    ;
    }

    .validation-summary-valid
    {
    display: none
    ;
    }
    </style
    >

    </
    head
    >

    <
    body class
    ="login-layout">
    <
    div class
    ="main-container">
    <
    div class
    ="main-content">
    <
    div class
    ="row">
    <
    div class
    ="col-sm-10 col-sm-offset-1">
    <
    div class
    ="login-container">
    <
    div class
    ="center">
    <
    h1
    >
    <
    i class="icon-group green"></i
    >
    <
    span class="red">CRM</span
    >
    <
    span class="white">Neumalia</span
    >
    </
    h1
    >
    <
    h4 class="blue">&copy; AutoEquip</h4
    >
    </
    div
    >

    <
    div class="space-6"></div
    >

    <
    div class
    ="position-relative">
    <
    div id="login-box" class
    ="login-box visible widget-box no-border">
    <
    div class
    ="widget-body">
    <
    div class
    ="widget-main">
    <
    h4 class
    ="header blue lighter bigger">
    <
    i class="icon-coffee green"></i
    >
    Introduce tus credenciales
    </h4
    >

    <
    div class="space-6"></div
    >

    @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form"
    }))
    {
    @
    Html.AntiForgeryToken()
    @Html.ValidationSummary(true
    )

    <fieldset
    >
    <
    label class
    ="block clearfix">
    <
    span class
    ="block input-icon input-icon-right">
    @Html.TextBoxFor(m => m.UserName, new { @class = "form-control", @placeholder="Nombre de usuario"
    })
    @
    Html.ValidationMessageFor(m => m.UserName)
    <i class="icon-user"></i
    >
    </
    span
    >
    </
    label
    >

    <
    label class
    ="block clearfix">
    <
    span class
    ="block input-icon input-icon-right">
    @Html.PasswordFor(m => m.Password, new { @class = "form-control", @placeholder="Contraseña"
    })
    @
    Html.ValidationMessageFor(m => m.Password)
    <i class="icon-lock"></i
    >
    </
    span
    >
    </
    label
    >

    <
    div class="space"></div
    >

    <
    div class
    ="clearfix">

    @
    Html.CheckBoxFor(m => m.RememberMe)
    @
    Html.LabelFor(m => m.RememberMe)

    <button type="submit" class
    ="width-45 pull-right btn btn-sm btn-primary">
    <
    i class="icon-key"></i
    >
    Iniciar sesión
    </button
    >
    </
    div
    >

    <
    div class="space-4"></div
    >
    </
    fieldset
    >
    }

    </div>
    <!-- /widget-main -->

    </div>
    <!-- /widget-body -->
    </div>
    <!-- /login-box -->

    </div>
    <!-- /position-relative -->
    </div
    >
    </
    div>
    <!-- /.col -->
    </div>
    <!-- /.row -->
    </div
    >
    </
    div>
    <!-- /.main-container -->

    </body
    >
    </
    html>image



  7. Adaptar _LoginPartial.cshtml:
    @using Microsoft.AspNet.Identity
    @if
    (Request.IsAuthenticated)
    {
    using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right"
    }))
    {
    @
    Html.AntiForgeryToken()
    }

    <a data-toggle="dropdown" href="#" class
    ="dropdown-toggle">
    <
    img class="nav-user-photo" src="~/templates/wrapbootstrap_ace/assets/avatars/avatar2.png" alt
    ="Foto usuario" />
    <
    span class
    ="user-info">
    <
    small>Hola,</small
    >
    @
    User.Identity.GetUserName()
    </span
    >

    <
    i class="icon-caret-down"></i
    >
    </
    a
    >

    <
    ul class
    ="user-menu pull-right dropdown-menu dropdown-yellow dropdown-caret dropdown-close">
    <
    li
    >
    <
    a href
    ="/Account/Manage">
    <
    i class="icon-cog"></i
    >
    Configurar cuenta
    </a
    >
    </
    li
    >

    <
    li
    >
    <
    a href
    ="#">
    <
    i class="icon-user"></i
    >
    Perfil
    </a
    >
    </
    li
    >

    <
    li class="divider"></li
    >

    <
    li
    >
    <
    a href
    ="javascript:document.getElementById('logoutForm').submit()">
    <
    i class="icon-off"></i
    >
    Cerrar sesión
    </a
    >
    </
    li
    >
    </
    ul
    >
    }
    else
    {
    <ul class
    ="nav navbar-nav navbar-right">
    @*<li>@Html.ActionLink("Registrarse", "Register", "Account", routeValues: null, htmlAttributes: new { id = "registerLink" })</li>
    *@
    <li>@Html.ActionLink("Iniciar sesión", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })</li
    >
    </
    ul
    >
    }



  8. image 

No hay comentarios:

Publicar un comentario