A veces, agregar una referencia de servicio WCF genera una referencia vacía.


159

A veces, agregar una referencia de servicio WCF genera una referencia vacía .cs y no puedo hacer referencia al servicio en ninguna parte del proyecto.

¿Alguien ha encontrado esto?

Respuestas:


377

En general, encuentro que es un problema de generación de código y la mayoría de las veces es porque tengo un conflicto de nombre de tipo que no pudo resolver.

Si hace clic con el botón derecho en su referencia de servicio y hace clic en configurar y desmarca "Reutilizar tipos en ensamblados referenciados" , probablemente resolverá el problema.

Si estaba utilizando algún aspecto de esta función, es posible que deba asegurarse de que se limpien sus nombres.


55
Cuando me sucedió, descubrí que también necesitaba cambiar el tipo de colección de ObjectModel.ObservableCollection a Generic.List
Yossi Dahan

2
Me pasó a mí porque agregué a la clase parcial.
Makotosan

2
Sin embargo, si desea usar tipos de un ensamblaje específico, puede seleccionar ese ensamblaje y funciona igual de bien (al menos en mi caso), ta
Dead

26
Me sorprende que obtenga un promedio de 50 puntos por semana de esta pregunta, incluso 6 años después. Vamos MS, arregla esto. Al menos déles a los desarrolladores algunos comentarios cuando esto no funcione bien en lugar de hacer que miren un archivo en blanco.
Anderson Imes

1
9 años después y todavía estás ayudando. ¡Gracias!
parámetro

38

Como señala la respuesta aceptada, un problema de referencia de tipo al reutilizar tipos es probablemente el culpable. Descubrí que cuando no puede determinar fácilmente el problema, usar la línea de comando svcutil.exe lo ayudará a revelar el problema subyacente (como señala John Saunders).

Como mejora, aquí hay un ejemplo rápido del uso de svcutil.

svcutil /t:code https://secure.myserver.com/services/MyService.svc /d:test /r:"C:\MyCode\MyAssembly\bin\debug\MyAssembly.dll"

Dónde:

  • / t: el código genera el código de la URL dada
  • / d: para especificar el directorio para la salida
  • / r: para especificar un ensamblaje de referencia

Referencia completa de la línea de comandos de svcutil aquí: http://msdn.microsoft.com/en-us/library/aa347733.aspx

Una vez que ejecute svcutil, debería ver la excepción lanzada por la importación. Puede recibir este tipo de mensaje sobre uno de sus tipos: "el tipo referenciado no se puede usar ya que no coincide con DataContract importado".

Esto podría ser simplemente como se especifica en que hay una diferencia en uno de los tipos en el ensamblado referenciado de lo que se generó en el DataContract para el servicio. En mi caso, el servicio que estaba importando tenía tipos más nuevos y actualizados de los que tenía en el ensamblado compartido. Esto no fue fácilmente aparente porque el tipo mencionado en la excepción parecía ser el mismo. Lo que era diferente era uno de los tipos complejos anidados utilizados por el tipo.

Hay otros escenarios más complejos que pueden desencadenar este tipo de excepción y la referencia en blanco resultante .cs. Aquí hay un ejemplo .

Si está experimentando este problema y no está utilizando tipos genéricos en sus contratos de datos ni está utilizando IsReference = true, le recomiendo verificar con certeza que sus tipos compartidos son exactamente iguales en su cliente y servidor. De lo contrario, es probable que se encuentre con este problema.


En mi caso, esto ocurrió después de que hice referencia a un ensamblado que también hacía referencia a mi servicio WCF. Eliminar ese conjunto de la lista de conjuntos para compartir tipos con fijo.
xr280xr

Recibía un mensaje de error sin sentido (solo un espacio de nombres) al agregar una referencia de servicio y esto señalaba el problema.
bcampolo

12

Cuando esto sucede, mire en la ventana Errores y en la ventana Salida para ver si hay algún mensaje de error. Si eso no ayuda, intente ejecutarlo svcutil.exemanualmente y vea si hay algún mensaje de error.


@ ¿Cómo ejecutar svcutil.exe? me puedes ayudar ?
Arul Sidthan

@Arul: use Google para buscar información sobre svcutil.exe.
John Saunders

2
No estoy seguro de si Microsoft ha leído esta publicación, pero incluso solo muestra un cuadro de mensaje que dice los errores y advertencias en lugar de simplemente ponerlos en silencio en la ventana (minimizada, en mi caso) Lista de errores lo habría hecho, así que no necesité Google esta. Alternativamente, supongo que sería útil que la pestaña se muestre en rojo o amarillo cuando haya nuevas advertencias / errores.
jrh

12

He estado golpeándome la cabeza durante todo un día con este problema exacto. Lo acabo de arreglar. Así es cómo...

El servicio tuvo que ejecutarse a través de SSL (es decir, está en https://mydomain.com/MyService.svc )

Agregar una referencia de servicio al servicio WCF en un servidor de desarrollo funcionó bien.

Implementar exactamente la misma compilación del servicio WCF en el servidor de producción en vivo, luego cambiar a la aplicación cliente y configurar la referencia del servicio para que apunte al servicio en vivo no mostró errores pero la aplicación no se compiló: Resulta que la referencia del servicio ¡El archivo Reference.cs estaba completamente vacío! La actualización de la referencia del servicio no hizo ninguna diferencia. Limpiar la solución no ayudó. Reiniciar VS2010 no hizo ninguna diferencia. Crear una nueva solución en blanco, iniciar un proyecto de consola y agregar una referencia de servicio al servicio en vivo exhibió exactamente el mismo problema.

No pensé que se debía a tipos en conflicto ni nada, pero qué diablos: reconfiguré la referencia del servicio WCF desmarcando "Reutilizar tipos en todos los ensamblados referenciados". Sin alegría; Puse la marca de verificación de nuevo.

El siguiente paso fue probar svcutil en la URL de referencia para ver si eso ayudaría a descubrir el problema. Aquí está el comando:

svcutil /t:code https://mydomain.com/MyService.svc /d:D:\test

Esto produjo lo siguiente:

Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, Version 4.0.30319.1]
Copyright (c) Microsoft Corporation.  All rights reserved.

Attempting to download metadata from 'https://mydomain.com/MyService.svc' using WS-Metadata Exchange or DISCO.
Error: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Schema with target namespace 'http://mynamespace.com//' could not be found.
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://mynamespace.com//']/wsdl:portType[@name='IMyService']


Error: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.
XPath to wsdl:portType: //wsdl:definitions[@targetNamespace='http://mynamespace.com//']/wsdl:portType[@name='IMyService']
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:binding[@name='WSHttpBinding_IMyService']


Error: Cannot import wsdl:port
Detail: There was an error importing a wsdl:binding that the wsdl:port is dependent on.
XPath to wsdl:binding: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:binding[@name='WSHttpBinding_IMyService']
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:service[@name='MyService']/wsdl:port[@name='WSHttpBinding_IMyService']


Generating files...
Warning: No code was generated.
If you were trying to generate a client, this could be because the metadata documents did not contain any valid contracts or services
or because all contracts/services were discovered to exist in /reference assemblies. Verify that you passed all the metadata documents to the tool.

Warning: If you would like to generate data contracts from schemas make sure to use the /dataContractOnly option.

Eso me dejó completamente perplejo. A pesar de buscar mucho en Google y de ser realmente un poco cruzado, y de reconsiderar una carrera como conductor de autobús, finalmente consideré por qué funcionó bien en el cuadro de desarrollo. ¿Podría ser un problema de configuración de IIS?

Me conecté de forma simultánea a los cuadros de desarrollo y en vivo, y en cada uno encendí el Administrador de IIS (ejecutando IIS 7.5). Luego, revisé cada ajuste de configuración en cada cuadro, comparando los valores en cada servidor.

Y ahí está el problema: en "Configuración de SSL" para el sitio, asegúrese de que "Requerir SSL" esté marcado y marque el botón de radio Certificados de cliente para "Aceptar". ¡Problema fijo!


5

He encontrado que esto ocurre comúnmente cada vez que agrego una referencia, la elimino y luego vuelvo a agregar un servicio con el mismo nombre. Los conflictos de tipo parecen ser causados ​​por los archivos antiguos que quedan en algún lugar que Visual Studio aún puede ver. Todo lo que necesito hacer para solucionarlo es limpiar antes de agregar la nueva referencia.

  1. Elimine la referencia de servicio que tiene problemas.
  2. Haga clic en el nombre del proyecto en el Explorador de soluciones para resaltar el proyecto.
  3. Haga clic derecho en la referencia del proyecto.
  4. Cerca de la parte superior de la lista de contexto, haga clic en el elemento Limpiar .
  5. Agregue su referencia de servicio como lo haría normalmente.

Espero que esto ayude.


3

Tuve este problema con un Silverlight 5 actualizado desde una versión anterior.

Incluso volver a agregar la referencia de servicio todavía me dio un Reference.cs vacío

Terminé teniendo que crear un nuevo proyecto y volver a crear la referencia del servicio. Esto es algo para probar si ha pasado más de media hora en esto. Incluso si está decidido a arreglar el proyecto original, puede probar esto solo para ver qué sucede y luego trabajar hacia atrás para tratar de solucionar el problema.

Nunca descubrí exactamente cuál era el problema, pero posiblemente algo en el archivo .csproj no se actualizó o alguna configuración salió mal.


1
ok resultó que estaba haciendo referencia a una versión anterior de System.Xml.Linq- así que verifique las versiones de todas sus DLL si ha cambiado las versiones
Simon_Weaver

1

Si recientemente agregó una colección a su proyecto cuando esto comenzó a ocurrir, el problema puede ser causado por dos colecciones que tienen el mismo atributo CollectionDataContract :

[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }

[CollectionDataContract(Name="AItems", ItemName="A")]  // Wrong
public class CollectionB : List<B> { }

Solucioné el error barriendo mi proyecto y asegurándome de que cada atributo Name y ItemName fuera único:

[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }

[CollectionDataContract(Name="BItems", ItemName="B")]  // Corrected
public class CollectionB : List<B> { }

Luego actualicé la referencia del servicio y todo volvió a funcionar.



1

La técnica que funcionó para mí en mi caso, después de leer estas respuestas en vano, fue simplemente comentar todo mi contrato y descomentar bits hasta que ya no funciona, en una búsqueda binaria. Eso reduce el código ofensivo.

Entonces solo tienes que adivinar qué hay de malo con ese código.

Algunos comentarios de error en la herramienta habrían ayudado, por supuesto.

Estoy escribiendo un contrato de servicio web. Tenía una enumeración de marcador de posición sin miembros. Está bien. Pero si lo uso en una propiedad de otra clase y reutilizo el dll del contrato en el cliente, el codegen explota sin mensaje de error. Ejecutar svcutil.exe no ayudó, simplemente no pudo generar un archivo cs sin mencionar por qué.


Comentando todos los contratos de operación funcionó para mí. Estaba mirando los métodos equivocados como el culpable. Gracias por el enfoque de regreso a lo básico para la resolución de problemas.
fizch

1

Lo siguiente no está en la lista aquí, y fue la solución que adopté (SvcUtils fue útil para ver el mensaje de error. Sin embargo, el error que obtuve fue wrapper type message cannot be projected as a data contract type since it has multiple namespaces. Es decir, seguí este ejemplo y me enteré wsdl.exepor esta publicación).

En mi caso, simplemente ejecutar wsdl [ my-asmx-service-address ] generó un .csarchivo libre de problemas , que incluí en mi proyecto e instalé para usar el servicio.


0

Como señala @dblood, el problema principal está en DataContractSerializer, que no reutiliza correctamente los tipos. Ya hay algunas respuestas aquí, así que comenzaré agregando algunos pros y contras sobre estos:

  • El indicador 'IsReference' causa muchos problemas, pero eliminarlo no siempre es la respuesta (específicamente: en situaciones de recursión).
  • El problema subyacente es que el contrato de datos de alguna manera no es el mismo que los nombres de tipo, aunque a veces lo sean (¿eh? ¡Sí, lo has leído bien!). Aparentemente, el serializador es bastante exigente y es muy difícil encontrar el verdadero problema.
  • Eliminar las 'comprobaciones de referencias' de 'Configurar referencia de servicio' funciona, pero te deja con múltiples implementaciones. Sin embargo, a menudo reutilizo las interfaces SOAP en las DLL. Además, en la mayoría de las SOA maduras que conozco, múltiples interfaces de servicios implementan y extienden las mismas clases de interfaz. La eliminación de las comprobaciones de 'usar tipos referenciados' da como resultado una situación en la que ya no puede simplemente pasar objetos.

Afortunadamente, si tiene el control de su servicio, existe una solución simple que resuelve todos estos problemas. Esto significa que aún puede reutilizar las interfaces de servicio a través de las DLL, que es IMO imprescindible para una solución adecuada. Así es como funciona la solución:

  1. Cree una interfaz DLL separada. En esa DLL, incluya todos los DataContract y ServiceContract's; Ponga ServiceContract en sus interfaces.
  2. Derive la implementación del servidor desde la interfaz.
  3. Use la misma DLL para construir el cliente usando su método favorito. Por ejemplo (IMyInterface es la interfaz del contrato de servicio):

    var httpBinding = new BasicHttpBinding();
    var identity = new DnsEndpointIdentity("");
    var address = new EndpointAddress(url, identity, new AddressHeaderCollection());
    var channel = new ChannelFactory<IMyInterface>(httpBinding, address);
    return channel.CreateChannel();

En otras palabras: no use la funcionalidad 'agregar referencia de servicio' , pero obligue a WCF a usar los tipos de servicio (correctos) omitiendo la generación de proxy. Después de todo, ya tienes estas clases.

Pro:

  1. Omite el proceso svcutil.exe, lo que significa que no tiene ningún problema IsReference
  2. Los tipos y nombres de DataContract son correctos por definición; después de todo, tanto el servidor como el cliente usan la misma definición.
  3. Si extiende la API o usa tipos de otra DLL, (1) y (2) aún se mantienen, por lo que no tendrá ningún problema allí.

Contras:

  1. Los métodos A-sync son una molestia, ya que no genera un proxy a-sync. Como resultado, no recomendaría hacer esto en aplicaciones Silverlight.

0

También tuve el problema de referencias de servicio rotas cuando trabajaba con referencias de proyecto en ambos lados (el proyecto de servicio y el proyecto que tiene una referencia al servicio). Si el .dll del proyecto al que se hace referencia, por ejemplo, se llama "Contoso.Development.Common", pero el nombre del proyecto simplemente se acorta a "Común", también las referencias de proyecto a este proyecto se denominan simplemente "Común". Sin embargo, el servicio espera una referencia a "Contoso.Development.Common" para resolver clases (si esta opción está activada en las opciones de referencia del servicio).

Entonces, con el explorador, abrí la carpeta del proyecto que hace referencia al servicio y al proyecto "Común". Allí edité el archivo de proyecto VS (.csproj) con el bloc de notas. Busque el nombre del proyecto de referencia (que es "Common.csproj" en este ejemplo) y encontrará rápidamente la entrada de configuración que representa la referencia del proyecto.

Cambié

<ProjectReference Include="..\Common\Common.csproj"> <Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project> <Name>Common</Name> </ProjectReference>

a

<ProjectReference Include="..\Common\Common.csproj"> <Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project> <Name>Contoso.Development.Common</Name> </ProjectReference>

Lo importante es cambiar el nombre de la referencia al nombre del dll que el proyecto referenciado tiene como salida.

Luego vuelva a VS. Allí se le pedirá que vuelva a cargar el proyecto, ya que se ha modificado fuera de VS. Haz clic en el botón de recarga.

Después de hacerlo, agregar y actualizar la referencia de servicio funcionó tal como se esperaba.

Espero que esto también ayude a alguien más.

Saludos MH


0

Me enfrenté a un problema similar ayer durante el desarrollo. Descubrí que estaba usando el mismo espacio de nombres en 2 versiones diferentes de contratos.

Tenemos 2 versiones de contratos, por ejemplo, versión 4 y versión 5. Copié todos los contratos de la versión 4 y renombré todo el espacio de nombres de la versión 4 a la versión 5. Mientras hacía esto, olvidé cambiar el nombre del espacio de nombres de v4 a v5 en uno de los archivos. Debido al conflicto del espacio de nombres, el archivo Reference.cs estaba vacío.

Este problema es difícil de solucionar, ya que no recibe ningún mensaje de error al generar la referencia del servicio. Para identificar este problema, validaría manualmente todos los archivos nuevos que había creado. Hay otras formas de resolver este problema. Este es el primer paso que debe realizar antes de buscar otras opciones.


0

Gracias a la publicación anterior de John Saunders que me dio una idea para mirar en la ventana Error. Estuve todo el día embolsando mi cabeza y estaba buscando en la ventana de Salida cualquier error.

En mi caso, el culpable fue ISerializable. Tengo una clase DataContract con la propiedad DataMember de tipo Exception. No puede tener ningún DataMember de tipo que tenga una palabra clave ISerializable. En esta excepción, ISerializable apenas la eliminé, todo funcionó a las mil maravillas.


0

Al intentar solucionar este problema svcutil, recibí el error mencionado en la respuesta de dblood ("el tipo de referencia no se puede usar ya que no coincide con el DataContract importado").

En mi caso, la causa subyacente parecía ser un tipo de enumeración que tenía el atributo DataContract, pero cuyos miembros no estaban marcados con el atributo EnumMember. La clase de problema svcutilapuntada tenía una propiedad con ese tipo de enumeración.

Esto encajaría mejor como un comentario a la respuesta de dblood, pero no hay suficiente representante para eso ...


0

En mi caso, tenía una solución con el proyecto VB Web Forms que hacía referencia a un Control de usuario de C #. Tanto el proyecto VB como el proyecto CS tenían una referencia de servicio para el mismo servicio. La referencia apareció en Referencias de servicio en el proyecto VB y en la agrupación de Servicios conectados en el proyecto CS (marco).

Para actualizar la referencia de servicio (es decir, hacer que el archivo Reference.vb no esté vacío) en el proyecto de formularios web de VB, necesitaba QUITAR EL PROYECTO CS, luego actualizar la Referencia de servicio de VB, luego agregar el proyecto CS nuevamente la solución.


0

Sigue estos pasos:

  1. Eliminar referencia de servicio
  2. Cerrar Visual Studio
  3. Eliminar / Bin y / Obj carpetas.
  4. Abra Visual Studio.
  5. Agregue la referencia de servicio.
  6. De nada :)

Parece que se dejan algunas referencias en estas carpetas al agregar el servicio, lo que causa errores durante la generación automática de código.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.