PDF using WCF Restful Services

2019-07-11 20:54发布

Task: To be able to render a PDF when user clicks a link (which is a WCF Service {example: http://localhost:6186/MyReportServices.svc/reports/012}). The Service goes and fetches the report from SSRS Server and returns the Stream. Here is the piece of code that is in .

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
public class AssistReportServices : IAssistReportServices
{
    public Stream GetReport(int value)
    {
      //skipped some lines of code. 
      try
        {
          result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
          execInfo = rs.GetExecutionInfo();             
        }
      catch (SoapException err)
        {
            throw;
        }
      MemoryStream ms = new MemoryStream();
      ms.Write(result, 0, result.Length);
      ms.Position = 0;
      //WebOperationContext.Current.OutgoingResponse.ContentType = ConfigurationManager.AppSettings["ResponseType"];
      WebOperationContext.Current.OutgoingResponse.ContentType = "application/pdf";
      return ms; 
    }
 }

My Operation Contract looks like:

[OperationContract(Action = "*")]
[WebInvoke(Method = "POST",
    UriTemplate = "reports/{value}")]
Stream GetReport(int value);

So far so good. But here is the problem... When i click the link above, i get the following error in a dialog box with title Adobe Reader and message:

File does not begin with '%PDF-'.

Error Image: http://i.imgur.com/A4J68.png

I can save the Memory Stream to a file and manually open the pdf, and it opens just fine without issues.

Thanks.

标签: c# wcf pdf rest
2条回答
女痞
2楼-- · 2019-07-11 21:13

I found where I was going wrong. I had used the Web.Config file to configure my WCF Service. When i switched to a code based configuration using the following code, the service worked and pointed out my errors as well.

static void Main(string[] args)
{

    ServiceHost serviceHost = new ServiceHost(typeof(MyReportingServices.MyReportServices), ServiceEndpointUri);
    WebHttpBinding binding = new WebHttpBinding();
    ServiceEndpoint sep = serviceHost.AddServiceEndpoint(typeof(MyReportingServices.IMyReportServices), binding, string.Empty);
    sep.Behaviors.Add(new WebHttpBehavior());
    serviceHost.Open();
    Console.WriteLine("Service is running @ " + ServiceEndpointUri);
    Console.WriteLine();
    Console.WriteLine("Press enter to shutdown service.");
    Console.ReadLine();
    serviceHost.Close();
}

The error was:

Operation 'GetReport' in contract 'IMyReportServices' has a path variable named 'value' which does not have type 'string'. Variables for UriTemplate path segments must have type 'string'.

Which I resolved by changing the datatype for my operation parameters to String.

Thanks to Mrchief, as i used his input to add the following line of code, to help me display a Save/Cancel dialog:-

WebOperationContext.Current.OutgoingResponse.ContentType = "application/pdf";
WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-disposition", "inline; filename=apurvReport.pdf"); 
查看更多
乱世女痞
3楼-- · 2019-07-11 21:28

How are you sending it to the browser? It looks like its being sent with a wrong mime type. It should go in as Response.ContentType = "application/pdf";

查看更多
登录 后发表回答