কীভাবে ওয়েব এপিআই ব্যবহার করে কোনও ফাইল ফেরত পাবেন?


101

আমি এএসপি.নেট ওয়েব এপিআই ব্যবহার করছি ।
আমি এপিআই থেকে সি # দিয়ে একটি পিডিএফ ডাউনলোড করতে চাই (যা এপিআই তৈরি করে)।

আমি কি কেবল এপিআই রিটার্ন দিতে পারি byte[]? এবং সি # অ্যাপ্লিকেশনটির জন্য আমি কেবল এটি করতে পারি:

byte[] pdf = client.DownloadData("urlToAPI");? 

এবং

File.WriteAllBytes()?

"ওয়েব এপিআই"? আপনি ঠিক কি বোঝাতে চেয়েছেন? দয়া করে tinyurl.com/so- ইঙ্গিতগুলি পড়ুন এবং আপনার প্রশ্নটি সম্পাদনা করুন।
জন স্কিটি

4
@ জোনস্কিট: ওয়েব এপিআই এএসপি.নেটের সর্বশেষ সংস্করণে একটি নতুন বৈশিষ্ট্য। দেখুন asp.net/ whitepapers
রবার্ট হার্ভে

4
@ রবার্ট: ধন্যবাদ - ট্যাগটি এটিকে আরও স্পষ্ট করে তোলে, যদিও "এএসপি.নেট ওয়েব এপিআই" উল্লেখ করা আরও পরিষ্কার হত। জঞ্জাল জেনেরিক নামটির জন্যও আংশিকভাবে এমএসের দোষ :)
জন স্কিটি


যে কেউ যদি ওয়েব এপিআই এবং আইএইচটিটিপিএ্যাকশনস রেজাল্টের মাধ্যমে স্রোতটি ফিরে আসতে চায়, তবে এখানে দেখুন: নোডোগমব্লগ.ব্রায়ানহোগান.ট.২০১7
ইবরার মমতাজ

উত্তর:


172

এর ভিতরে স্ট্রিমকন্টেন্টের সাথে এইচটিপিআরস্পোনমেসেজটি ফেরানো ভাল।

এখানে উদাহরণ:

public HttpResponseMessage GetFile(string id)
{
    if (String.IsNullOrEmpty(id))
        return Request.CreateResponse(HttpStatusCode.BadRequest);

    string fileName;
    string localFilePath;
    int fileSize;

    localFilePath = getFileFromID(id, out fileName, out fileSize);

    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
    response.Content = new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read));
    response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
    response.Content.Headers.ContentDisposition.FileName = fileName;
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

    return response;
}

পৃষ্ঠপোষকের মন্তব্য থেকে ইউপিডি : অন্য যে কেউ এখানে আসল ফাইলের পরিবর্তে বাইট অ্যারে থেকে প্রতিক্রিয়া প্রেরণ করতে চাইলে আপনি স্ট্রিমকন্টেন্টের পরিবর্তে নতুন বাইটআরাই কনটেন্ট (কিছু ডেটা) ব্যবহার করতে চান ( এখানে দেখুন )।


4
প্রথম জিনিস - আপনি একই ফাইলটিতে নির্দেশিত দুটি ফাইল স্ট্রিম অবজেক্টকে নতুন করে আনতে এই কোডটি একটি ব্যতিক্রম ঘটায়। দ্বিতীয় বিষয়টি হ'ল আপনি কোনও "ব্যবহার" বিবৃতিটি ব্যবহার করতে চান না কারণ ভেরিয়েবলটি সুযোগের বাইরে চলে যাওয়ার সাথে সাথেই। নেট এটি নিষ্পত্তি করবে এবং অন্তর্নিহিত সংযোগটি বন্ধ হওয়ার বিষয়ে ত্রুটির বার্তা পাবেন।
ব্র্যান্ডন মন্টগোমেরি

48
অন্য যে কোনও আসল ফাইলের পরিবর্তে বাইট অ্যারে থেকে প্রতিক্রিয়া পাঠানোর জন্য এখানে আসার পরে আপনি তার new ByteArrayContent(someData)পরিবর্তে StreamContent( এখানে দেখুন ) ব্যবহার করতে চাইছেন ।
পৃষ্ঠপোষক

আপনি বেস ডিসপোজ () কে ওভাররাইড করতেও চাইতে পারেন যাতে ফ্রেমওয়ার্ক যখন ডাকে তখন আপনি আপনার সংস্থানগুলি সঠিকভাবে পরিচালনা করতে পারেন।
ফিল কুপার

4
আমি উল্লেখ করতে চাই যে সঠিক মিডিয়াটাইপহাইডারভ্যালু অত্যন্ত গুরুত্বপূর্ণ এবং এটির গতিশীল হওয়ার জন্য যদি আপনার কাছে বিভিন্ন ফাইলের ধরণ থাকে তবে আপনি এটি করতে পারেন। (যেখানে ফাইলনাম একটি স্ট্রিং এবং একটি ফাইল টাইপ সমাপ্ত হয় যেমন .jpg, .pdf, ডকএক্স ইত্যাদি।) var কন্টেন্টটাইপ = মাইম্যাপিং.গেটমাইম্যাপিং (ফাইলের নাম); প্রতিক্রিয়া.কন্টেন্ট.হিডার্স.সন্টেন্টটাইপ = নতুন মিডিয়াটাইপহাইডারভ্যালু (কনটেন্টটাইপ);
জিমি সুইডেন

4
ফাইল স্ট্রিমটি কি স্বয়ংক্রিয়ভাবে নিষ্পত্তি হবে?
ব্রায়ান ট্যাকার

37

আমি অনুসরণের ক্রিয়াটি করেছি:

[HttpGet]
[Route("api/DownloadPdfFile/{id}")]
public HttpResponseMessage DownloadPdfFile(long id)
{
    HttpResponseMessage result = null;
    try
    {
        SQL.File file = db.Files.Where(b => b.ID == id).SingleOrDefault();

        if (file == null)
        {
            result = Request.CreateResponse(HttpStatusCode.Gone);
        }
        else
        {
            // sendo file to client
            byte[] bytes = Convert.FromBase64String(file.pdfBase64);


            result = Request.CreateResponse(HttpStatusCode.OK);
            result.Content = new ByteArrayContent(bytes);
            result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            result.Content.Headers.ContentDisposition.FileName = file.name + ".pdf";
        }

        return result;
    }
    catch (Exception ex)
    {
        return Request.CreateResponse(HttpStatusCode.Gone);
    }
}

এটি আসলে প্রশ্নের উত্তর দেয়
মিক

4
বড় ফাইলগুলির সাথে এটি ভাল ধারণা হবে না কারণ এটি পুরো চিত্রটিকে মেমরিতে লোড করে। স্ট্রিম বিকল্পটি আরও ভাল।
পল রেডি

@ পলরিডি পারফেক্ট ... তবে অনেক ক্ষেত্রে আপনার বড় ফাইল নিয়ে কাজ করার দরকার নেই। তবে আমি আপনার বক্তব্যের সাথে একমত!
আন্দ্রে দে মাতোস

16

সঙ্গে উদাহরণ IHttpActionResultমধ্যে ApiController

[HttpGet]
[Route("file/{id}/")]
public IHttpActionResult GetFileForCustomer(int id)
{
    if (id == 0)
      return BadRequest();

    var file = GetFile(id);

    IHttpActionResult response;
    HttpResponseMessage responseMsg = new HttpResponseMessage(HttpStatusCode.OK);
    responseMsg.Content = new ByteArrayContent(file.SomeData);
    responseMsg.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
    responseMsg.Content.Headers.ContentDisposition.FileName = file.FileName;
    responseMsg.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
    response = ResponseMessage(responseMsg);
    return response;
}

আপনি যদি পিডিএফ ডাউনলোড করতে না চান এবং পিডিএফ ভিউয়ারে নির্মিত ব্রাউজারগুলি ব্যবহার না করে নিম্নলিখিত দুটি লাইন সরিয়ে ফেলুন:

responseMsg.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
responseMsg.Content.Headers.ContentDisposition.FileName = file.FileName;

@ এলবার্ট জন ফিলিপ হ্যাঁ, আপনি ফাইলটি সাথে পাবেন var file = GetFile(id);file.SomeDataএকটি বাইট অ্যারে ( byte[]) এবং file.FileNameহয় string
ওগ্লাস

আপনার পোস্টের জন্য আপনাকে ধন্যবাদ। 'এইচটিপিআরএসপোনসমেজেজ' কোনও অ্যাপি-কন্ট্রোলারের ভিতরে আমার পক্ষে কাজ করেনি, তাই আপনি আমাকে বাঁচিয়েছেন।
সর্বোচ্চ

15

এর জন্য কেবল একটি নোট .Net Core: আমরা কাঁচা বাইটগুলি প্রেরণ FileContentResultকরতে application/octet-streamচাইলে আমরা বিষয়বস্তু টাইপটি সেট করতে এবং সেট করতে পারি । উদাহরণ:

[HttpGet("{id}")]
public IActionResult GetDocumentBytes(int id)
{
    byte[] byteArray = GetDocumentByteArray(id);
    return new FileContentResult(byteArray, "application/octet-stream");
}

4
এটি দুর্দান্ত কাজ করে, এছাড়াও আপনি যদি ফাইলের নামটি নিয়ন্ত্রণ করতে চান তবে ফাইল নাম নির্দিষ্ট করার জন্য FileContentResultডাকা কোনও সম্পত্তি আছেFileDownloadName
সপ্তাহের দেবদেহ

@ উইকসদেব আহ এটি জানত না। মন্তব্যের জন্য ধন্যবাদ.
আমির শিরাজী

ধন্যবাদ, ধন্যবাদ। এছাড়াও সপ্তাহদেব থেকে মন্তব্য খুব দরকারী।
টগবগ করুন

1

আমি ভাবছিলাম যে আরও একটি ফাইল "সাধারণ" উপায়ে ডাউনলোড করার কোনও সহজ উপায় ছিল কিনা? আমি এই নিয়ে এসেছি।

এটি এমন একটি সহজ ActionResultযা আপনাকে একটি নিয়ন্ত্রণকারী কল থেকে একটি ফাইল ডাউনলোড করার অনুমতি দেয় যা একটি ফেরত দেয় IHttpActionResult। ফাইলটি সংরক্ষণ করা হয় byte[] Content। প্রয়োজনে আপনি এটিকে স্রোতে পরিণত করতে পারেন।

আমি এটি একটি ডাটাবেসের ভের্বাইনারি কলামে সঞ্চিত ফাইলগুলি ফিরতে ব্যবহার করেছি।

    public class FileHttpActionResult : IHttpActionResult
    {
        public HttpRequestMessage Request { get; set; }

        public string FileName { get; set; }
        public string MediaType { get; set; }
        public HttpStatusCode StatusCode { get; set; }

        public byte[] Content { get; set; }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            HttpResponseMessage response = new HttpResponseMessage(StatusCode);

            response.StatusCode = StatusCode;
            response.Content = new StreamContent(new MemoryStream(Content));
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
            response.Content.Headers.ContentDisposition.FileName = FileName;
            response.Content.Headers.ContentType = new MediaTypeHeaderValue(MediaType);

            return Task.FromResult(response);
        }
    }

আপনার কোড কীভাবে ওপি'র সমস্যা (গুলি) সমাধান করে তার সংক্ষিপ্ত বিবরণ আপনার উত্তরের গুণমানকে বাড়িয়ে তুলবে।
অ্যাড্রিয়ান মোল

0

ফাইল ডাউনলোড করার আরেকটি উপায় হ'ল সরাসরি প্রতিক্রিয়াটির শরীরে স্ট্রিমের সামগ্রী লিখিত:

[HttpGet("pdfstream/{id}")]
public async Task  GetFile(long id)
{        
    var stream = GetStream(id);
    Response.StatusCode = (int)HttpStatusCode.OK;
    Response.Headers.Add( HeaderNames.ContentDisposition, $"attachment; filename=\"{Guid.NewGuid()}.pdf\"" );
    Response.Headers.Add( HeaderNames.ContentType, "application/pdf"  );            
    await stream.CopyToAsync(Response.Body);
    await Response.Body.FlushAsync();           
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.