vendredi 1 septembre 2017

C# Web Api 2 - Ember App File download

Im building an app using WebAPI 2, and an ember front end. I've set up an endpoint that returns a file -

DocumentsController -

    public IHttpActionResult GetFile(int id, string project_code)
    {
        DocumentsMapper dm = new DocumentsMapper();
        //GetFileForDownload calculates the file path and returns 
        //new FileInfo(FilePath);
        FileInfo fi = dm.GetFileForDownload(id, project_code);


        return new FileResult(fi.FullName,fi.Name);
    }

The return method of the controller is here

public class FileResult : IHttpActionResult
{
    private readonly string _filePath;
    private readonly string _contentType;
    private readonly string _fileName;

    public FileResult(string filePath,string fileName, string contentType = null)
    {
        if (filePath == null) throw new ArgumentNullException("filePath");

        _filePath = filePath;
        _contentType = contentType;
        _fileName = fileName;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        FileStream stream = new FileStream(_filePath, FileMode.Open, FileAccess.Read);

        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content =  new StreamContent(stream)
        };
        string contentType = _contentType ?? MimeMapping.GetMimeMapping(Path.GetExtension(_filePath));
        response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
        response.Content.Headers.ContentDisposition =new ContentDispositionHeaderValue("attachment") { FileName = _fileName };
        return Task.FromResult(response);
    }
}

That's pretty much all the server side stuff.

On the ember side i have a list of documents, each with a download button This is the template for each document in that list, they are just rendered in a table

<tr>
 <td>
  <div></div>
</td>

<td>
  <strong></strong><br>
</td>
<td>
   <a href="http://localhost:15476/api/v1/Documents?project_code=3patest&id=65698" download="filename.txt"  > 
    <span class="fa fa-download pointer" >  
    </span>
  </a>   
</td>
  <td>
    <span class="fa fa-download pointer" >       
    </span>
</td>

and the corresponding component -

import Ember from 'ember';
import SessionControllerMixin from 'nec3-ui/mixins/controllers/session';
const { service } = Ember.inject;


export default Ember.Component.extend(SessionControllerMixin, {
session: service('session'),
tagName: '',

actions:{
    download:function(id){

        var projectCode = this.get('session').get('data.projectCode')
        Ember.$.ajax({
            beforeSend:function(request){
                request.setRequestHeader("Authorization","Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c3IiOiIxNjkiLCJ1c3JuYW1lIjoia2Vua28gICAgICIsInVzcnR5cGUiOjAsInByZiI6bnVsbH0.K2wNmNFmbupj38tNSNa_Zreo81Lda5C4laJLQ5cFr08");
                request.setRequestHeader("Access-Control-Allow-Credentials","true");
            },
            type:"GET",
            url:"http://localhost:15476/api/v1/Documents?project_code=3patest&id=65698",
            success:function(data){
              console.log(data)

            }
        });

        //this.get('store').queryRecord('document',{id:id,project_code:projectCode});

    }
}
});

Here's the document serializer

import DS from "ember-data";
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin';
import ENV from "../config/environment";
import FormDataAdapterMixin from 'ember-cli-form-data/mixins/form-data-
adapter';

export default DS.RESTAdapter.extend(DataAdapterMixin,FormDataAdapterMixin, 
{
  host: ENV.APP.nec3ReportsHost,
  authorizer: 'authorizer:sypro-legacy'

});

I can hit the endpoint and get the content of the file in the response, but nothing after that. I gave up using the

this.get('store').queryRecord('document',{id:id,project_code:projectCode});

method of calling the endpoint because Ember-data kept trying to parse the response content.

Ideally I'd want to pop up a save dialog. It was my understanding that setting the content disposition on the response would do that, but it doesn't seem to work. but that doesn't seem to work. Any pointers are welcome. If there's information I've left out please let me know!

Thanks




Aucun commentaire:

Enregistrer un commentaire