Wednesday, December 13, 2006 6:39 PM
mikaeld
Wrapped/Bare
I linje med Roy Osheroves artikel om "The devil wears Prada arkitektur" kommer en härlig uppstickare i WebService modevärlden... Ännu en omgång med Bare/Wrapped diskussioner!!! Jag hjälpte en gammal kollega med en ASMX implementation häromdagen, han ville ha bort de där weirda "root elementet" som bara såg fult ut och inte tillförde något, hur göra? Om du undrar vad det hela är så kommer här en liten förklaring...
Wrapped:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<VoteResponse xmlns="http://Idol2007.VotingServices.ServiceContracts/2006/12">
<VotingRequestResponse>
<ResultCode>int</ResultCode>
<Status>string</Status>
</VotingRequestResponse>
</VoteResponse>
</soap:Body>
</soap:Envelope>
Bare:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<VotingRequestResponse xmlns="http://Idol2007.VotingServices.ServiceContracts/2006/12">
<ResultCode>int</ResultCode>
<Status>string</Status>
</VotingRequestResponse>
</soap:Body>
</soap:Envelope>
Utav en mindre bra anledning är default wrapped under ASMX. Detta kan leda till lite problem när vi går över till WCF så det är inte helt fel att veta vad man skall skruva på för att ställa detta beteende. Då jag tydligen har lite dåligt minne och jag vet att ServiceFactory har en vacker liten combo för att välja wrapped/bare så slängde jag ihop ett enkelt ServiceFactoryexempel för att hitta aktuellt attribut, så här gör ServiceFactory implementationen;
namespace Idol2007.VotingServices.ServiceContracts
{
[System.Web.Services.WebService(Namespace = "http://Idol2007.VotingServices.ServiceContracts/2006/12", Name = "VotingService")]
[System.Web.Services.WebServiceBindingAttribute(ConformsTo = System.Web.Services.WsiProfiles.BasicProfile1_1, EmitConformanceClaims = true, Name = "VotingService")]
public interface IVotingService
{
[System.Web.Services.WebMethodAttribute(MessageName = "Vote")]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute(Action = "http://Idol2007.VotingServices.ServiceContracts/2006/12/Vote", ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
Idol2007.VotingServices.ServiceContracts.VotingRequestResponse Vote(Idol2007.VotingServices.ServiceContracts.VotingRequestRequest VoteRequest);
}
}
Kom ihåg den lilla otäcka buggen med att om vi anger namespace på interfacenivå (som i IVotingServices ovan) så kommer vi högaktningsfullt strunta i det i er ServiceImplementation (Tack för kaffet! Bra ungdomlig kommentar Micke...). Ni måste alltså göra detta igen om ni inte vill ha en klassisk hemsk tempUri. ServiceFactory sätter detta på både Interface och Implementationsnivå för att kompensera beteendet (buggen!) enligt nedan;
namespace Idol2007.VotingServices.ServiceImplementation
{
[System.Web.Services.WebService(Namespace = "http://Idol2007.VotingServices.ServiceContracts/2006/12", Name = "VotingService")]
[System.Web.Services.WebServiceBindingAttribute(ConformsTo = System.Web.Services.WsiProfiles.BasicProfile1_1, EmitConformanceClaims = true)]
public class VotingService : Idol2007.VotingServices.ServiceContracts.IVotingService
{...
}
}
Blev lovad finöl som tack för hjälpen, så många öl som jag har innestående från kollegor från min tid innan Microsoft... Ser fram emot en gratis helkväll!!! :-)
"What a beautiful wedding!, What a beautiful wedding!" says a bridesmaid to a waiter.
"Ah yes, but what a shame, what a shame, the poor groom's bride is a ......"