2009-03-20 20 views
7
1 namespace Uploader 
2 { 
3  using System; 
4  using System.IO; 
5  using System.ServiceModel; 
6  using System.ServiceModel.Description; 
7  using System.ServiceModel.Web; 
8  using System.Drawing; 
9  using System.Drawing.Imaging; 
10  using System.Net; 
11  using System.Xml; 
12 
13  [ServiceContract(Namespace = "http://Uploader")] 
14  public interface IUploaderService 
15  { 
16   [OperationContract, WebInvoke(Method = "POST",UriTemplate = "File/{fileName}")] 
17   bool UploadFile(string fileName, Stream fileContents); 
18  } 
19 
20  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 
21  public class UploaderService : IUploaderService 
22  { 
23   public bool UploadFile(string fileName, Stream fileContents) 
24   { 
25    return true; 
26   } 
27  } 
28 
29  class Program 
30  { 
31   static void Main() 
32   { 
33    var host = new 
34     ServiceHost(typeof (UploaderService), 
35     new Uri("http://localhost:8080/Uploader")); 
36    host.AddServiceEndpoint("Uploader.IUploaderService", 
37     new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior()); 
38    try 
39    { 
40     host.Open(); 
41     Console.WriteLine(host.BaseAddresses[0].AbsoluteUri + " running."); 
42     Console.WriteLine(); 
43     var uri = "http://localhost:8080/Uploader/file.jpg"; 
44     var req = WebRequest.Create(uri) as HttpWebRequest; 
45     if (req != null) 
46     { 
47      req.Method = "POST"; 
48      req.ContentType = "image/jpeg"; 
49      var reqStream = req.GetRequestStream(); 
50     
51      var imageStream = new MemoryStream(); 
52      using (var i = Image.FromFile(@"c:\photo.jpg")) 
53       i.Save(imageStream, ImageFormat.Jpeg); 
54      
55      var imageArray = imageStream.ToArray(); 
56      reqStream.Write(imageArray, 0, imageArray.Length); 
57      reqStream.Close(); 
58      var resp = (HttpWebResponse)req.GetResponse(); 
59      var r = new XmlTextReader(resp.GetResponseStream()); 
60      if (r.Read()) 
61      { 
62       Console.WriteLine(r.ReadString());  
63      } 
64     } 
65     Console.WriteLine("Press <ENTER> to quit."); 
66     Console.ReadLine(); 
67    } 
68    catch (Exception ex) 
69    { 
70     Console.WriteLine(ex.Message); 
71     Console.ReadKey(); 
72    } 
73    finally 
74    { 
75     if (host.State == CommunicationState.Faulted) 
76      host.Abort(); 
77     else 
78      host.Close(); 
79    } 
80   } 
81  } 
82 } 
83 
84 

Hola, esperamos que usted puede ayudar ....WCF REST problema de imagen servicio de carga

Estoy creando una aplicación sencilla (quizás página web) que tendrá una interfaz de usuario sencilla y se subir archivos desde un dispositivo externo , la aplicación/página web se iniciará a través de autorun.inf cuando el usuario conecte un dispositivo a su PC. El servicio web realizará el trabajo complejo de vincular el archivo al sistema de gestión, etc. Esto permitirá a los usuarios analfabetos de TI que no pueden usar el archivo explorar enviar archivos al sistema de gestión ...!

El problema que tengo es que mi serivce REST es que me da un error 400 cuando el tipo de contenido es un image/jpeg .. Funciona bien para text/plain o text/xml (ver blog)

Gracias J

Respuesta

7

Puede intentar anular cualquier tipo de contenido y cargar todos los archivos como application/octet-stream, o text/plain usando un IOperationBehavior.

public class WebContentTypeAttribute : Attribute, IOperationBehavior, IDispatchMessageFormatter 
{ 
    private IDispatchMessageFormatter innerFormatter; 
    public string ContentTypeOverride { get; set; } 

    public WebContentTypeAttribute(string contentTypeOverride) 
    { 
     this.ContentTypeOverride = contentTypeOverride; 
    } 


    // IOperationBehavior 
    public void Validate(OperationDescription operationDescription) 
    { 

    } 

    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) 
    { 
     innerFormatter = dispatchOperation.Formatter; 
     dispatchOperation.Formatter = this; 
    } 

    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) 
    { 

    } 

    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) 
    { 

    } 

    // IDispatchMessageFormatter 
    public void DeserializeRequest(Message message, object[] parameters) 
    { 
     if (message == null) 
      return; 

     if (string.IsNullOrEmpty(ContentTypeOverride)) 
      return; 

     var httpRequest = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name]; 
     httpRequest.Headers["Content-Type"] = ContentTypeOverride; 
    } 

    public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result) 
    { 
     return innerFormatter.SerializeReply(messageVersion, parameters, result); 
    } 
} 

Y usted tendría que modificar su Contrato de servicios para parecerse a éste

[OperationContract] 
[WebInvoke(Method = "POST",UriTemplate = "File/{fileName}")] 
[WebContentType("application/octet-stream")] 
bool UploadFile(string fileName, Stream fileContents); 

Aunque, si carga de una página web, ¿no los datos se publicarán en un multipart/form -¿formato de datos?

+0

¡Justo lo que estaba buscando! No estoy seguro acerca de la carga de la página web, sin embargo, puedo usar JavaScript para engancharme en el servicio, así que también necesitaré hacer una versión habilitada para JSON. Cruza ese puente cuando/si lo alcanzo. La aplicación es un pequeño prototipo en el mo. – jaimie

+2

Me gusta mucho este WCF RESTful, parece mucho más limpio y más delgado que los estándares estándar SOAP WS- * para la interoperabilidad. Hay una gran nota técnica en msdn: http://msdn.microsoft.com/en-us/library/dd203052.aspx para cualquier persona que quiera saber más. Gracias por su ayuda Ben ... J – jaimie

Cuestiones relacionadas