Download file from WCF service using WebGet

14 ביולי 2013

תגיות: , , , ,
אין תגובות

נשאלתי כיצד ניתן להוריד קובץ pdf משירות WCF התומך ב – WebGet.

(להורדת קוד המקור)

קוד צד השרת הוא פשוט, בסך הכול להחזיר stream (בדוגמא הבאה השתמשתי ב – PdfSharp)

Code Snippet
public class FileService : IFileService
{
    public Stream GetFile()
    {
        MemoryStream myMemoryStream = new MemoryStream();

        PdfDocument document = new PdfDocument();
        PdfPage page = document.AddPage();
        XGraphics gfx = XGraphics.FromPdfPage(page);
        XFont font = new XFont("Verdana", 20, XFontStyle.Bold);
        gfx.DrawString("Hello, World!", font, XBrushes.Black, new XRect(0, 0, page.Width, page.Height), XStringFormats.Center);
            
        document.Save(myMemoryStream, false);

        myMemoryStream.Seek(0, SeekOrigin.Begin);

        WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Disposition", "attachment; filename=Report0.pdf");
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/pdf";

        return myMemoryStream;
    }
}

חשוב לשים לב לשורה בסוף שאנחנו מוסיפים את ה – header בשם Content-Disposition – זה מגדיר האם הקובץ יפתח בדפדפן או תמיד יהיה קובץ להורדה, ולשורה בה מגדירים את ה – Content-Type.

כמובן להלן קוד ה – Interface

Code Snippet
[ServiceContract]
public interface IFileService
{
    [OperationContract]
    [WebGet]
    Stream GetFile();
}

ואחרון חביב בצד השרת הגדרות הקונפיג כדי לתמוך ב – WebGet (כל ההסברים על הנושא – כאן)

Code Snippet
<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="true" />
      </behavior>
    </serviceBehaviors>
    <endpointBehaviors>
      <behavior>
        <webHttp faultExceptionEnabled="true" />
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <services>
    <service name="WebApplication2.FileService">
      <endpoint address=""
                binding="webHttpBinding"
                contract="WebApplication2.IFileService"></endpoint>
    </service>
  </services>
  <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

למעשה צד הלקוח הוא ממש פשוט, ניתן ב – html לכתוב את הלינק הבא:

Code Snippet
<a href="FileService.svc/GetFile" target="_blank">Direct Download</a>

במידה וצריך לשלוח פרמטרים – פתרון חביב וקל הוא להשתמש ב – jquery.fileDownload.

לדוגמא אם המתודה בשרת נראית כך:

Code Snippet
public Stream GetFile2(int id, string name)
{
    return GetFile();
}

נוכל לכתוב בצד הלקוח את הסקריפט הבא:

Code Snippet
function download() {
    $.fileDownload('FileService.svc/GetFile2', {
        data: {
            id: 12,
            name: 'shlomo'
        }
    });
}

הסיבה לשימוש ב – fileDownload, היא מכיוון שאי אפשר באמת ב – ajax להוריד קובץ (אלא אם כן נשתמש ב – html5, אבל זה סיפור אחר ולא באמת ניתן לשמור את הקובץ אצל המשתמש).

וכדי להוריד קובץ צריך פעולת submit או לשנות את כתובת העמוד – מה שהסקריפט הנ”ל עושה, זה לייצר iframe דינמי ולהוריד אליו את הקובץ.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *