jueves, 28 de abril de 2011
WCF RIA Services como OData, SOAP o JSON
Casi a punto ya de agotar las vacaciones de Semana Santa, he querido escribir este post que ya llevaba tiempo como Draft, espero que sea de utilidad.
- ¿Estas intentando trabajar con RIA Services?
- ¿Quieres exponer tu servicio RIA a través de un servico web?
- ¿SOAP o REST?
- ¿Quieres exponer tus datos SQL con EntityFramework a través de un Servicio Web en cuestion de unos cuantos clicks?
Si estas interesado en conocer las respuestas a estas preguntas este es tu post:
Antes de comenzar asegura que las DLLs instaladas son las adecuadas. Para ello revisa que en la ruta “C:\Program Files (x86)\Microsoft SDKs\RIA Services\v1.0\Libraries\Server” se encuentra el siguiente conjunto de Dlls:
De no ser así, sigue lo siguientes pasos hasta conseguirlo. Esto es debido a que los distintos cambios de versiones instaladas sobreescriben a las anteriores y en la mayoria de los casos, verás que sólo existen la dlls “Microsoft.xxx” o las “System.xxx”. ¡Vaya complicación!, de no ser por mi compañero y amigo “David Gonzalez” todavía estaría instalando, ¡Muchas gracias!.
Para evitar todo esto:
Desinstala:
- Microsoft Silverlight
- Microsoft Silverlight Tools for Visual Studio 2010
- Microsoft Silverlight 4 SDK
- Microsoft F# Runtime for Silverlight 4
- WCF RIA Services v1.0 for Visual Studio 2010
- WCF RIA Services Toolkit
Instala en el siguiente orden. Importante tener muy en cuenta las versiones:
- Silverlight4_Tools.exe (en Ingles).
- RiaServices.msi (RIA Services v1.0 for Visual Studio 2010 – Mayo 2010).
- RiaServicesToolkit.msi (Aunque esta disponible la versión de Diciembre, instala la versión de Mayo 2010 con objeto de que sea compatible con RiaServices puesto que de este aun no está disponible una versión más actualizada.
Ahora el Visual Studio está listo para comenzar.
Importante: Desde Abril de 2011 ya está disponible la nueva versión de “WCF RIA Services ToolKit” que es compatible con la versión de Mayo de 2010 y por tanto podemos evitar la ardua tarea anterior, adicionalmente, tambien está disponible WCF RIA Services v1.0 SP1, con lo que tenemos todo al completo.
Ahora ya podemos comenzar a crear nuestro servico RIA:
Para exponer un servicio como RIA, añadiremos un nuevo item de tipo “Domain Service Class” a nuestro proyecto Web.
NOTA: No neceariamente tiene que ser un proyecto web, pero si pretendes sacarle partico al servicio y no solo para el acceso desde SilverLigth o LigthSwitch, entonces utiliza un servicio web como “Best Practice”:
Una vez incluido este nuevo item, veremos que en el “web.config” se ha añadido lo siguiente:
<domainServices>
<endpoints>
<add name="OData" type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</endpoints>
</domainServices>
Ahora nuestro servicio (REST) ya está listo para ser consultado como si de un Atom, RSS, etc se tratara, eso sí, no existe ningún servicio "*.svc" físicamente, sin embargo se autogenera un “.svc” de la siguente manera:
Formato de la url dinámica: -.svc/OData/">http://localhost:[Puerto]/<namespace>-<DomainServiceName>.svc/OData/
Una vez que ya tenemos este servicio, ¿Porqué no utilizarlo como SOAP o incluso como JSON?, para ello bastará con incluir las siguientes dos líneas/endpoints en la sección <domainServices> <endpoints>.
<add name="soap" type="Microsoft.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="json" type="Microsoft.ServiceModel.DomainServices.Hosting.JsonEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
Ahora tendremos tres url distintas para el acceso a cada uno de estos distintos endpoints:
- ODATA: -.svc/OData/">http://localhost:[Puerto]/<namespace>-<DomainServiceName>.svc/OData/
- SOAP: -.svc">http://localhost:[Puerto]/<namespace>-<DomainServiceName>.svc
- JSON:-.svc/json/GetProducts/"> http://localhost:[Puerto]/<namespace>-<DomainServiceName>.svc/json/GetProducts/
- Para probar el punto (1) podemos utilizar la herramienta “OData Explorer” o incluso con el Propio Exel (su extension PowerPivot Excel 2010)
- Para el punto (2) podemos añadir una referencia web a uno de nuestros proyectos y consumirlo desde .NET como cualquier otro endponit WCF, es decir, se generará el Proxy correspondiente.
- Y, para el punto (3), podemos utilizar el “JSON Explorer”. Para ello accedemos a la url correspondiente sin el último backslash (“/”) desde Internet Explorer y abrimos el fichero generado con notepad. Copiamos el contenido en el “Source” de esta pequeña herramienta y, aquí estan los datos:
Ahora sí, nuestros endpoints estarán listos para comenzar a ser usados.
Uso desde Ligthswitch.
Para que todos estos EndPoint funcionen correctamente es necesario que nuestra clase de Dominio contenga el atributo de clase “[EnableClientAccess()]”, sin embargo “VS Ligthswitch” recomienda el uso de este atributo y por tanto mostrará el siguiente mensaje: “This data source will be publicly accessible from outside your application. It is recommended that EnableClientAccess is disabled on the WCF RIA Service.”
En cualquier caso siempre podremos continuar.
Nada más por el momento, espero haber aclarado algunos temas. Si quieres conocer más detalle y ver ejemplos sobre su consumo, echa un vistazo a este enlace: WCF RIA Services Part 10 - Exposing Domain Services To Other Clients.
Saludos @Higuera la Real
Juanlu
Etiquetas: LightSwitch, WCF, WCF RIA Services, Windows Communication Foundation
domingo, 7 de diciembre de 2008
WCF: Un behavior para personalizar cabeceras HTTP.
Hace ya unos días ante la necesidad de tener que trabajar con información adicional en las cabeceras ("Headers") HTTP de WCF me encontré con un lugar más donde aplicar un nuevo "Behabior". Como siempre, el tener que crear uno nuevo implica a "vote pronto" un, ¡¡¡bufffff, una vez más a meterse en las entrañas de WCF....!!! si, esta sería quizás la reacción normal, sin embargo no fué así la mia, jejejeje...
Comento a continuación como crear una nuevo Behavior para este caso y por supuesto con objeto de evitar esta constante idea sobre nuestras mentes informáticas bastante ocupadas, :-D.
- Crear un proyecto "WCF Service Application" y añadir el siguiente método a la clase "Service1" que se crea por defecto:
- Crear un proyecto cliente de tipo consola y añadir la clausula using; "using ConsoleApplication1.localhost;" y el siguiente código al método "main":
- Para hostear el servicio en IIS añadir el attributo "[AspNetCompatibilityRequirements(RequirementsMode= AspNetCompatibilityRequirementsMode.Allowed)]" a la clase "Service1", de esta manera, estará disponible el contexto HTTP ("HttpContext.Current") para su tratamiento y de donde obtendremos la información de cabecera enviada por el cliente. Como hostear WCF en IIS.
- Publicar el servico Web en IIS, ej.: http://loclahost:9001/PruebaWCFCustomHeader/Service1.svc
- Finalmente, añadir en el proyecto consola la referencia al servicio web con la url del punto anterior.
- Run (F5) y a depurar.
public string GetHeader()
{
HttpApplication app = HttpContext.Current.ApplicationInstance;
string header = app.Request.Headers["UserQuery"];
if ((header == null) || (header.Length == 0))
throw new Exception(String.Format("Access Denied. Header information not found. {0}",
header ?? String.Empty));
return header;
}
Service1Client client = new Service1Client();
client.Endpoint.Behaviors.Add(new HttpHeaderEndPointBehavior("UsuarioCabecera1"));
string header = client.GetHeader();
client.Close();
Para que todo esto funcione es necesario generar un Behavior específico y para ello será necesario escribir un par de clases que implementen las interfaces IEndPointBehavior y IClientMessageInspector. Básicamente los métodos que nos interesan son; ApplyClientBeabior y BeforeSendRequest respectivamente:
HttpHeaderEndPointBehavior:
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using elGuerre.Pocs.HttpHeaderExtension;
namespace elGuerre.Pocs.HttpHeaderExtension
{
public class HttpHeaderEndPointBehavior : IEndpointBehavior
{
private string _UserName;
public HttpHeaderEndPointBehavior(string userAgent)
{
this._UserName = userAgent;
}
public void AddBindingParameters(ServiceEndpoint endpoint,
System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
// Nothing to do
}
public void ApplyClientBehavior(ServiceEndpoint endpoint,
System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
HttpHeaderMessageInspector inspector = new HttpHeaderMessageInspector(this._UserName);
clientRuntime.MessageInspectors.Add(inspector);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
// Nothing to do
}
public void Validate(ServiceEndpoint endpoint)
{
// Nothing to do
}
}
}
HttpHeaderMessageInspector:
using System;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
namespace elGuerre.Pocs.HttpHeaderExtension
{
public class HttpHeaderMessageInspector : IClientMessageInspector
{
private const string USER_NAME_HTTP_HEADER = "UserQuery";
private string _UserName;
private string _UserEncodedName;
public HttpHeaderMessageInspector(string userName)
{
_UserName = userName;
_UserEncodedName = null;
}
private string UserEncodedName
{
get
{
if (_UserEncodedName == null)
{
_UserEncodedName = GetBase64Encoded(_UserName);
}
return _UserEncodedName;
}
}
public void AfterReceiveReply(
ref System.ServiceModel.Channels.Message reply,
object correlationState)
{
// Nothing to do.
}
public object BeforeSendRequest(
ref System.ServiceModel.Channels.Message request,
System.ServiceModel.IClientChannel channel)
{
HttpRequestMessageProperty httpRequestMessage;
object httpRequestMessageObject;
if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
{
httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
if (string.IsNullOrEmpty(httpRequestMessage.Headers[USER_NAME_HTTP_HEADER]))
{
httpRequestMessage.Headers[USER_NAME_HTTP_HEADER] = this.UserEncodedName;
}
}
else
{
httpRequestMessage = new HttpRequestMessageProperty();
httpRequestMessage.Headers.Add(USER_NAME_HTTP_HEADER, this.UserEncodedName);
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
}
return null;
}
private static string GetBase64Encoded(string userName)
{
byte[] inData;
char[] charArr;
charArr = userName.ToCharArray();
inData = new byte[charArr.Length];
for (int i = 0; i < charArr.Length; i++)
{
inData[i] = (byte)charArr[i];
}
return Convert.ToBase64String(inData, 0, inData.Length);
}
}
}
Nota: La información de los "bindings" es la generada por defecto, así que para probar este behavior no será necesario nada más, luego, más fácil aún, :-D.
KIS: "Nada es difícil hasta que se demuestra lo contrario"
Saludos
JuanLu, elGuerre
Etiquetas: Framework .NET, WCF, Windows Communication Foundation
martes, 24 de junio de 2008
WCF & MSMQ
Hace unas semanas hablaba con un compañero acerca de como implementar una aplicación con acceso a MSMQ y tras una larga discusión, en un intento de conseguir pensar en el mejor camino de lograrlo, pensé en hacerlo con WCF, y, ¿Que mejor forma de probarlo que haciendo un ejemplo o proyecto? , pues, e aquí el motivo de este post.
Os dejo el conjunto de pasos seguidos:
Pasos:
- Generar una estructura en Visual Studio similar a la siguiente:

- Añadir el siguiente código a la interfaz, fichero IService1.cs
[ServiceContract]
public interface IService1
{
[OperationContract(IsOneWay = true, Action = "*")]
void Send(MsmqMessage<Persona> msg);
}
- Añadir el siguiente código al servicio Service1.cs
public class Service1 : IService1
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void Send(MsmqMessage<Persona> message)
{
Persona msg = (Persona)message.Body;
Console.WriteLine("Persona: [{0} {1}; ({2})] ", msg.Nombre, msg.Apellidos, msg.OtraCosaMariposa);
}
}
- En el fichero Program.cs del proyecto WcfMsmqHost añadir lo siguiente:
static void Main(string[] args)
{
string msmqPath = ConfigurationManager.AppSettings["baseAddress"];
if (!MessageQueue.Exists(msmqPath))
MessageQueue.Create(msmqPath);
Uri baseAddress = new Uri(String.Format("msmq.formatname:DIRECT=OS:{0}", msmqPath));
using (ServiceHost serviceHost = new ServiceHost(typeof(Service1), baseAddress))
{
serviceHost.Authorization.PrincipalPermissionMode = System.ServiceModel.Description.PrincipalPermissionMode.None;
serviceHost.Open();
Console.WriteLine("Servicio listo.");
Console.WriteLine("Pulsa <INTRO> para finalizar.");
Console.ReadLine();
serviceHost.Close();
}
}
- El fichero de configuración del servidor deberá contener esto:
<appSettings>
<add key="baseAddress" value=".\private$\MyTest33"/>
</appSettings>
<system.serviceModel>
<bindings>
<msmqIntegrationBinding>
<binding name="NewBinding0" exactlyOnce="false" useSourceJournal="false"
useMsmqTracing="true">
<security mode="None">
<transport msmqAuthenticationMode="None" />
</security>
</binding>
</msmqIntegrationBinding>
</bindings>
<services>
<service name="WcfMsmqHost.Service1">
<endpoint address="" binding="msmqIntegrationBinding" bindingConfiguration="NewBinding0"
contract="WcfMsmqIntegration.IService1" />
</service>
</services>
</system.serviceModel>
- Finalmente la función Main, en Program.cs del proyecto de test debe contener algo similar a esto:
string msmqPath = ConfigurationManager.AppSettings["baseAddress"];
MsmqIntegrationBinding binding = new MsmqIntegrationBinding();
EndpointAddress address = new EndpointAddress(
String.Format(@"msmq.formatname:DIRECT=OS:{0}", msmqPath));
ChannelFactory<IService1> channelFactory = new ChannelFactory<IService1>(binding, address);
// None, porque MQM no esta en Active Directory
binding.Security.Mode = MsmqIntegrationSecurityMode.None;
IService1 channel = channelFactory.CreateChannel();
Persona msg = new Persona();
msg.Nombre = "Juan Luis";
msg.Apellidos = "Guerrero";
msg.OtraCosaMariposa = "elGuerre";
MsmqMessage<Persona> message = new MsmqMessage<Persona>(msg);
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
channel.Send(message);
scope.Complete();
}
- Y el fichero de configuración del cliente deberá contener:
<configuration>
<appSettings>
<add key="baseAddress" value=".\private$\MyTest33"/>
</appSettings>
</configuration>
No olvidar incluir los espacios de nombre:
using System.ServiceModel;
using System.Messaging;
using System.ServiceModel.MsmqIntegration;
Y ni que decir tiene que la clase Persona (Persona.cs) contiene tres propiedades públicas sin más; Nombre, Apellidos y OtraCosaMariposa, incluso, no será necesario establecer el atributo DataContract.
Por otro lado y durante la configuración del ejemplo nos podemos encontrar con alguno errores y que detallo a continuación:
Caso 1:
serviceHost.Open: Binding validation failed because the binding's ExactlyOnce property is set to true while the destination queue is non-transactional. The service host cannot be opened. Resolve this conflict by setting the ExactlyOnce property to false or creating a transactional queue for this binding.
Este problema es debido a la propiedad "exactlyOnce" tiene el valor "true" y la cola no es transaccional para solucionarlo:
- Si la cola es transaccional entonces asignarle el valor "true" a esta propiedad.
- si la cola NO es transaccional asignarle el valor "false".
Caso 2:
Binding validation failed because the binding's MsmqAuthenticationMode property is set to WindowsDomain but MSMQ is installed with Active Directory integration disabled. The channel factory or service host cannot be opened.
En este caso la solución es evitar que el valor del modo de seguridad del binding sea "WindowsDomain", puesto que la integración de MSMQ con Active Directory no ha sido instalada. Bastará, y si estamos en un dominio, con instalar esta integración desde los componentes de windows. Luego para nuestro caso, tanto cliente como servidor/host deberán establecer algunos valores:
Cliente en modo programático:
binding.Security.Mode = MsmqIntegrationSecurityMode.None;
Servidor mediante fichero de configuración:
<endpoint address="" binding="msmqIntegrationBinding"
bindingConfiguration="NewBinding0" contract="WcfMsmqIntegration.IService1" />
El inconveniente de utilizar transacciones, si es que es un inconveniente, es el MSTC (Microsoft Transsaction Coordinator), que nos asegura la transaccionalidad de la operación de forma automática, pero que sin embargo, y dependiendo del entorno, es decir de la distribución entre servidores, podría resultar muy pesado e incluso no deseable. En caso de no hacer uso de la transaccionalidad, bastará con invocar de nuevo a nuestro "Sender" (envío de mensajes a MSMQ con WCF) desde el propio servidor/host y establecer un tratamiento adecuado y con esto estaría solucionado.
Finalmente y por ahora, he decir, que la ventaja de utilizar WCF para el tratamiento de colas MSMQ radica principalmente en la posibilidad de cambiar los bindings sin problema alguno, la trazabilidad totalmente automática, la seguridad de que todo va a funcionar a la primera, :-D
"Lo malo" puede ser que nos encontremos con que ya tenemos un sistema de colas MSMQ en un entorno de producción y que no podamos crear ningún servicio WCF, en tal caso, siempre podremos optar por crear un cliente WCF (ClientBase<T>), incluso también optar por el caso contrario, un servidor WCF y un cliente no WCF (System.Messaging).
http://www.cogin.com/mq/download.php
Un nuevo camino para el tratamiento de colas MSMQ.
saludos
Juanlu
Etiquetas: Visual Studio 2008, WCF, Windows Communication Foundation
jueves, 28 de febrero de 2008
WCF - Creación dinámica de una clase proxy a partir de un WSDL

No sé si a alguien le puede venir bien este ejemplo, pero seguro que sí, en cualquier caso, aquí está, :-P
Se trata de un proyecto C# que permite crear "proxys" clientes a partir de un WSDL de forma dinámica.
Es un ejemplo de una calculadora muy sencillo pero que sin embargo y lo más importante es que puede modificarse y adaptase a nuestra necesidad con bastante facilidad.
He aquí la referencia para descargarlo y pegarse un poco más con el: http://wcf.netfx3.com/files/folders/development_tools/entry6148.aspx
Una vez Más espero haber ayudado un poquito.
Juanlu
Etiquetas: Framework .NET, WCF, Windows Communication Foundation
miércoles, 27 de febrero de 2008
Hosteando en IIS un WCF con Http Basic Authentication y Compatibilidad ASP.NET (HttpContext; Session, cookies, cache, etc)
Una vez más, sigo por aquí con VS2008 y con WCF, en esta ocasión trataré de comentar, como hostear en IIS un WCF basado en un binding "Http Basic Authentication" y conseguir hacer uso de nuestra conocida clase HttpContext. Son unos cuantos pasos muy fáciles y básicos, jejeje.. ¡claro, ahora que los conozco!
Los pasos a seguir para conseguir el objetivo de este post son:
- Crear un proyecto Web de tipo "WCF Service Application".
- La plantilla nos creará un proyecto con un Interfaz (Servicio) y una clase de datos (contrato), además un servicio, lo que es nuestro Web Service que ha de implementar obligatoriamente la Interfaz.
- Seguidamente modificamos el Web.config del servicio manualmente o con nuestro maravilloso editor (Windows Communication Foundation (WCF) - BUG 1) estableciendo principalmente la configuración tal y como muestro aquí un par de pantallazos:
- A continuación tenemos dos opciones para trabajar con la compatibilidad ASP NET:
- Anadir el attributo "AspNetCompatibilityRequirements" ([AspNetCompatibilityRequirements(RequirementsMode= AspNetCompatibilityRequirementsMode.Allowed)]) al servicio, Service1 tal y como se muestra a continuación. Aprovechamos para establecer el Namespace, :-D, ¡ya sabéis "best practices"! (tempuri.org con WCF).
1 [ServiceBehavior(Namespace="http://elGuerre.loc/Service1/")]
2 [AspNetCompatibilityRequirements(RequirementsMode= AspNetCompatibilityRequirementsMode.Allowed)]
3 public class Service1 : IService1
4 {
5 public string GetData(int value)
6 {
7 return string.Format("You entered: {0}", value);
8 }
9
10 public CompositeType GetDataUsingDataContract(CompositeType composite)
11 {
12 if (composite.BoolValue)
13 {
14 composite.StringValue += "Suffix";
15 }
16 return composite;
17 }
- y, añadir la siguiente línea en el web.config.
1 <system.serviceModel>
2 <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
3 ...
O,
- Añadir el atributo "AspNetCompatibilityRequirements" ([AspNetCompatibilityRequirements(RequirementsMode= AspNetCompatibilityRequirementsMode.Required)] y,
- no incluir la configuración en el web.config.
- Publicar el servicio ("Publish").
- Modificar las propiedades del sitio Web en IIS:
- Quitar autenticación anónima
- Activar autenticación básica (dejar activa solamente esta casilla).
Ahora tenemos la compatibilidad con ASP.NET pero con la potencia de WCF, nuestra clase HttpContext (session, cookies, cache, etc) está lista para ser usada.
Si estáis interesados en esto, aquí os dejo unas cuantas referencias:
Saludos @3Cantos
Juanlu
Etiquetas: WCF, Windows Communication Foundation
lunes, 11 de febrero de 2008
Evitando el namespace "http://tempuri.org" con WCF
Hace unos días me toco quitar el ya conocido http://tempuri.org del WSDL y asignarle un namespace específico, es más, esto es lo recomendado por seguridad y como buena practica, en fin, para conseguirlo bastará con lo siguiente:
- Especificar el Namespace en el ServiceContract (Interfaces):
[ServiceContract(Namespace = "http://MyProject.Tests")]
- Especificar el Namespace en cada uno de los tipos/clases de datos o contratos; DataContract
[DataContract(Namespace="http://MyProject.Tests")]
- Quitar el http://tempuri.org de la definición del WSDL y para ello:
- Añadir el siguiente atributo al servicio:
[ServiceBehavior(Namespace="http://MyProject.Tests")] - Modificar/Añadir valor a la propiedad "bindingNamespace" del endpoint del servicio según indico concretamente en la línea 2, si no se tiene en cuenta este punto, el namespace por defecto es es "tempuri.org" y aunque cambiemos el namespace en los tres puntos anteriores, este no cambiará:
1 <service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
2 <endpoint bindingNamespace="http://MyProject.Tests" address="" binding="wsHttpBinding" contract="WcfService1.IService1">ó, graficamente:
![]()
El valor para esta propiedad, aunque puede ser cualquiera, ¡con un poco de sentido común, claro!, sería conveniente que tomara el mismo que el indicado para el "[ServiceBehavior]".
Este último punto fue el que más tardé en encontrar, ¡y mira que está visible! :-D ¡si leyera un poco de vez en cuando!, jeje... ¡si es que lo dice claramente al pie de la ventana! De todos modos, es curioso, porque todos los post y artículos que hacen referencia a los namespaces, pasan por alto este último punto.
Una ayudita más, un gran logro, :-D.
Saludos
Juanlu
Etiquetas: Framework .NET, Visual Studio 2008, WCF, Windows Communication Foundation
miércoles, 30 de enero de 2008
WCF - "ServiceModelReg -i"
Durante el día de ayer mientras trabajaba con WCF en una máquina virtual, tuve la necesidad de instalar Exchanger Server 2003 junto con OWA porque el proyecto en el que estoy en cierta forma lo requería, cual fue mi sorpresa cuando tras la instalación, los web services desarrollados con WCF (Framework 3.0) dejaron de funcionar. El error "The page cannot be display" o "Service Unavailable" ¿Por qué? ¿A que se debe esto?, pues bien, la respuesta es muy fácil,¡claro ahora que la conozco! Los ficheros ".svc" no son reconocidos, las ISAPI que tratan estos ficheros no se encuentran registradas y por tanto es necesario volverlas a registrar, jeje... ¡es lo que tiene el instalar y desinstalar cosas en las máquinas de desarrollo!
Estos son los pasos a realizar:
- C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Aspnet_regiis -i - enable. (Esta ya es bastante conocida y seguro que a más de uno nos a pasado más de una vez).
- C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg -i
Tras la ejecución de este comando
En esta página, explica los pasos más en profundidad así como la reparación manual si fuera necesario.
Justo hoy, un añito más viejo, jejeje...
Gracias a tod@s por compartirlo conmigo
Juanlu
Etiquetas: Framework .NET, Visual Studio 2008, WCF, Windows Communication Foundation
miércoles, 12 de diciembre de 2007
Windows Communication Foundation (WCF) - BUG 1
Seguimos con otra cosita interesante, ahora sobre WCF, se trata del Configurador "WCF Service Configuration Editor". Sabemos que es una herramienta "externa" pero a la vez, integrada en el Visual Studio 2008, bueno, o eso creo.
Es curioso, pero si intentamos abrir este configurador a partir de nuestro menú "popup" al hacer "click" sobre un fichero ".config" de un proyecto, debería abrirse, ese es su cometido, sin embargo, no ocurre así, no la primera vez, si, como digo, no, la primera vez, jejejeje....
Sigue estos pasos y verás:
- Abre el Visual estudio y crea un nuevo proyecto.
- Añade un item de tipo ".config"
- Haz clic con el botón derecho sobre dicho item, y...
- Ahora, selecciona: Menu: "Tools - WCF Service Configurator Editor"

Por último, vuelve a hacer "click" con el botón derecho sobre el item ".config" y........ "taaaaachaaaaannnn....", ahí esta el "tío", :-P
Pues nada, una vez más, mostrando un camino más fácil, o por lo menos, dando a conocer los tropiezos de un largo recorrido, :-D
Saludos desde Nuevos Ministerios
Juanlu
Etiquetas: Framework .NET, Visual Studio .NET, Visual Studio 2008, Windows Communication Foundation
