ServiceKnownTypeAttribute não aparece no WSDL
-
19-09-2019 - |
Pergunta
Eu tenho uma interface de serviço:
[ServiceContract]
[ServiceKnownType(typeof(Models.ArticleImage))]
public interface IPhotoManagementService
{
[OperationContract]
bool Login(string username, string password);
[OperationContract]
bool IsLoggedIn();
[OperationContract]
void UpdateImage(string articleID, string selectedImage);
}
Como você pode ver, especifico um typeof(Models.ArticleImage) no meu ServiceContract.
Portanto, construir o WSDL deste serviço deve fazer com que ArticleImage apareça no WSDL.Infelizmente isso não acontece de jeito nenhum.Por que é que?
ArticleImage tem DataContract nele.E quando eu retorno um ArticleImage em minha interface, o WSDL seleciona ArticleImage.
Editar:ele nem aparece na referência de serviço do projeto de consumo!
Este é o resultado de muitos testes:
- O modelo que estou tentando adicionar é um modelo LINQ to SQL.
- Quando adiciono um modelo normal com ServiceKnownType ele funciona.
- Quando uso minhas entidades LINQ to SQL em minha interface, ela funciona.
- Quando adiciono minha entidade LINQ to SQL por meio de ServiceKnownType, ela não aparece.
Solução
Por que isso precisaria? Onde seu serviço exponha algo que poderia possivelmente feijão ArticleImage
?
Re seu comentário; Ao usar [ServiceKnownType]
, o Trype extra ainda está exposto no "MEX" (consumido via "svcutil") - mas não pelo WSDL. Você está usando um cliente WCF? Deveria parecer (acabei de verificar ... sim). Em geral, porém, retornar dados vagos de um serviço na Web não é uma ótima idéia ... subtipos, com certeza! Dictionary<string,ArticleImage>
ou até Dictionary<string,SomeBaseType>
(com [KnownType]
etc), tudo bem! Mas object
, HashTable
, etc - não são uma boa ideia (IMO).
Você também pode apenas devolver um Lista do seu tipo (List<ArticleImage>
) que funcionará em todos os cenários (e será fácil para WSDL etc); E deixe o cliente fazer o dicionário no fim deles.
Com relação ao LINQ-para-SQL; Objetos para "mex" precisam ser decorados com [DataContract]
/ [DataMember]
. Você pode fazer isso na propriedade projetada da propriedade "serialização" para o DBML. Com este conjunto (modo de serialização = unidirecional), ele deve funcionar. Para ser sincero, porém, acho que você está melhor adicionando um método fictício que torna o tipo explícito da API.
Outras dicas
Somente os tipos usados como parâmetros de entrada/saída de operações de contrato de serviço são publicados no WSDL.