[C#.NET] HttpWebRequest extenden

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 27-07 10:18
Mijn C# kennis is een beetje gruizig, dus daarom kom ik er misschien niet helemaal uit.

Ik heb een klasse geschreven voor POST-acties naar een web-adres waarmee je met 2 simpele commando's, AddFile(string key, FileInfo f) en AddField(string key, string value), zowel files als velden kan deze klasse. Deze klasse zet dan vervolgens al deze gegevens om in een lading bytes welke naar een stream gestuurd kunnen worden voor de Stream van HttpWebRequest.GetRequestStream().
Dit werkt allemaal prima overigens.

Ik dacht echter slim te zijn en even HttpWebRequest te extenden naar HttpWebRequestMultiPart, zodat ik dan 1 klasse heb waar ik alles in kan doen en eigenlijk alleen nog maar bestanden en andere velden toe kan voegen en dan de respons op kan vragen. Ik snap alleen niet hoe ik die moet extenden, aangezien HttpWebRequest geinstantieerd wordt uit WebRequest.Create(string uri). Ik weet dus niet hoe de HttpWebRequest constructor wordt aangeroepen en als ik die al probeer te overriden dan zegt VS dat ie obsolete, maar als ik het dan toch probeer lukt het volgende ook niet:
C#:
1
2
3
4
5
6
7
8
9
//casten lukt niet
HttpWebRequestMultiPart request = WebRequest.Create("http://www.test.tld");

//ook hier niet
HttpWebRequestMultiPart request = (HttpWebRequestMultiPart)WebRequest.Create("http://www.test.tld");

//ook dit niet
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.test.tld");
(HttpWebRequestMultiPart)request.Methode() //cast lukt niet


De klasse is als volgt:
C#:
1
2
class WebRequestMultiPart : HttpWebRequest {
}

maar dan mist de constructor, dus doe ik het volgende:

C#:
1
2
3
4
5
6
7
class WebRequestMultiPart : HttpWebRequest {
  protected WebRequestMultiPart(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) 
  {
     //nog even niks
  }

}


Ik vermoed dat het te maken heeft met dat WebRequest abstract is en dat ie dus een descendant (HttpWebRequest) instantieerd.... maar die moet ik toch simpel kunnen extenden?

Engineering is like Tetris. Succes disappears and errors accumulate.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je zult dan je eigen uri schema moeten toevoegen: http://msdn.microsoft.com...quest.registerprefix.aspx

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • codeneos
  • Registratie: Augustus 2004
  • Laatst online: 11-09 00:04

codeneos

[...]

Ik zou een static method Create op de HttpWebRequestMultiPart maken welke de private contructor van je HttpWebRequestMultiPart called. Wat je doet in je eerste code sample gaat nooit werken aangezien dit geen HttpWebRequestMultiPart is (en het dus ook nooit word met casten misschien is dit wel mogelijk met een implicit contructor maar dat zou ik niet doen). Edit: of je registerd een creator interface zoals Woy voorstelt ;), maar je kan http en https niet overschrijven en het zou mijns inziens je code niet begrijpelijker maken als je custom uri prefixes gaat verzinnen :P.

Wat je beter kan doen is een zogenaamde static extension class schrijven waarmee je als het ware nieuwe methods kan toevoegen aan bestaan de classes.

Dat zou er zo uit zien:

C#:
1
2
3
4
5
6
7
8
9
10
static class WebRequestEx : HttpWebRequest {
    public static void AddField(this HttpWebRequest request, string key, string value) {
        // Jouw code voor het adden van fields hier, waar request de 
        // orignele request is waar deze method op gecalled werd.
    }

    public static void AddFile(this HttpWebRequest request, string key, FileInfo f) {
        // Jouw code hier
    }
}


Nu heb je dus eigenlijk de originele webrequest class uitgebreid met nieuwe methode die direct op alle webrequest instances beschikbaar zijn. Dit lijkt me voor jou de beste oplossing en kan je gewoon WebRequest.Create("http://www.test.tld"); blijven gebruiken voor het maken van de requests.

[ Voor 51% gewijzigd door codeneos op 09-04-2010 17:10 ]

http://www.tweakers.net/gallery/119170/sys


Acties:
  • 0 Henk 'm!

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 27-07 10:18
Dank!

Ik ben even verder gegaan en het is gelukt. De source is nog wat rommelig, dus dat ga ik opschonen, maar ik roep het nu als volgt aan:
C#:
1
2
3
4
5
6
WebRequestMultiPart request = new WebRequestMultiPart("http://test.localhost/postdata/post.php");
request.AddField("naam", "Foo");
request.AddField("achternaam", "Bar");
request.AddFile("file1", new System.IO.FileInfo(@"C:\Temp\File1.pdf"));
request.AddFile("file2", new System.IO.FileInfo(@"C:\Temp\File2.pdf"));
Console.Out.WriteLine(request.ResponseString());


En de console output wordt dan:
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
$_POST
(
    [naam] => Foo
    [achternaam] => Bar
)

$_FILES
(
    [file1] => Array
        (
            [name] => File1.pdf
            [type] => application/pdf
            [tmp_name] => C:\Windows\Temp\php42E7.tmp
            [error] => 0
            [size] => 257405
        )

    [file2] => Array
        (
            [name] => File2.pdf
            [type] => application/pdf
            [tmp_name] => C:\Windows\Temp\php42E8.tmp
            [error] => 0
            [size] => 2318575
        )

)


Ik ben tevreden :) Dank!
Vooral het boundary geneuzel was nogal wat werk zeg....

Engineering is like Tetris. Succes disappears and errors accumulate.