هل تستطيع وحدة تحكم ASP.NET MVC عرض صورة؟


Answers

باستخدام نسخة إصدار MVC ، إليك ما أقوم به:

[AcceptVerbs(HttpVerbs.Get)]
[OutputCache(CacheProfile = "CustomerImages")]
public FileResult Show(int customerId, string imageName)
{
    var path = string.Concat(ConfigData.ImagesDirectory, customerId, "\\", imageName);
    return new FileStreamResult(new FileStream(path, FileMode.Open), "image/jpeg");
}

من الواضح أن لدي بعض الأشياء الخاصة بالتطبيق هنا فيما يتعلق ببناء المسار ، ولكن إرجاع FileStreamResult هو أمر لطيف وبسيط.

أجريت بعض اختبارات الأداء فيما يتعلق بهذا الإجراء ضد مكالمتك اليومية للصورة (تجاوز جهاز التحكم) وكان الفرق بين المتوسطات حوالي 3 مللي ثانية فقط (كان متوسط ​​وحدة التحكم 68 مللي ثانية ، وكان جهاز التحكم غير 65 مللي ثانية).

لقد جربت بعض الطرق الأخرى المذكورة في الإجابات هنا وكان أداءها أكثر دراماتيكية ... العديد من استجابات الحلول كانت بقدر 6x غير المتحكم (وحدات التحكم الأخرى avg 340ms ، 65-x غير تحكم).

Question

هل يمكنني إنشاء وحدة تحكم تقوم فقط بإرجاع أصل الصورة؟

أود توجيه هذا المنطق من خلال جهاز تحكم ، كلما طلب عنوان URL مثل ما يلي:

www.mywebsite.com/resource/image/topbanner

سوف تبحث وحدة التحكم عن topbanner.png وترسل تلك الصورة مباشرة إلى العميل.

لقد رأيت أمثلة على ذلك حيث يجب عليك إنشاء عرض - لا أريد استخدام طريقة عرض. أريد أن أفعل كل ذلك فقط مع المراقب المالي.

هل هذا ممكن؟




يمكنك استخدام HttpContext.Response وكتابة المحتوى مباشرة (قد يعمل WriteFile () لك ثم) وإرجاع ContentResult من الإجراء الخاص بك بدلاً من ActionResult.

إخلاء المسؤولية: لم أحاول ذلك ، لأنه يعتمد على النظر إلى واجهات برمجة التطبيقات المتاحة. :-)




لماذا لا تذهب بسيطة واستخدام المشغل تيلدا ~ ؟

public FileResult TopBanner() {
  return File("~/Content/images/topbanner.png", "image/png");
}






قد يكون هذا مفيدًا إذا كنت تريد تعديل الصورة قبل إعادتها:

public ActionResult GetModifiedImage()
{
    Image image = Image.FromFile(Path.Combine(Server.MapPath("/Content/images"), "image.png"));

    using (Graphics g = Graphics.FromImage(image))
    {
        // do something with the Graphics (eg. write "Hello World!")
        string text = "Hello World!";

        // Create font and brush.
        Font drawFont = new Font("Arial", 10);
        SolidBrush drawBrush = new SolidBrush(Color.Black);

        // Create point for upper-left corner of drawing.
        PointF stringPoint = new PointF(0, 0);

        g.DrawString(text, drawFont, drawBrush, stringPoint);
    }

    MemoryStream ms = new MemoryStream();

    image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);

    return File(ms.ToArray(), "image/png");
}



هذا العمل بالنسبة لي. منذ أنا تخزين الصور على قاعدة بيانات SQL Server.

    [HttpGet("/image/{uuid}")]
    public IActionResult GetImageFile(string uuid) {
        ActionResult actionResult = new NotFoundResult();
        var fileImage = _db.ImageFiles.Find(uuid);
        if (fileImage != null) {
            actionResult = new FileContentResult(fileImage.Data,
                fileImage.ContentType);
        }
        return actionResult;
    }

في المقتطف أعلاه _db.ImageFiles.Find(uuid) تبحث عن سجل ملف الصورة في db (سياق EF). تقوم بإرجاع كائن FileImage الذي يعد فقط فئة مخصصة قمت بعملها للنموذج ثم يستخدمه كـ FileContentResult.

public class FileImage {
   public string Uuid { get; set; }
   public byte[] Data { get; set; }
   public string ContentType { get; set; }
}



if (!System.IO.File.Exists(filePath))
    return SomeHelper.EmptyImageResult(); // preventing JSON GET/POST exception
else
    return new FilePathResult(filePath, contentType);

يجب أن ترجع SomeHelper.EmptyImageResult() FileResult مع الصورة الموجودة (1 × 1 شفاف ، على سبيل المثال).

هذه أسهل طريقة إذا كان لديك ملفات مخزنة على محرك أقراص محلي. إذا كانت الملفات byte[] أو stream - ثم استخدم FileContentResult أو FileStreamResult كما اقترح ديلان.




انظر إلى ContentResult. هذا إرجاع سلسلة ولكن يمكن استخدامها لإنشاء فئة تشبه BinaryResult الخاصة بك.




Related