Jonathan Hansen
Jonathan Hansen

Reputation: 443

C# Web API Response Type for a pdf

I know this is simple, but I am losing my mind. I am generating a pdf stream (or whatever you want to call it) and want it to go to the web browser. I expect I need to return a byte array to the browser (if I am incorrect, please let me know). But I have yet to figure out what to set the Response Type to. Please help.

[HttpGet]
[ActionName("GetPrint")]
[ResponseType(typeof(HttpResponseMessage))] //DOESN'T WORK
public IHttpActionResult GetPrint(string templateName, int personId, int badgeId, string authToken, string ipAddress)
{
    var bdgBl = PeliquinIOC.Instance.Resolve<IBadgeDesignBL>(UserId, UserName, PropertyCode, PartitionName, IpAddress);
    //var apiRsp = new PeliquinApiRsp();

    if (!(IsAllowed(SysPrivConstants.SYSPRIV__TYPE_PERSONNEL, templateName, SysPrivConstants.SYSPRIV__LEVEL_READ)))
    {
        return (Unauthorized());
    }

    var bdgDto = bdgBl.GetPrint(templateName, personId, badgeId);

    if (bdgDto == null)
    {
        return (Unauthorized());
    }

    var myRspMsg = new HttpResponseMessage(HttpStatusCode.OK);
    myRspMsg.Content = new StreamContent(new MemoryStream(bdgDto));
    myRspMsg.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

    return myRspMsg;
}

Just in case you ask how I am generating the pdf (the image creation absolutely works, as we use it elsewhere):

public byte[] GetPrint(string templateName, int personId, int badgeId)
{
    var bdgDesignDto = new BadgeDesignDTO();
    bdgDesignDto.BdgLayoutFront = Get_BadgeLayout_Front(templateName, personId, badgeId);
    bdgDesignDto.BdgLayoutBack = Get_BadgeLayout_Back(bdgDesignDto.BdgLayoutFront, personId, badgeId);

    //Generate the images for Front and Back
    bdgDesignDto.BdgFrontImage = CreateImage(bdgDesignDto.BdgLayoutFront);
    bdgDesignDto.BdgBackImage = CreateImage(bdgDesignDto.BdgLayoutBack);

    var document = new Document(PageSize.A4, 0, 0, 0, 0);
    var msReport = new MemoryStream();
    var writer = PdfWriter.GetInstance(document, msReport); //required to write to msReport stream

    document.Open();
    document.NewPage();
    var jpg = iTextSharp.text.Image.GetInstance(bdgDesignDto.BdgFrontImage);
    jpg.SetAbsolutePosition(1,1);
    document.Add(jpg);

    document.NewPage();
    jpg = iTextSharp.text.Image.GetInstance(bdgDesignDto.BdgBackImage);
    jpg.SetAbsolutePosition(1,1);
    document.Add(jpg);

    return msReport.ToArray();  //Maybe this works?
} 

Upvotes: 1

Views: 5168

Answers (2)

Jonathan Hansen
Jonathan Hansen

Reputation: 443

Here is the working solution:

    [System.Web.Http.HttpGet]
    [System.Web.Http.ActionName("GetPrint")]
    //[ResponseType(typeof(HttpResponseMessage))]
    public HttpResponseMessage GetPrint(string templateName, int personId, int badgeId, string authToken, string ipAddress)
    {
        var bdgBl = PeliquinIOC.Instance.Resolve<IBadgeDesignBL>(UserId, UserName, PropertyCode, PartitionName, IpAddress);

        //if (!(IsAllowed(SysPrivConstants.SYSPRIV__TYPE_PERSONNEL, templateName, SysPrivConstants.SYSPRIV__LEVEL_READ)))
        //{
        //    return (Unauthorized());
        //}

        var bdgDto = bdgBl.GetPrint(templateName, personId, badgeId);

        var result = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new ByteArrayContent(bdgDto)
        };
        result.Content.Headers.ContentDisposition =
            new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
            {
                FileName = $"badge_{badgeId}.pdf"
            };
        result.Content.Headers.ContentType =
            new MediaTypeHeaderValue("application/octet-stream");

        return result;
    }

Upvotes: 1

Marcus H&#246;glund
Marcus H&#246;glund

Reputation: 16811

One option is to use the ControllerBase File() method from the controller which returns a Microsoft.AspNetCore.Mvc.FileContentResult. It will set the byte[] to an appropriate response content.

Implement it like this

[HttpGet]
[ActionName("GetPrint")]
[ResponseType(typeof(HttpResponseMessage))]
public IHttpActionResult GetPrint(string templateName, int personId, int badgeId, string authToken, string ipAddress)
{
    var bdgBl = PeliquinIOC.Instance.Resolve<IBadgeDesignBL>(UserId, UserName, PropertyCode, PartitionName, IpAddress);
    //var apiRsp = new PeliquinApiRsp();

    if (!(IsAllowed(SysPrivConstants.SYSPRIV__TYPE_PERSONNEL, templateName, SysPrivConstants.SYSPRIV__LEVEL_READ)))
    {
        return (Unauthorized());
    }

    var bdgDto = bdgBl.GetPrint(templateName, personId, badgeId);

    if (bdgDto == null)
    {
        return (Unauthorized());
    }

    return File(bdgDto, "application/pdf", "yourPdfName.pdf");
}

Upvotes: 1

Related Questions