IT

때때로 WCF 서비스 참조를 추가하면 빈 참조가 생성됩니다.

lottoking 2020. 6. 8. 08:02
반응형

때때로 WCF 서비스 참조를 추가하면 빈 참조가 생성됩니다.


때때로 WCF 서비스 참조를 추가하면 빈 reference.cs가 생성되고 프로젝트의 어느 곳에서나 서비스를 참조 할 수 없습니다.

누구든지 이것을 만난 적이 있습니까?


일반적으로 코드 생성 문제이며 대부분 해결할 수없는 유형 이름 충돌이 있기 때문에 발생합니다.

서비스 참조를 마우스 오른쪽 단추로 클릭하고 구성을 클릭하고 "참조 어셈블리의 유형 재사용"을 선택 취소 하면 문제가 해결 될 수 있습니다.

이 기능의 일부 측면을 사용중인 경우 이름을 정리해야합니다.


허용되는 답변에서 알 수 있듯이 유형을 재사용 할 때 유형 참조 문제가 원인 일 수 있습니다. 문제를 쉽게 결정할 수없는 경우 svcutil.exe 명령 줄을 사용하면 기본 문제를 밝히는 데 도움이됩니다 (John Saunders가 지적한 것처럼).

다음은 svcutil을 사용하는 간단한 예입니다.

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

어디:

  • / t : code는 주어진 URL에서 코드를 생성합니다
  • / d : 출력 디렉토리를 지정합니다
  • / r : 참조 어셈블리를 지정합니다

전체 svcutil 명령 줄 참조 : http://msdn.microsoft.com/en-us/library/aa347733.aspx

svcutil을 실행하면 가져 오기에서 예외가 발생하는 것을 볼 수 있습니다. 유형 중 하나에 대해 다음 유형의 메시지가 표시 될 수 있습니다. "참조 된 유형은 가져온 DataContract와 일치하지 않으므로 사용할 수 없습니다."

이는 서비스에 대한 DataContract에서 생성 된 것과 참조 된 어셈블리의 유형 중 하나에 차이가 있다는 점에서 명시 적으로 지정할 수 있습니다. 필자의 경우 가져오고 있던 서비스에 공유 어셈블리에 있던 것보다 최신의 업데이트 된 유형이있었습니다. 예외에서 언급 된 유형이 동일 해 보였기 때문에 쉽게 알 수 없었습니다. 다른 점은 유형에 사용되는 중첩 복합 유형 중 하나였습니다.

이러한 유형의 예외가 발생하여 결과적으로 빈 참조가 발생하는 다른 복잡한 시나리오가 있습니다. 여기에 하나의 예가 있습니다.

이 문제가 발생하고 데이터 계약에서 일반 유형을 사용하지 않거나 IsReference = true를 사용하지 않는 경우 클라이언트와 서버에서 공유 유형이 정확히 동일한 지 확인하는 것이 좋습니다. 그렇지 않으면이 문제가 발생할 수 있습니다.


나는이 정확한 문제로 하루 종일 내 머리를 강타했다. 방금 수정했습니다. 방법은 다음과 같습니다.

서비스 SSL을 통해 실행되어야했습니다 (예 : https://mydomain.com/MyService.svc에 있음 )

개발 서버에서 WCF 서비스에 대한 서비스 참조를 추가하면 정상적으로 작동합니다.

라이브 프로덕션 서버에 정확히 동일한 WCF 서비스 빌드를 배포 한 다음 클라이언트 응용 프로그램으로 전환하고 라이브 서비스를 가리 키도록 서비스 참조를 구성하면 오류가 표시되지 않지만 앱은 빌드되지 않습니다. Reference.cs 파일이 완전히 비었습니다! 서비스 참조를 업데이트해도 아무런 차이가 없었습니다. 솔루션을 청소해도 도움이되지 않았습니다. VS2010을 다시 시작해도 아무런 차이가 없습니다. 새로운 빈 솔루션을 만들고 콘솔 프로젝트를 시작하고 라이브 서비스에 서비스 참조를 추가하면 정확히 같은 문제가 발생했습니다.

충돌하는 유형이나 다른 것이 원인이라고 생각하지 않았지만 "참조 된 모든 어셈블리에서 유형 재사용"을 선택 취소하여 WCF 서비스 참조를 재구성했습니다. 기쁨이 없다. 확인 표시를 다시 넣습니다.

다음 단계는 참조 URL에서 svcutil 을 시도 하여 문제를 발견하는 데 도움이되는지 확인하는 것입니다. 명령은 다음과 같습니다.

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

이것은 다음을 생성했습니다.

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.

그것은 완전히 저주 받았다. 심한 인터넷 검색과 교차로에 가까워지고 버스 운전사로서의 경력을 다시 생각하기는했지만 마침내 개발 박스에서 제대로 작동하는 이유를 고려했습니다. IIS 구성 문제 일 수 있습니까?

나는 개발 박스와 라이브 박스에 동시에 원격 접속했고, 각각 IIS 관리자 (IIS 7.5 실행)를 시작했다. 다음으로 각 상자의 각 구성 설정을 살펴보고 각 서버의 값을 비교했습니다.

문제가 있습니다. 사이트의 "SSL 설정"에서 "SSL 필요"가 선택되어 있는지 확인하고 "승인"에 대한 클라이언트 인증서 단일 선택 단추를 확인하십시오. 문제가 해결되었습니다!


When this happens, look in the Errors window and the Output window to see if there are any error messages. If that doesn't help, try running svcutil.exe manually, and see if there are any error messages.


I have found this to occur commonly whenever I add a reference, remove it, and then re-add a service with the same name. The type conflicts appear to be caused by the old files remaining somewhere that Visual Studio can still see. All I need to do to fix it, is a clean before adding the new reference.

  1. Remove the service reference having issues.
  2. Click on the project name in the Solution Explorer to highlight the project.
  3. Right-click on the project reference.
  4. Near the top of the context list, click the Clean item.
  5. Add your service reference as you normally would.

Hope this helps.


I had this problem with a Silverlight 5 upgraded from a previous version.

Even re-adding the service reference still gave me an empty Reference.cs

I ended up having to create a brand new project and re-creating the service reference. This is something to try if you've spent more than about half an hour on this. Even if you're determined to fix the original project you may want to try this just to see what happens and then work backwards to try to fix the problem.

I never did figure out exactly what the problem was - but possibly something in the .csproj file wasn't upgraded or some setting went wrong.


If you recently added a collection to your project when this started to occur, the problem may be caused by two collections which have the same CollectionDataContract attribute:

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

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

I fixed the error by sweeping through my project and ensuring that every Name and ItemName attribute was unique:

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

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

Then I refreshed the service reference and everything worked again.


My issue was that I left the "mex" onto the end of my web service link.

Instead of "http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc/mex"

Use "http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc"


The technique that worked for me in my case, after reading these answers to no avail, was simply to comment out all of my contract, and uncomment bits until it doesn't work anymore, in a binary search fashion. That narrows down the offending bit of code.

Then you just have to guess what's wrong with that code.

Some error feedback in the tool would have helped, of course.

I am writing a web service contract. I had a placeholder enum with no members. That's OK. But if I use it in a property of another class, and re-use the contract dll on the client, the codegen explodes with no error message. Running svcutil.exe didn't help, it just failed to output a cs file without mentioning why.


The following is not listed here, and it was the solution I adopted (SvcUtils was useful in seeing the error message. However, the error I got was wrapper type message cannot be projected as a data contract type since it has multiple namespaces. Meaning, I followed this lead, and learned about wsdl.exe via this post).

In my case, simply running wsdl [my-asmx-service-address] generated a problem-free .cs file, which I included in my project and instanced to use the service.


As @dblood points out, the main pain is in the DataContractSerializer, that doens't correctly re-use the types. There are already some answers here so I'll start by adding some pro's and cons about these:

  • The 'IsReference' flag causes a lot of trouble, but removing it isn't always the answer (specifically: in situations with recursion).
  • The underlying issue is that the data contract is somehow not the same as the type names, even though they sometimes are (huh? Yes, you read that right!). Apparently the serializer is quite picky and it's very hard to find the real issue.
  • Removing the 'references checks' from the 'Configure service reference' works, but leaves you with a multiple implementations. However, I often reuse SOAP interfaces across DLL's. Also, in most mature SOA's that I know, multiple services interfaces implement and extend the same interface classes. Removing 'use referenced types' checks results in a situation where you cannot simply pass objects around anymore.

Fortunately, if you are in control of your service, there is a simple solution that solves all these issues. This means you can still re-use service interfaces across DLL's - which is IMO a must-have for a proper solution. This is how the solution works:

  1. Create a separate interface DLL. In that DLL, include all DataContract and ServiceContract's; put ServiceContract's on your interfaces.
  2. Derive the server implementation from the interface.
  3. Use the same DLL to construct the client using your favorite method. For example (IMyInterface is the service contract interface):

    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();
    

In other words: Don't use the 'add service reference' functionality, but force WCF to use the (correct) service types by bypassing the proxy generation. After all, you already have these classes.

Pro's:

  1. You bypass the svcutil.exe process, which means you don't have any IsReference issues
  2. DataContract types and names are correct by definition; after all, both server and client use the very same definition.
  3. If you extend the API or use types from another DLL, (1) and (2) still hold, so you won't run in any trouble there.

Cons:

  1. A-sync methods are a pain, since you don't generate an a-sync proxy. As a result, I wouldn't recommend doing this in Silverlight applications.

I also had the issue of broken service references when working with project references on both sides (the service project and the project having a reference to the service). If the the .dll of the referenced project for example is called "Contoso.Development.Common", but the projects name is simply shortened to "Common", also project references to this project are named just "Common". The service however expects a reference to "Contoso.Development.Common" for resolving classes (if this option is activated in the service reference options).

So with explorer I opened the folder of the project which is referencing the service and the "Common"-project. There I editet the VS project file (.csproj) with notepad. Search for the name of the refernced project (which is "Common.csproj" in this example) and you will quickly find the configuration entry representing the project reference.

I changed

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

to

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

The important thing is to change the name of the reference to the name of the dll the referenced project has as output.

Then switch back to VS. There you will be asked to reload the project since it has been modified outside of VS. Click the reload button.

After doing so adding und updating the service reference worked just as expected.

Hope this also helps someone else.

Regards MH


I faced similar issue yesterday during development. I found out I was using same namespace in 2 different versions of contracts.

We've 2 version of contracts for example version4 and version5. I've copied all the contracts from version4 and renamed all the namespace from version4 to version5. While doing this I forgot to rename the namespace from v4 to v5 in one of the files. Due to namespace conflict, Reference.cs file was empty.

This issue is hard to troubleshoot as you don't get any error message while generating the service reference. To identify this issue I'd manually validate all the new files I'd created. There are other ways to solve this issue. This is the first step you should perform before going for other options.


Thanks to John Saunders post above which gave me an idea to look into Error window. I was bagging all day my head and I was looking at Output window for any error.

In my case the culprit was ISerializable. I have a DataContract class with DataMember property of type Exception. You cannot have any DataMember of type which has ISerializable keyword. In this Exception has ISerializable as soon as I removed it everything worked like a charm.


When attempting to troubleshoot this problem with svcutil, I received the error referred to in dblood's answer ("referenced type cannot be used since it does not match imported DataContract").

In my case the underlying cause seemed to be an enum type that had the DataContract attribute, but whose members were not marked with the EnumMember attribute. The problem class svcutil pointed at had a property with that enum type.

This would fit better as a comment to dblood's answer, but not enough rep for that...


In my case I had a solution with VB Web Forms project that referenced a C# UserControl. Both the VB project and the CS project had a Service Reference to the same service. The reference appeared under Service References in the VB project and under the Connected Services grouping in the CS (framework) project.

In order to update the service reference (ie, get the Reference.vb file to not be empty) in the VB web forms project, I needed to REMOVE THE CS PROJECT, then update the VB Service Reference, then add the CS project back into the solution.

참고URL : https://stackoverflow.com/questions/1408509/sometimes-adding-a-wcf-service-reference-generates-an-empty-reference-cs

반응형