3

I am developing a WCF web service that needs to be able to upload files among other things.

Currently my method for adding a 'floorplan' item looks like:

[OperationContract]
[WebInvoke(Method = "GET",
    ResponseFormat = WebMessageFormat.Xml,
    BodyStyle = WebMessageBodyStyle.Wrapped,
    UriTemplate = "Floorplan?token={token}&floorplan={floorplan}")]
string XmlInputFloorplan(string token, string floorplan);

I need to alter it so that an image will be uploaded as a part of this call that can be used in a method like:

public static Guid AddFile(byte[] stream, string type);

In this case the byte[] is the content of the image. The resulting guid is then passed on to the data layer and the addition of the floorplan is finalized.

So I need to figure out two things:

1) How should I alter the XmlInputFloorplan interface method so that it also allows for an image as a parameter?
2) How do I consume the service after the alteration?

Thanks!

Here is how I solved it:

[OperationContract]
[WebInvoke(Method = "POST",
    ResponseFormat = WebMessageFormat.Xml,
    BodyStyle = WebMessageBodyStyle.Wrapped,
    UriTemplate = "Floorplan")]
XmlDocument XmlInputFloorplan(Stream content);

Expects an input XML like:

<?xml version="1.0" encoding="us-ascii" ?>
<CreateFloorplanRequest>
  <Token></Token>
  <Floorplan></Floorplan>
  <Image></Image>
</CreateFloorplanRequest>

And the Image contains a base 64 encoded string that represents the image file which I convert to byte[] via:

XmlDocument doc = new XmlDocument();
doc.Load(content);
content.Close();

XmlElement body = doc.DocumentElement;
byte[] imageBytes = Convert.FromBase64String(body.ChildNodes[2].InnerText);

In order to allow for this I had to configure the Web.config like so:

<service behaviorConfiguration="someBehavior" name="blah.blahblah">
    <endpoint 
        address="DataEntry" 
        behaviorConfiguration="web" 
        binding="webHttpBinding" 
        bindingConfiguration="basicBinding" 
        contract="blah.IDataEntry" />
</service>

<bindings>
  <webHttpBinding>
    <binding name="basicBinding" maxReceivedMessageSize ="50000000"
        maxBufferPoolSize="50000000" >
      <readerQuotas maxDepth="500000000"
        maxArrayLength="500000000" maxBytesPerRead="500000000"
        maxNameTableCharCount="500000000" maxStringContentLength="500000000"/>
      <security mode="None"/>
    </binding>
  </webHttpBinding>
</bindings>
FlyingStreudel
  • 4,434
  • 4
  • 33
  • 55

2 Answers2

4

Your URI will look completely different - something like this (I'm having to make some guesses)

[OperationContract]
[WebInvoke(Method = "POST",
           ResponseFormat = WebMessageFormat.Xml,
           BodyStyle = WebMessageBodyStyle.Wrapped,
           UriTemplate = "Floorplan?type={type}&token={token}&floorplan={floorplan}")]
Guid XmlInputFloorplan(string type, string token, string floorplan, Stream image);

I've taken the liberty of changing the byte array to a Stream which gives you the option of streaming the image should it be large (but doesn' t require streaming)

To call this you can create a WebRequest with the correct Uri (including the type, token and floorplan) and perform a POST. Make the content type the right one for the format of the image (jpeg, png, etc) and get the request stream copying the image into it. Then call GetResponse on the WebRequest to make the HTTP request

Richard Blewett
  • 6,089
  • 1
  • 18
  • 23
  • This doesn't work. Its yelling at me that it has no idea what to do with the `Stream` parameter. – FlyingStreudel Jul 12 '11 at 18:42
  • It was saying that for a post it expected exactly one parameter call stream. I ended up removing all of the arguments and just sending an xml file in the stream. Ill still accept the answer since it set me on the right path. – FlyingStreudel Jul 13 '11 at 15:19
  • I've certainly done this under .NET 4 - which version of .NET are you using? – Richard Blewett Jul 13 '11 at 19:34
  • @RichardBlewett It won't work. I have same problem. Stream paramter doesn't allow to attache any other parameter. We have to find other solution. – Faizan Mubasher Jan 06 '14 at 12:54
2

You wont be able to pass the byte array as a GET. Passing that much data in the request string wouldent work. You will need to do a http POST

Tom Squires
  • 8,848
  • 12
  • 46
  • 72