Toon posts:

[ASP.NET] Geserialized object via webservice assembly fout

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik probeer een object geserialized naar een webservice te sturen (C#).

Ik heb het object eerst [Serializable] gemaakt. Vervolgens serialize ik het object met een BinaryFormatter naar een MemoryStream, die ik Base64 encode in een string.

Die string stuur ik naar de WebService, waar ik hem Base64 decode en in een MemoryStream zet. Deze memorystream deserialize ik vervolgens.

Ik krijg dan de "Cannot find assembly" error als ik de WebService aanroep, aangezien hij probeert de versturende Assembly te zoeken, in plaats van die van de WebService.

Kan ik misschien tijdens het serializen meegeven dat hij de Assembly info niet meeneemt? Of kan ik die, tijdens het deserializen, weer wijzigen naar de nieuwe Assembly?

Als er meer info nodig is dan post ik wel ff wat code, maar die staat verspreid over een aantal klassen dus dat gaat niet zo heel makkelijk.

  • whoami
  • Registratie: December 2000
  • Laatst online: 16:53
Je wilt een object naar een webservice versturen ?

Just a thought: kan je dat object (dat je serializable maakt, dmv het Serializable attribuut, of dmv de ISerializable interface) niet gewoon meegeven als argument v/d web-method die je aanroept ? :?

https://fgheysels.github.io/


Verwijderd

Topicstarter
Had ik al een keer gebrobeerd, even kijken wat daar precies mis ging...

Edit:

Hij zegt dat er geen public default constructor in staat.. maar:
code:
1
public SecurePrincipal(){}


lijkt mij een public default constructor, toch?

[ Voor 56% gewijzigd door Verwijderd op 25-05-2004 14:55 ]


Verwijderd

Topicstarter
Ik krijg nu de fout dat IIdentity, aangezien het een interface is, niet geserialized kan worden.

Ik heb nu ook een extra implementatie van IIdentity geschreven die wel serializable is, maar nu klopt de implementation van IPrinciple niet meer aangezien die een IIdentity verwacht, en niet mijn serializable variant..

Dat zelf serializen leek mij wel een handige oplossing, maar als ik die Assembly niet kan forceren...

  • whoami
  • Registratie: December 2000
  • Laatst online: 16:53
:?
Als je een custom class hebt, die de IIdentity interface implementeert, dan is die class eigenlijk ook een IIdentity, dus die moet je kunnen doorgeven aan een property / method die een IIdentity verwacht.

https://fgheysels.github.io/


Verwijderd

Topicstarter
code:
1
2
3
4
5
6
7
public IIdentity Identity
{
    get
    {
        return _identity;
    }
}


werkt uiteraard niet, een interface is niet serializable, ookal is _identity van het type SecureFormsIdentity, dus geen interface...

code:
1
2
3
4
5
6
7
public SecureFormsIdentity Identity
{
    get
    {
        return _identity;
    }
}


werkt ook niet:

(15): 'EWS.Security.SecurePrincipal' does not implement interface member 'System.Security.Principal.IPrincipal.Identity'. 'EWS.Security.SecurePrincipal.Identity' is either static, not public, or has the wrong return type.

terwijl
code:
1
2
[Serializable]  
public class SecureFormsIdentity : IIdentity


Dus de geimplementeerde interface, geldt niet als het goede type voor een andere interface.

Misschien kan ik FormsIdentity extenden, en hem zo serializable maken. Maar dan is waarschijnlijk het volgende probleem dat de Ticket niet serializable is, etc...

Dat probeerde ik af te vangen door de Binary Format, maar ik weet nog steeds niets om die assembly goed te krijgen. Iets wat met de SOAP formatter wel goed gaat, maar die kan dus niet alles serializen...

  • whoami
  • Registratie: December 2000
  • Laatst online: 16:53
Probeer het eens door de interface ISerializable te implementeren ipv mbhv het Serializable object te werken.
Dat Serializable attribuut heeft een aantal beperkingen, terwijl je mbhv ISerializable veel flexibeler bent.

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 16:53
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[Serializable]
public class blaat : ISerializable
{
    
  private IFGInter _test;
  private int      _leeftijd;
    
  public blaat()
  {
      _leeftijd = 25;
      _test = new MySpul();
  }
        
   public void GetObjectData(SerializationInfo info , StreamingContext context)
   {
        info.AddValue ("interface", _test);
        info.AddValue ("leeftijd", _leeftijd);
   }
        
}


Deze class is perfect serialiseerbaar.

Om ze nog te kunnen deserializen, moet je ook nog een 'speciale' constructor maken.

[ Voor 12% gewijzigd door whoami op 25-05-2004 16:23 ]

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 16:53
Hoe heb je het nu opgelost ?

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ik heb het nog niet opgelost, helaas... Ik ben bezig met een workaround, maar dat is eigenlijk te omslachtig...

  • whoami
  • Registratie: December 2000
  • Laatst online: 16:53
Ik weet natuurlijk niet wat jouw bedoeling is enzo, en waar je naartoe wilt, maar ik heb even een klein testje in elkaar geflanst.

webservice
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Service1 : System.Web.Services.WebService
{
    public Service1()
    {
        InitializeComponent();
    }

    [WebMethod]
    public string GetName (TheClass c )
    {
        return c.GetName();        
    }
    
    [WebMethod]
    public string GetKlop (TheClass c)
    {
        return c.GetKlopInfo();
    }
    
    [WebMethod]
    public string GetSomething()
    {
        return "zwiep";
    }
}


Custom class TheClass, custom interface en custom class die interface implementeert
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
interface IMyInterface
{
    string GetSome();
}
    
[Serializable]
public class SomeClass : IMyInterface
{
    private string test = "blaat";
        
    public string GetSome()
    {
        return test;
    }
}
    
[Serializable]
public class TheClass : ISerializable
{
    
    private string          naam;
    private IMyInterface    klop;
    
    public TheClass()
    {
        naam = "ikke";
        klop = new SomeClass();
    }
        
    public TheClass( string s )
    {
        naam = s;
        klop = new SomeClass();
    }
        
    public void GetObjectData(SerializationInfo info , StreamingContext context )
    {
        info.AddValue ("naam", naam);
        info.AddValue ("inter", klop);
    }
        
    public TheClass( SerializationInfo info, StreamingContext context )
    {
        naam = info.GetString ("naam");
        klop = (IMyInterface)info.GetValue("inter", typeof(IMyInterface));
    }
        
    public string GetName()
    {
        return naam;
    }
        
    public string GetKlopInfo()
    {
        return klop.GetSome();
    }
        
}


Client app code
code:
1
2
3
4
5
6
7
8
9
10
11
private void button1_Click(object sender, System.EventArgs e)
{
    localhost.Service1 c = new localhost.Service1();
    textBox1.Text = c.GetName(new localhost.TheClass());
}

private void button2_Click(object sender, System.EventArgs e)
{
    localhost.Service1 c = new localhost.Service1();
    textBox2.Text = c.GetKlop(new localhost.TheClass());
}

https://fgheysels.github.io/


Verwijderd

Topicstarter
Dank je wel... Mijn probleem is echter het volgende:

Ik heb een website waar mensen inloggen met een FormsIdentity. Deze wil ik beperkt toegang geven tot verdere webservices, afhankelijk van wie ze zijn.

Ik heb daarvoor een SecurePrinciple class gemaakt dat zichzelf op juistheid kan controleren dmv van een checksum die die bijhoudt. Als je deze dus meestuurt weet je zeker dat de Principle rechtmatig verkregen is, aangezien de checksum met een passphrase gemaakt is, en op de ontvangende server die passphrase bekend is.

Nu maak ik een webservice afgeschermd, je moet dus ingelogd zijn om hem te kunnen gebruiken, afhankelijk van je rol.

Ik dacht eerst om het Principal object mee te sturen, en op de andere server neer te zetten, om zodoende daar ermee verder te kunnen. Dat gaat dus voorlopig niet werken.

Ik probeer nu door middel van Credentials meezenden de Identity te verkrijgen VOORDAT de beveiliging een 401 geeft.

  • whoami
  • Registratie: December 2000
  • Laatst online: 16:53
Je kan je webservice toch afschermen door gebruik te maken van de web.config file ?
Daarin heb je toch een sectie waarin je aangeeft welke authentication je wilt gebruiken (Forms Auth in dit geval), en een sectie waarin je kunt aangeven welke users er ge-authoriseerd zijn om de service te gebruiken?

Of sla ik de plank nu helemaal mis?

https://fgheysels.github.io/


Verwijderd

Topicstarter
Het probleem is dat Forms Authentication niet werkt met Web Services.

Ik heb het nu opgelost door SOAP Headers mee te sturen, en die in de globals.asax.cs uit te lezen, en zo tijdens authenticatie een nieuwe identity te maken.

Dus dan heb ik een GenericIdentity met mijn zichzelf controlerende SecurePrincipal (CheckSum met Salt), en weet ik zeker dat de gebruiker geauthenticeerd is, via de orginele FormsIdentity...

Dan kan je de webservices dichtgooien (web.config) met
code:
1
2
3
4
<Athentication mode="None" />
<Authorization>
   <deny users="?" />
</Authorization>


Volgens mij een goede oplossing, aangezien ik nu ook aangepaste user credentials kan meesturen in de SOAP Header, gewoon username/password was namelijk niet goed genoeg.
Pagina: 1