viernes, 18 de mayo de 2012

Upload file MVC 3

Actualmente estoy trabajando en un proyecto de una aplicación MVC. En esta aplicación hay que crear usuarios donde podamos adjuntar una foto del usuario.

Cuando utilizamos MVC y queremos usar un input de tipo file, hay que cambiar alguna cosilla en el form del página, a continuación comentamos como habría que hacerlo.

Por defecto si en una vista usamos la siguiente declaración de tag form:

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>


</fieldset>
}


Esto nos incluye en nuestro html el siguiente tag:



<form action="/Controller/Action" method="post">
<fieldset>
</fieldset>
</form>


Este tag form no contiene el atributo enctype, por lo que usara el enctype por defecto, es decir: “application/x-www-form-urlencoded”, pero este tag no nos sirve para hacer un post de un documento, por lo que tendremos que cambiar nuestra declaración del tag form, de manera que el enctype sea “multipart/form-data”, esto lo conseguimos de la siguiente forma:



@using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.ValidationSummary(true)
<fieldset>


</fieldset>
}


De esta forma ya obtenemos el tag form que necesitamos para poder subir un fichero:



<form action="/Controller/Action" enctype="multipart/form-data" method="post">
<fieldset>
</fieldset>
</form>


Una vez tenemos el form preparado, ya sólo necesitamos incluir un input de tipo file, por lo que nuestra vista podría quedar de la siguiente forma:



@using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.ValidationSummary(true)
<fieldset>
<legend>Upload file</legend>
<div class="editor-label">
@Html.Label("Choose file")
</div>
<div class="editor-field">
<input type="file" name="file" id="file" />
</div>

</fieldset>
}


Por último nuestro controller quedaría de la siguiente forma:



public class ControllerController : Controller
{
[HttpPost]
public ActionResult Action(MyViewModel viewModel, HttpPostedFileBase file)
{
if (!ModelState.IsValid)
{

}
}
}

jueves, 17 de mayo de 2012

BDD Training

Quería compartir una presentación que he elaborado para un training interno de Spenta. En esta training se hablará sobre BDD y que herramientas tenemos en el mundo .NET para llevar a cabo una aplicación a partir del diseño dirigido por comportamientos.

Así que sin más dilación os dejo un enlace a la presentación.

http://prezi.com/zcuuubv7hifl/behavior-driven-development/

jueves, 22 de marzo de 2012

string.Format y uso de llaves para abrir cerrar función

Este es un post bien corto y seguro que muchos de vosotros ya lo conocéis, pero yo no me había encontrado con el caso hasta ahora…

La idea es que quería usar la función string.Format para que me escribiera en cliente una función de javascript y claro en esta función aparece el caracter ‘{‘ y ‘}’, pero no me interesa que string.Format, lo interprete como parámetro, por lo que necesito un carácter de escape. Bueno, pues el carácter de escape es usar este mismo carácter.

string.Format(@"
<script>
$(document).ready(function()
{{
$(""#{0}"").doSomething();
}});
</script>","HelloWorld");


Esta información la encontré en el siguiente blog:



http://geekswithblogs.net/jonasb/archive/2007/03/05/108023.aspx

viernes, 2 de diciembre de 2011

IEnumerable en vez de List para propiedades

Hoy toca un post muy sencillo y básico pero que puedes preguntarte en algunas ocasiones.

Hoy le he hecho una pregunta a mi amigo y maestro Pedro Santos que me estaba rondando por la cabeza, ¿por qué exponer una propiedad como IEnumerable en vez de List, si yo internamente la voy a definir como una List?

Su respuesta ha sido muy clarificadora:

Al exponerla como IEnumerable tu no expones (encapsulas) su estructura interna, además así limitas las operaciones a realizar con esta propiedad y puedes aplicar las reglas de negocio que te interesen, como por ejemplo, que tenga un cierto comportamiento concreto al añadir un nuevo elemento a la lista.

Si tu expones una propiedad como List, también le estas exponiendo la opción de añadir sin que tu controles como se han de añadir estos elementos a tu colección.

Pues bueno, a partir de ahora, todas mis colecciones irán como IEnumerable y cuando me interese le expondré el método AddNewFooItem(FooItem item). Por último, lo ideal también sería exponer el setter de la lista como private o protected, para que no puedan “settearte” una nueva colección.

jueves, 3 de noviembre de 2011

Llamando a un web service sobre https (ssl) desde sharepoint 2010

He estado trabajando en un proyecto donde teniamos que integrar una aplicación externa, esta integración la hacemos mediante servicios webs. Estos servicios webs contienen datos privados por lo que están securizados mediante certificados (el mensaje) y además la información viaja por un medio seguro, es decir, ssl.

Bueno hasta aquí nada nuevo, hice mis pruebas con un proyecto de test, colocando los certificados en los diferentes repositiorios, dependiendo de su función: Trusted Root Certification Authorities, Intermediate Certification Authorities, etc. y todo funcionaba a las mil maravillas.

Pero esta llamada al servicio web ha de ser hecha desde un entorno SharePoint 2010, pensé que esto no sería ningún problema pues en el otro tipo de proyecto me funcionaba correctamente, pero no fue así, de pronto observé que la llamada al servicio web me estaba devolviendo la siguiente excepción:

Type: System.Net.WebException
Message: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
InnerException: The remote certificate is invalid according to the validation procedure.

Esta excepción me extraño mucho, pues si yo accedía mediante el browser a la url del web service me decía que el certificado estaba correctamente instalado.

Entonces empecé a googlear un poco y leía gente que decía de crear un bypass, mediante la creación de tu propia clase CertificatePolicy que implemente la interfaz ICertificatePolicy, y en el método CheckValidationResult devolver true siempre para que se salte la validación.

public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy
{
public TrustAllCertificatePolicy()
{}

public bool CheckValidationResult(ServicePoint sp,
X509Certificate cert,WebRequest req, int problem)
{
return true;
}
}


La llamada a esta clase se tendría que hacer justo antes de la llamada a tu servicio web.


System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();

He visto en muchos foros y blogs que esto lo daban como la solución correcta, pero ojo, aquí estamos aceptando cualquier cosa que nos esté enviando el servidor sin validar el certificado!!


Por lo tanto seguí buscando y el problema reside en la forma que tiene sharepoint de obtener los certificados raíz, que parece ser que usa su propio repositorio de certificados en vez de usar el de la propia máquina. Por lo que tendremos que añadir estos certificados raíz de confianza en el repositorio de sharepoint. Para hacerlo seguiremos los siguientes pasos:



  1. Ir a la administración central

  2. Ir a security

  3. Manage trust

  4. Aquí es donde instalaremos los certificados raíz que nos interese, pulsando new, buscando el certificado y poniéndole un nombre.


Esta información la obtuve del siguiente blog:


http://blog.mattsampson.net/index.php/calling-a-webservice-over-ssl-in-sharepoint-ssl?blog=1

jueves, 9 de junio de 2011

WCF tools

Esta semana me he estado peleando he estado haciendo una integración con un proveedor de servicios para poder consumir su servicio una aplicación que estamos desarrollando. Lo primero que hemos de saber es que toda integración suele dar muchos dolores de cabeza ser un bonito reto.

En nuestro caso teníamos que consumir un servicio elaborado con java axis2. Este servicio tenia que tener seguridad a nivel de transporte (mediante certificado) y seguridad a nivel de mensaje (también mediante certificado), más concretamente en nuestro caso debía contener una firma.

Cuando hacemos este tipo de integraciones lo más normal es que no nos salga a la primera y que tengamos que ver que mensajes estamos enviando al servidor, ya que los errores que nos pueden devolver el servidor pueden ser poco intuitivos. Y he aquí donde realmente empieza el contenido de este post, o sea, que herramientas podemos usar para ver lo que estamos enviando.

Una de las primeras herramientas que podemos utilizar es el tracing de Windows Communication Foundation. En la siguiente página de las MSDN podemos ver como configurar esto:

http://msdn.microsoft.com/en-us/library/ms733025.aspx

En mi caso la configuración ha sido la siguiente:

Justo antes del cierre del tal configuration (</configuration>)

<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true" >
<listeners>
<add name="xml"/>
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="xml"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\logs\CommandLineSTS.svclog" />
</sharedListeners>
</system.diagnostics>

Y esto dentro del nodo system.serviceModel:

<!-- add trace logging -->
<diagnostics wmiProviderEnabled="true">
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
/>
</diagnostics>

Otras herramientas que podemos usar para ver que se esa enviando son HTTP monitors, en mi caso he utilizado dos, destacando el último de los que menciono a continuación:

image

Otra de las cosas con las que nos entretendremos mucho es configurando nuestro service model a nivel de configuración o programándolo con código. Para ello nada mejor que las msdn y como punto de partida esta seria una buena página:

http://msdn.microsoft.com/en-us/library/ms733103.aspx

Tampoco podemos olvidar las herramientas de WCF que se nos ofrecen con nuestro visual studio, un resumen de ellas son las que indica la msdn en la siguiente página:

http://msdn.microsoft.com/en-us/library/ms732015(v=vs.90).aspx

Seguramente y debido a las peculiaridades de cada integración, no nos valdrá con las típicas configuraciones de bindings que nos ofrece el framework por defecto, es decir BasicHttpBinding o WSHttpBinding, entre otras, y tengamos que echar mano de custombindings, ahora bien no esta mal partir de uno de los bindings de los que disponemos, para poder hacer esto podemos convertir cualquiera de estos bindings a custom bindings utilizando por ejemplo una herramienta que expone en su blog un crack en la materia como es Yaron Naveh.

http://webservices20.blogspot.com/2009/08/bindingbox-convert-wcf-bindings.html

Sobre el tema de configuración, decir que antes de pensar en desarrollar nosotros una solución como dirian los anglosajones “from scratch”, mirar todas las posibilidades que nos ofrecen las configuraciones de los bindings, seguro que encontraremos alguna que satisface nuestras necesidades.

En caso de que nuestra solución sea muy compleja y no podamos obtenerla con lo que nos ofrece wcf out of the box, siempre podemos pensar en extender estas funcionalidades ya que wcf es un framework de comunicación altamente extensible. Por ejemplo, podemos crear un message inspector o un message encoder (derivando de la interfaz IClientMessageInspector o de la clase MessageEncoder, respectivamente). Para estas posibles extensiones que podamos hacer sobre WCF es interesante descargarnos los ejemplos que encontramos en la msdn, más concretamente en:

http://msdn.microsoft.com/en-us/library/ms751514(v=VS.90).aspx

Aquí podemos encontrar ejemplos divididos en las siguientes categorías:

  • Basic
  • Extensibility
  • Scenario
  • Setup
  • Tools

lunes, 18 de abril de 2011

Alternativa a .NET Reflector

Hoy toca una entrada muy cortita.

El otro día estuve buscando una alternativa open source a la famosa herramienta de Redgate .NET Reflector y encontré una que me ha gustado mucho. Al igual que .NET Reflector, se trata de una herramienta que nos permite navegar por los ensamblados y decompilar codigo IL.

Como podéis apreciar en la siguiente imagen, la interfaz es identica a .NET Refector, por lo que no nos costará nada acostumbrarnos a trabajar con esta nueva herramienta.

ILSpy

Por último os dejo la url de la herramienta:

http://wiki.sharpdevelop.net/ilspy.ashx