¿Cómo conectarnos a un proyecto en desarrollo en Visual Studio desde otra computadora? .Net

Algunas veces tenemos la necesidad de conectarnos a un proyecto que está en desarrollo, es decir está programándose aun y se encuentra en una solución de visual studio, ya sea para probar una aplicación móvil conectándose al servicio web o para conectarnos desde un celular y ver como se verá un sitio web responsivo.
Los pasos son los siguientes, todos son sobre el equipo que tiene el código fuente:

  • Desactivar el firewall (Importantísimo).
  • Verificar la ip del equipo.
  • Todos los proyectos de visual studio tienen una carpeta oculta llamada .vs dentro de esta carpeta se encuentra una llamada config y dentro un archivo llamado applicationhost.config (quedando así la ruta “.vs/config/applicationhost.config”). Abrimos este archivo con notepad u otro editor de texto.
  • Ahora buscamos nuestro proyecto en el Xml el apartado Sites y debe aparecer algo así:

 <site name="MiProyecto" id="1">
                <application path="/" applicationPool="Clr4IntegratedAppPool">
                    <virtualDirectory path="/" physicalPath="C:\Users\User\Documents\MiProyecto\MiProyecto" />
                </application>
                <bindings>
                    <binding protocol="http" bindingInformation="*:2248:localhost" /><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>
                </bindings>
</site>

  • Ahora agregamos la siguiente línea quedando así (suponiendo que el puerto es el 2248 y la ip 192.168.0.26) :

 <site name="MiProyecto" id="1">
                <application path="/" applicationPool="Clr4IntegratedAppPool">
                    <virtualDirectory path="/" physicalPath="C:\Users\User\Documents\MiProyecto\MiProyecto" />
                </application>
                <bindings>
                    <binding protocol="http" bindingInformation="*:2248:localhost" />
	            <binding protocol="http" bindingInformation="192.168.0.26:2248:*" />
                </bindings>
</site>

  • Por ultimo corremos visual studio como administrador, el proyecto ya podrá ser visto desde otro equipo en la misma red por medio de la ip más el puerto.

Con eso bastara para que puedan conectarse de otro equipo a la maquina que tiene el desarrollo, sin importar que el otro equipo esa movil, mac o pc, e igual podrá debuggearse el código.

Corregir el error: Método ambiguo en Dataset visual studio, dataset corrupto

Hace poco me toco modificar un proyecto que tenía sin modificarlo algunos años, mi sorpresa fue que al modificar el DataSet se destruyó y todos sus métodos, TableAdapters etc me marcaba como si fueran ambiguos o inexistentes. Después de unas horas sufriendo logre corregirlo de la siguiente manera:

  1. Eliminar el archivo .xsc y el .xss.
  2. Excluir él .xsd del proyecto (no eliminarlo, solo excluirlo)
  3. Volver a incluir el .xsd al proyecto (esto regenera el .xsc y el .xss).

Y listo con esos pasos se restablecerá el DataSet.

Un poco de abstracción en la programación no hace daño

Este es un tema muy subjetivo pero el cual es tan importante como el conocer el lenguaje de programación y herramientas de terceros.
La abstracción es un concepto filosófico que comenzó por las reflexiones filosóficas de aquel pensador llamado Aristóteles (dudo que hubiera sido el primero), y se resume como las propiedades y funciones que hacen un objeto (esos griegos ya sabían POO). En palabras simples, la abstracción es aquello que hace que un triángulo no sea un cuadrado, y si un sujeto entiende un triángulo a la perfección y otro sujeto también lo entiende a la perfección deberían ver el concepto de triángulo de la misma forma. Claro esto es yéndonos al extremo de abstracción.
¿Entonces todas estas cosas marihuanas a que nos llevan o para que nos sirven en la programación? Pues sirve prácticamente para trabajar menos.
Los requerimientos son los que definen un problema y para resolver ese problema es para lo que nos pagan, cuando tenemos un par de años trabajando desarrollando software es más fácil identificar los requerimientos parecidos y por lo cual es más fácil aplicar funcionalidades compartidas, en sí, estamos aplicando abstracción funcional al desarrollo, por lo cual trabajaremos menos pero pensaremos más (cuando digo más no hablo de tiempo aplicado sino de complejidad).
Un poco de abstracción no hace daño, un poco de herencia, sobrecarga y rehusó de funcionalidad ayuda a crear más estética en nuestro código, pero como todo, el exceso es malo, el balance de cuanta abstracción utilizar es decisión de uno, y cuando hablo de saber cuánto rehusó de funcionalidad utilizar, hablo por los cambios de requerimientos que a veces van desde una funcionalidad única en solo un módulo la cual nos hace re-codificar mucho.
Como conclusión, la abstracción es algo que se aprende por uno mismo con la experiencia, ni un curso ayudara a tener mejor abstracción, ni gurus, ni evangelistas, lo único que nos hará mejorar el nivel son los distintos problemas nacidos de distintos requerimientos.

Ver – Abstracción en la programación 

¿Cómo crear una función en transact-sql que reciba una cadena con los ids para aplicaros con la función In de sql?

Para esto necesitaremos crear la función mítica Split de sql que tiene años en internet y pongo a continuación (desconozco el autor):

CREATE FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20) = ' ')
RETURNS @Strings TABLE
(
  position int IDENTITY PRIMARY KEY,
  value varchar(8000)
)
AS
BEGIN

DECLARE @index int
SET @index = -1

WHILE (LEN(@text) > 0)
  BEGIN
    SET @index = CHARINDEX(@delimiter , @text)
    IF (@index = 0) AND (LEN(@text) > 0)
      BEGIN
        INSERT INTO @Strings VALUES (@text)
          BREAK
      END
    IF (@index > 1)
      BEGIN
        INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))
        SET @text = RIGHT(@text, (LEN(@text) - @index))
      END
    ELSE
      SET @text = RIGHT(@text, (LEN(@text) - @index))
    END
  RETURN
END

Una vez con la función Split agregada a nuestra base de datos de la siguiente manera podemos aplicar una cadena que contenga ids y aplicarles alguna modificación a los registros dentro dicha cadena, por ejemplo una procedimiento que modifique un campo(o varios) en común de varios registros recibiendo una cadena con los ids:

CREATE FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20) = ' ')
RETURNS @Strings TABLE
(
  position int IDENTITY PRIMARY KEY,
  value varchar(8000)
)
AS
BEGIN

DECLARE @index int
SET @index = -1

WHILE (LEN(@text) > 0)
  BEGIN
    SET @index = CHARINDEX(@delimiter , @text)
    IF (@index = 0) AND (LEN(@text) > 0)
      BEGIN
        INSERT INTO @Strings VALUES (@text)
          BREAK
      END
    IF (@index > 1)
      BEGIN
        INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))
        SET @text = RIGHT(@text, (LEN(@text) - @index))
      END
    ELSE
      SET @text = RIGHT(@text, (LEN(@text) - @index))
    END
  RETURN
END

Y así la mandaríamos llamar:


EXEC sp_algo '1,3,5,7,77,65,666','leviathan'

Esto es útil y rápido cuando se desea modificar masivamente una colección de registros (por ejemplo desde un backend con entity framework) los cuales tendrán el mismo valor en uno de sus campos, solo tomar precauciones con SQL INJECTION (es 2017 y si aún existe)

¿Cómo recorrer dinámicamente los atributos de un objeto en C#?

En c# existe una manera fácil para recorrer dinámicamente los atributos de un objeto, de la siguiente manera podemos obtener el valor de un objeto dinámicamente y también el nombre de sus atributos en forma de cadena, para ello haremos uso de la clase PropertyInfo con la cual podemos obtener la estructura de nuestro objeto, abajo comento y pongo un ejemplo simple para entenderlo:

Clase para el ejemplo:


public class Auto
{
            public string Nombre { get; set; }
            public string Marca { get; set; }
            public string Modelo { get; set; }

            public int Año { get; set; }
}

Y para realizar el recorrido de los atributos lo hacemos de la siguiente manera:


Auto oAuto = new Auto() { Nombre = "Mi auto", Marca = "Honda", Modelo = "Civic", Año = 2018 };

PropertyInfo[] properties = typeof(Auto).GetProperties();
foreach (PropertyInfo property in properties)
{
     //así obtenemos el nombre del atributo
     string NombreAtributo=property.Name; 

     //así obtenemos el valor del atributo
     string Valor=property.GetValue(oAuto);
     Console.WriteLine("El atributo "+NombreAtributo+" tiene el valor: "+ Valor);
}

Y el resultado:

El atributo Nombre tiene el valor: Mi auto
El atributo Marca tiene el valor: Honda
El atributo Modelo tiene el valor: Civic
El atributo Año tiene el valor: 2018

Si agregamos nuevos atributos a nuestra clase este algoritmo seguiría recorriendo dinámicamente todas la nuevas propiedades de nuestra clase.

¿Cómo ponerle una contraseña a un pdf en c#?

Para poner un password a un pdf en C# podemos hacer uso de la librería iTextSharp(la cual pueden instalar con nuget, ¿Cómo utilizar nuget?) la cual tiene muchas funcionalidades para el manejo de archivos pdf.
Partiendo de un archivo pdf ya existente con el siguiente código:


 using (var input = new FileStream("C:/archivoOriginal.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
 using (var output = new FileStream("C:/archivoConContrasena.pdf", FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    var reader = new PdfReader(input);
                    PdfEncryptor.Encrypt(reader, output, true,"tucontraseña", "tucontraseña", PdfWriter.ALLOW_PRINTING);
                }

¿Cómo realizar un join entre 2 base de datos distintas con entity framework y LINQ? C# #linq

No es bueno para el rendimiento hacer este tipo de consultas ya que las tablas están en bases de datos distintas, pero muchas veces es necesario para el hecho de crear un reporte, o cuando se expande un sistema con nueva tecnología y al final el cliente desea un reporte combinado entre sus sistemas viejos y los nuevos, yo les mostrare una manera de poder lograr un join entre dos bases de datos distintas.
El problema es el siguiente(es hipotético no necesariamente es real solo sirve para el ejemplo), tenemos una base de datos (BD1) con las ventas diarias guardadas en una tabla llamada ventas, se nos pide que sea mostrada la venta y a su lado los datos del domicilio de la tienda, pero nos damos cuenta que no contamos con esos datos, esos datos están en una tabla llamada tienda en una base de datos distinta (BD2), entonces necesitamos hacer un join entre las 2 bases de datos, y para hacerlo debemos tomar a consideración lo siguiente:
Debemos evaluar cual tabla tiene menos registros ya que haremos primero la consulta sobre esa tabla primero y esos datos los tendremos en memoria. En este caso la tabla tienda es la que tiene menos datos (una tienda tiene muchas ventas así que el universo es menor por sentido común). Así que primero vamos por las tiendas de la siguiente forma:

//creamos nuestro contexto de la bd2 ya que ahi esta la tabla tienda
var db2= new entitiesTiendaDB();
//obtenemos las tiendas con una consulta simple de linq
var lstTiendas = from d in db2.tiendas.ToList()
                  select d;

Ahora que a tenemos las tiendas, de la siguiente manera hacemos el join con los datos que ya tenemos en la variable lstTienda:


//creamos el contexto de db1 el cual contiene la tabla ventas
var db = new entitiesVentasDB();

//teniendo un viewmodel llamado VentasViewModel el cual tenga solo los campos que necesitamos creamos la consulta
List<VentasViewModel> lst= from d in db.ventas.ToList()
                          //nuestra tienda se une por el campo codigTienda de lstTiendas y por el mismo campo en
                          //la tabla ventas
                          join t in lstTiendas on d.codigoTienda equals t.codidoTienda into un
                          //esto hace que sea un left join,
                          // si no ponen esto solo les regresara todo como inner join
                          from x in un.DefaultIfEmpty()
                          orderby t.nombreTienda
                     select new VentasViewModel
                      {
                          idTienda = (x!=null) ? x.id : 0, //como hicimos left join podría haber datos nullos y debemos evaluar
                          nombreTienda =(x!=null) ? x.nombre : "",
                          domicilioTienda =(x!=null) ? x.domicilio : "", //asi obtenemos el domicilio
                          codigo = (x!=null )? x.codigoTienda : "",
                          total= d.total //este viene en ventas así que accedo con d
                          subtotal=d.subtotal //igual que arriba

                      };

Y así se hace la magia. Dudas en los comentarios.

¿Cómo convertir una cadena XML a Objeto en c#? deserializar

Existen varias formas de llenar un objeto por medio de valores incrustados en XML(deserialización) y esta que planteo a continuación es la forma más comprensible de hacerlo.
Teniendo el siguiente texto de xml:


<padre>
  <hijo>
    <id>18</id>
    <valor>CFE7785</valor>
    <entero>1</entero>
  </hijo>
<padre>

Primero tenemos que hacer un conjunto de clases las cuales nos ayudaran a guardar los valores:

    [XmlRoot("padre")]
    public class padre
    {
        [XmlElement("hijo")]
        public List lstHijos{ get; set; }
    }

    public class hijo
    {
        [XmlElement("id")]
        public int id { get; set; }
        [XmlElement("valor")]
        public string valor { get; set; }

        [XmlElement("entero")]
        public int entero { get; set; }

    }

Y ahora el proceso para la magia:


string xml= "<padre> <hijo> <id>18</id> <valor>CFE7785</valor> <entero>1</entero> </hijo> <padre>"

XmlSerializer serializer = new XmlSerializer(typeof(padre));
using (TextReader reader = new StringReader(xml))
{
        //de esta manera se deserializa
        padre result = (padre)serializer.Deserialize(reader);
}

¿Cómo obtener el #UUID (Timbre fiscal) de un xml timbrado en c#? #facturacion

Para obtener el UUID de un xml que ya tengamos timbrado del SAT lo podemos hacer con LINQ muy sencillo como muestro a continuación:

            //sustituir por la ruta de tu xml
            string rutaXML="C:/carpeta1/carpeta2/factura.xml";

            //variables del esquema
            XNamespace cfdi = @"http://www.sat.gob.mx/cfd/3";
            XNamespace tfd = @"http://www.sat.gob.mx/TimbreFiscalDigital";

            //cargamos el xml
            var xdoc = XDocument.Load(rutaXML);

            //Navegamos hasta el elemento que contiene el UUID
            var elt = xdoc.Element(cfdi + "Comprobante")
                          .Element(cfdi + "Complemento")
                          .Element(tfd + "TimbreFiscalDigital");

            //listo obtenemos el UUID
            var uuid = (string)elt.Attribute("UUID");

Catálogos para facturar CFDI 3.3 SAT en mysql

ULTIMA ACTUALIZACIÓN DE LOS CATÁLOGOS: 3 DE ENERO 2018

Pongo a disposición los catálogos en mysql publicados por SAT necesarios para la facturación 3.3.

Estaré actualizándolos conforme el SAT libere nuevos registros. Solo dar clic en el siguiente enlace:



DESCARGAR CATÁLOGOS SAT

Si deseas descargar los catálogos para sql server entra aquí

Si deseas descargar los catálogos para SQLite entra aquí