سؤال

أحتاج إلى إنشاء HTML (لجسم رسالة بريد إلكتروني) خاصة بـ Customer هدف
فكرت في صنع ملف View هذا يحصل Customer الكائن ويجعل النص المناسب.

هل هناك طريقة لاستدعاء طريقة العرض والحصول على الإخراج المقدم دون ربطه بعمل وحدة تحكم؟

من الناحية المثالية في Pseydocode ، سأفعل شيئًا كهذا

customer = new Customer();
view = new GetCustomerEmailBodyView(customer);
string htmlBody = view.SomeFunctionToRenderViewAndGetOutput()

لقد وجدت حلاً للحصول على HTML من العرض هنا هذا له إجراء لإرجاع stringResult (يرث من ViewResult) بدلاً من ActionResult الذي يكشف Html منشأه.
ومع ذلك ، لا يزال يتعين عليّ اتخاذ إجراء مخصص للاتصال به ، ولا أحب حقيقة أن ذلك يعتمد على controlercontext مما يجعل من الصعب اختباره.

هل ما أطلبه ضد مديري MVC؟ كيف ينبغي تنظيم الكود الخاص بي لهذا السيناريو؟

هل كانت مفيدة؟

المحلول

الكود الأصلي من هنا

protected string RenderPartialViewToString(string viewName, object model) {
    if (string.IsNullOrEmpty(viewName))
        viewName = ControllerContext.RouteData.GetRequiredString("action");
    ViewData.Model = model;
    using (StringWriter sw = new StringWriter()) {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
        ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}

نصائح أخرى

هل تقول إنك تريد أن تكون بعض البرامج قادرة على الاستفادة من وجهة نظر دون أن تكون في سياق وحدة تحكم على الإطلاق ، أم أنك تقول أنك تريد أن تكون قادرًا على تقديم طريقة عرض من داخل وحدة تحكم ، دون استدعاء بعضها الآخر مراقب؟

بالنسبة إلى الأول ، لا يمكنني أن أكون من المساعدة ، ولكن بالنسبة لهذا الأخير ، لدينا هذه الطريقة في نوع وحدة التحكم الأساسية التي نرثها مع جميع وحدات التحكم الأخرى لدينا:

    /// <summary>
    /// Generates a string based on the given PartialViewResult.
    /// </summary>
    /// <param name="partialViewResult"></param>
    /// <returns></returns>
    protected internal string RenderPartialViewToString(ViewResultBase partialViewResult)
    {
        Require.ThatArgument(partialViewResult != null);
        var context = ControllerContext;
        Require.That(context != null);
        using (var sw = new StringWriter())
        {
            if (string.IsNullOrEmpty(partialViewResult.ViewName))
            {
                partialViewResult.ViewName = context.RouteData.GetRequiredString("action");
            }
            ViewEngineResult result;
            if (partialViewResult.View == null)
            {
                result = partialViewResult.ViewEngineCollection.FindPartialView(context, partialViewResult.ViewName);
                Require.That(result.View != null,
                             () => new InvalidOperationException(
                                       "Unable to find view. Searched in: " +
                                       string.Join(",", result.SearchedLocations)));
                partialViewResult.View = result.View;
            }

            var view = partialViewResult.View;
            var viewContext = new ViewContext(context, view, partialViewResult.ViewData,
                                              partialViewResult.TempData, sw);
            view.Render(viewContext, sw);
            return sw.ToString();
        }
    }

الاستخدام:

public ActionResult MyAction(...) 
{
    var myModel = GetMyModel(...);
    string viewString = RenderPartialViewToString(PartialView("MyView", myModel));
    // do something with the string
    return someAction;
}

نستخدم هذا بالفعل في نموذج AJAX قائم على الحدث ، حيث تعيد معظم إجراءاتنا فعليًا فقط قائمة من أحداث Ajax من جانب العميل ، وقد تكون بعض أحداث من جانب العميل هذه هي تحديث عنصر DOM معين مع السلسلة ينتج عن طريق تقديم هذا الرأي الجزئي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top