1

I have an angularjs form that I would like users to be able to download a filled out PDF of what they requested. I have an [HTTPGet] method that accepts a base64 encoding of the json request. Everything works except when my base64 encoding goes above 2027 characters in length. When that happens, I don't receive anything more than the 2027 characters. Is there another way to send the data on a get call or a better way to do this.

My angular js app does this.

scope.DownloadTempResults = function () {
                window.open('/Home/GetCopyOfRequest?strRequest=' + window.btoa(JSON.stringify(scope.request)), '_blank', '');
            }

My C# code behind does this.

[HttpGet]
public ActionResult GetCopyOfRequest(string strRequest)
{
     byte[] data = Convert.FromBase64String(strRequest);
     string request = Encoding.UTF8.GetString(data);
     ExternalModel model = JsonHelper.Deserialize<ExternalModel>(request);

     byte[] filedata = ObjectFactory.GetInstance<ManagerFactory>().Create().CreateRequestForm(model);
     string contentType = "application/pdf";
     var cd = new System.Net.Mime.ContentDisposition
     {
          FileName = "name of File",
          Inline = true
     };
     Response.AppendHeader("Content-Disposition", cd.ToString());
     return File(filedata, contentType);
}

At the end of the day, what we are trying to do is encode the json in the query string so that you can not look directly at the query string and get the values of the json object. If I am going about this completely wrong, please let me know what to look up to accomplish this.

Updated below here. So based on the comments, I changed to a post method that looks like this.

[HttpPost]
public HttpResponseMessage GetCopyOfRequest(string strRequest)
{
     ExternalModel model = JsonHelper.Deserialize<ExternalModel>(strRequest);
     byte[] filedata = ObjectFactory.GetInstance<IManagerFactory>().Create().CreateRequestForm(model);
     string fileName = "Request form for request";

     HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
     httpResponseMessage.Content = new ByteArrayContent(filedata);
     httpResponseMessage.Content.Headers.Add("x-filename", fileName);
     httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
     httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
     httpResponseMessage.Content.Headers.ContentDisposition.FileName = fileName;
     httpResponseMessage.StatusCode = HttpStatusCode.OK;
     return httpResponseMessage;
}

In the angularjs app, I have the following code.

$http({
            url: '/Home/GetCopyOfRequest',
            method: 'POST',
            data: { strRequest: JSON.stringify(request) },
            responseType: 'arraybuffer'
        }).success(function (data, status, headers) {
            var file = new Blob([data], { type: 'application/pdf' });
            var fileURL = URL.createObjectURL(file);
            window.open(fileURL);
        }).error(function (response) {

        });

When I do this on the server, my byte array has a length of 400000. On the client side, I have an array of 270. I followed an example from How to display a server side generated PDF stream in javascript sent via HttpMessageResponse Content .

  • `If I am going about this completely wrong, please let me know what to look up to accomplish this.` <= Use `httpS` instead of unencrypted http. The url will also be secured in the end-to-end transmission between server/client. There is no need to add security through obscurity, this adds nothing of value for the application and *can* cause bugs (like this one). – Igor Sep 21 '18 at 15:28
  • 1
    You need to use POST instead. You're hitting the browser's URL max length of 2,083 characters. – Dan Wilson Sep 21 '18 at 15:28
  • Welcome to SO. If you take a step back and read your own question, it should become pretty obvious that you should not be using `get`. You are allowing users to provide you with some data which you then **POST** to the server in order to download a file. – JuanR Sep 21 '18 at 15:41
  • By the way, there are other considerations in terms of security with `get` (like the fact that the url gets stored in the browser's cache and the logs). Encoding in Base64 offers little to no protection. Check this out: https://www.diffen.com/difference/GET-vs-POST-HTTP-Requests – JuanR Sep 21 '18 at 15:45
  • Thanks for the comments, I updated the method to a POST method, but they byte array isn't matching. – Nathan Newman Sep 21 '18 at 15:57
  • `...encode the json in the query string so that you can not look directly at the query string and get the values of the json object` <= Why not see the values in the query string? Who should not be seeing this? – Igor Sep 21 '18 at 16:38

0 Answers0