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




8 Answers

استخدم أسلوب "التحكم الأساسي" في الملفات.

public ActionResult Image(string id)
{
    var dir = Server.MapPath("/Images");
    var path = Path.Combine(dir, id + ".jpg"); //validate the path for security or use other means to generate the path.
    return base.File(path, "image/jpeg");
}

كملاحظة ، يبدو أن هذا فعال إلى حد ما. لقد أجريت اختبارًا حيث طلبت الصورة من خلال وحدة التحكم ( http://localhost/MyController/Image/MyImage ) وعبر عنوان URL المباشر ( http://localhost/Images/MyImage.jpg ) وكانت النتائج:

  • MVC: 7.6 ميلي ثانية لكل صورة
  • Direct: 6.7 مللي ثانية لكل صورة

ملاحظة: هذا هو متوسط ​​وقت الطلب. تم حساب المتوسط ​​عن طريق جعل الآلاف من الطلبات على الجهاز المحلي ، لذلك لا يجب أن تتضمن الإجماليات وقت استجابة الشبكة أو مشكلة عرض النطاق الترددي.

validation c#

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

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

www.mywebsite.com/resource/image/topbanner

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

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

هل هذا ممكن؟




لفضاء على استجابة Dyland قليلا:

ثلاث فئات تطبيق فئة FileResult :

System.Web.Mvc.FileResult
      System.Web.Mvc.FileContentResult
      System.Web.Mvc.FilePathResult
      System.Web.Mvc.FileStreamResult

انهم جميعا تفسيرية النفس إلى حد ما:

  • بالنسبة لتنزيلات مسار الملفات حيث يوجد الملف على القرص ، استخدم FilePathResult - هذه هي الطريقة الأسهل وتجنب استخدام تيارات.
  • للحصول على صفيف [] بايت [أقرب إلى Response.BinaryWrite) ، استخدم FileContentResult .
  • بالنسبة إلى صفيفات البايت [] حيث تريد تنزيل الملف (content-disposition: attachment) ، استخدم FileStreamResult بالطريقة نفسها أدناه ، ولكن باستخدام MemoryStream واستخدام GetBuffer() .
  • Streams استخدام FileStreamResult . يطلق عليه FileStreamResult لكنه يأخذ Stream لذلك أعتقد أنه يعمل مع MemoryStream .

فيما يلي مثال على استخدام تقنية تصرف المحتوى (لم يتم اختبارها):

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult GetFile()
    {
        // No need to dispose the stream, MVC does it for you
        string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "myimage.png");
        FileStream stream = new FileStream(path, FileMode.Open);
        FileStreamResult result = new FileStreamResult(stream, "image/png");
        result.FileDownloadName = "image.png";
        return result;
    }



يمكنك إنشاء ملحق خاص بك والقيام بهذه الطريقة.

public static class ImageResultHelper
{
    public static string Image<T>(this HtmlHelper helper, Expression<Action<T>> action, int width, int height)
            where T : Controller
    {
        return ImageResultHelper.Image<T>(helper, action, width, height, "");
    }

    public static string Image<T>(this HtmlHelper helper, Expression<Action<T>> action, int width, int height, string alt)
            where T : Controller
    {
        var expression = action.Body as MethodCallExpression;
        string actionMethodName = string.Empty;
        if (expression != null)
        {
            actionMethodName = expression.Method.Name;
        }
        string url = new UrlHelper(helper.ViewContext.RequestContext, helper.RouteCollection).Action(actionMethodName, typeof(T).Name.Remove(typeof(T).Name.IndexOf("Controller"))).ToString();         
        //string url = LinkBuilder.BuildUrlFromExpression<T>(helper.ViewContext.RequestContext, helper.RouteCollection, action);
        return string.Format("<img src=\"{0}\" width=\"{1}\" height=\"{2}\" alt=\"{3}\" />", url, width, height, alt);
    }
}

public class ImageResult : ActionResult
{
    public ImageResult() { }

    public Image Image { get; set; }
    public ImageFormat ImageFormat { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        // verify properties 
        if (Image == null)
        {
            throw new ArgumentNullException("Image");
        }
        if (ImageFormat == null)
        {
            throw new ArgumentNullException("ImageFormat");
        }

        // output 
        context.HttpContext.Response.Clear();
        context.HttpContext.Response.ContentType = GetMimeType(ImageFormat);
        Image.Save(context.HttpContext.Response.OutputStream, ImageFormat);
    }

    private static string GetMimeType(ImageFormat imageFormat)
    {
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
        return codecs.First(codec => codec.FormatID == imageFormat.Guid).MimeType;
    }
}
public ActionResult Index()
    {
  return new ImageResult { Image = image, ImageFormat = ImageFormat.Jpeg };
    }
    <%=Html.Image<CapchaController>(c => c.Index(), 120, 30, "Current time")%>



يمكنك الكتابة مباشرة إلى الرد ولكن بعد ذلك لا يمكن اختباره. يفضل إرجاع ActionResult له تأجيل التنفيذ. هنا هو بلدي StreamResult قابلة لإعادة الاستخدام:

public class StreamResult : ViewResult
{
    public Stream Stream { get; set; }
    public string ContentType { get; set; }
    public string ETag { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.ContentType = ContentType;
        if (ETag != null) context.HttpContext.Response.AddHeader("ETag", ETag);
        const int size = 4096;
        byte[] bytes = new byte[size];
        int numBytes;
        while ((numBytes = Stream.Read(bytes, 0, size)) > 0)
            context.HttpContext.Response.OutputStream.Write(bytes, 0, numBytes);
    }
}



استكمال: هناك خيارات أفضل من جوابي الأصلي. هذا يعمل خارج MVC بشكل جيد ولكن من الأفضل الالتزام بالأساليب المضمنة لإعادة محتوى الصورة. الاطلاع على الإجابات صعودًا.

يمكنك بالتأكيد. جرب هذه الخطوات:

  1. قم بتحميل الصورة من القرص إلى صفيف بايت
  2. تخزين الصورة في الحالة التي تتوقع فيها المزيد من الطلبات للصورة ولا تريد إدخال / إخراج القرص (لا تخزن العينة مؤقتًا أدناه)
  3. قم بتغيير نوع mime عبر Response.ContentType
  4. Response.BinaryWrite خارج مجموعة بايت الصورة

إليك بعض نماذج التعليمة البرمجية:

string pathToFile = @"C:\Documents and Settings\some_path.jpg";
byte[] imageData = File.ReadAllBytes(pathToFile);
Response.ContentType = "image/jpg";
Response.BinaryWrite(imageData);

امل ان يساعد!




الحل 1: لعرض صورة في ملف شخصي من عنوان URL للصورة

يمكنك إنشاء طريقة الإضافة الخاصة بك:

public static MvcHtmlString Image(this HtmlHelper helper,string imageUrl)
{
   string tag = "<img src='{0}'/>";
   tag = string.Format(tag,imageUrl);
   return MvcHtmlString.Create(tag);
}

ثم استخدمها مثل:

@Html.Image(@Model.ImagePath);

الحل 2: لتقديم صورة من قاعدة البيانات

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

public sealed class ImageController : Controller
{
  public ActionResult View(string id)
  {
    var image = _images.LoadImage(id); //Pull image from the database.
    if (image == null) 
      return HttpNotFound();
    return File(image.Data, image.Mime);
  }
}

واستخدمها في طريقة العرض مثل:

@ { Html.RenderAction("View","Image",new {[email protected]})}

لاستخدام صورة تم تقديمها من هذا الإجراء في أي HTML ، استخدم

<img src="http://something.com/image/view?id={imageid}>



أرى خيارين:

1) تنفيذ IViewEngine الخاصة بك وتعيين الخاصية ViewEngine من وحدة تحكم كنت تستخدم ل ImageViewEngine الخاص بك في طريقة "صورة" المطلوب.

2) استخدم طريقة العرض :-). ما عليك سوى تغيير نوع المحتوى وما إلى ذلك.




يمكنك استخدام File لإرجاع ملف مثل View، Content etc

 public ActionResult PrintDocInfo(string Attachment)
            {
                string test = Attachment;
                if (test != string.Empty || test != "" || test != null)
                {
                    string filename = Attachment.Split('\\').Last();
                    string filepath = Attachment;
                    byte[] filedata = System.IO.File.ReadAllBytes(Attachment);
                    string contentType = MimeMapping.GetMimeMapping(Attachment);

                    System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
                    {
                        FileName = filename,
                        Inline = true,
                    };

                    Response.AppendHeader("Content-Disposition", cd.ToString());

                    return File(filedata, contentType);          
                }
                else { return Content("<h3> Patient Clinical Document Not Uploaded</h3>"); }

            }



Related

asp.net asp.net-mvc image controller