Hasilkan URL dalam pembantu HTML

168

Biasanya dalam tampilan ASP.NET orang dapat menggunakan fungsi berikut untuk mendapatkan URL (bukan an <a>):

Url.Action("Action", "Controller");

Namun, saya tidak dapat menemukan cara melakukannya dari pembantu HTML khusus. saya sudah

public class MyCustomHelper
{
   public static string ExtensionMethod(this HtmlHelper helper)
   {
   }
}

Variabel pembantu memiliki metode Tindakan dan GenerateLink, tetapi mereka menghasilkan <a>. Saya melakukan beberapa penggalian dalam kode sumber ASP.NET MVC, tetapi saya tidak dapat menemukan cara yang mudah.

Masalahnya adalah bahwa Url di atas adalah anggota kelas tampilan dan untuk instantiasinya diperlukan beberapa konteks dan peta rute (yang saya tidak ingin berurusan dengan dan saya tidak seharusnya melakukannya). Atau, turunan dari kelas HtmlHelper juga memiliki beberapa konteks yang saya anggap sebagai perjamuan subset dari informasi konteks dari instance Url (tapi sekali lagi saya tidak ingin berurusan dengan itu).

Singkatnya, saya pikir itu mungkin tetapi karena semua cara saya bisa melihat, melibatkan beberapa manipulasi dengan beberapa hal ASP.NET internal yang kurang lebih, saya bertanya-tanya apakah ada cara yang lebih baik.

Sunting: Misalnya, satu kemungkinan yang saya lihat adalah:

public class MyCustomHelper
{
    public static string ExtensionMethod(this HtmlHelper helper)
    {
        UrlHelper urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
        urlHelper.Action("Action", "Controller");
    }
}

Tapi sepertinya itu tidak benar. Saya tidak ingin berurusan dengan contoh UrlHelper sendiri. Pasti ada cara yang lebih mudah.

Jan Zich
sumber
3
Saya menyadari ini adalah contoh yang disederhanakan, tetapi untuk contoh yang ditampilkan saya akan memperluas UrlHelper alih-alih HtmlHelper. Kode sebenarnya Anda mungkin membutuhkan keduanya.
Craig Stuntz
Maaf, saya seharusnya lebih jelas: Saya ingin melakukan rendering HTML dalam metode ekstensi dan saya perlu membuat URL untuk itu.
Jan Zich

Jawaban:

217

Anda dapat membuat url helper seperti ini di dalam metode ekstensi helper html:

var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var url = urlHelper.Action("Home", "Index")
Darin Dimitrov
sumber
2
Saya pikir akan lebih baik jika konstruktor juga menginisialisasi RouteCollectionnew UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection)
kpull1
22

Anda juga bisa mendapatkan tautan menggunakan UrlHelperkelas publik dan statis:

UrlHelper.GenerateUrl(null, actionName, controllerName, null, null, null, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true)

Dalam contoh ini Anda tidak perlu membuat kelas UrlHelper baru apa yang bisa menjadi sedikit keuntungan.

menangis
sumber
Saya lebih suka jawaban ini karena mengatur RouteCollection.
kpull1
10

Berikut ini adalah metode UrlHelperpengembangan kecil saya untuk mendapatkan HtmlHelpercontoh:

  public static partial class UrlHelperExtensions
    {
        /// <summary>
        /// Gets UrlHelper for the HtmlHelper.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <returns></returns>
        public static UrlHelper UrlHelper(this HtmlHelper htmlHelper)
        {
            if (htmlHelper.ViewContext.Controller is Controller)
                return ((Controller)htmlHelper.ViewContext.Controller).Url;

            const string itemKey = "HtmlHelper_UrlHelper";

            if (htmlHelper.ViewContext.HttpContext.Items[itemKey] == null)
                htmlHelper.ViewContext.HttpContext.Items[itemKey] = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

            return (UrlHelper)htmlHelper.ViewContext.HttpContext.Items[itemKey];
        }
    }

Gunakan sebagai:

public static MvcHtmlString RenderManagePrintLink(this HtmlHelper helper, )
{    
    var url = htmlHelper.UrlHelper().RouteUrl('routeName');
    //...
}

(Saya memposting ans ini hanya untuk referensi)

Kibria
sumber
Pendekatan yang sangat baik karena menggunakan kembali objek yang sudah ada daripada membuat yang baru.
Mike
Kami menggunakan ASP.NET 4.5 dan mengalami masalah re-entrancy. Kami tidak percaya UrlHelper dapat digunakan kembali di seluruh permintaan http. Mohon diperhatikan.
Carl di Veld