|
I have following code in ASP.NET MVC5 custom helper need to be converted in ASP.NET Core MVC custom helper:
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
string urlEdit = url.RouteUrl("Default");
I have read Microsoft doc about how to access HttpContext in ASP.NET Core but still cannot figure it out how to convert the above code.
-- modified 22-Aug-18 12:43pm.
|
|
|
|
|
ASP.NET Core is all about middleware and DI . In ASP.NET Core, the UrlHelper requires the current action context, and you can acquire that from the ActionContextAccessor . For example in your ConfigureServices method, you can do:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
You can then inject the IActionContextAccessor and use it in your custom helper service:
public class MyCustomHelper : IMyCustomHelper
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IUrlHelperFactory _urlHelperFactory;
public MyCustomHelper(IHttpContextAccessor httpContextAccessor, IUrlHelperFactory urlHelperFactory)
{
_httpContextAccessor = httpContextAccessor;
_urlHelperFactory = urlHelperFactory;
}
public string GetUrl()
{
var context = _httpContextAccessor.HttpContext;
IUrlHelper urlHelper = urlHelperFactory.GetUrlHelper(context);
}
}
|
|
|
|
|
Thanks for your response. I'm new to ASP.NET Core and still have following questions:
- Where should I put ConfigureServices method?
- My current MVC5 custom helper like following:
public static class HtmlHelperExt
{
public static IHtmlString CHGridTable<tmodel>(this HtmlHelper<tmodel> htmlHelper, DataTable dt, object htmlAttributes = null)
{
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
string urlEdit = url.RouteUrl("Default");
......
}
......//many other custom helpers
}
How can I inject the IActionContextAccessor and use it in my custom helper CHGridTable and other helpers? - How can I use the ContextAccessor to get info for the code lines below:
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
string urlEdit = url.RouteUrl("Default");
|
|
|
|
|
JimFeng wrote: I'm new to ASP.NET Core and still have following questions:
- Where should I put ConfigureServices method?
Configuring services should be placed inside startup.cs . For more details, see: ASP.NET Core fundamentals | Microsoft Docs[^]
JimFeng wrote: How can I inject the IActionContextAccessor and use it in my custom helper CHGridTable and other helpers?
While it may be possible, I would still recommend you to convert your static/extension class into a service whose concrete implementation would use the IHttpContextAccessor as a dependency that can be injected via its constructor just like what I've showed you on my first reply.
If you still want to follow the static class approach then you could try this:
public static class HtmlHelperExt{
private static IHttpContextAccessor _httpContextAccessor;
private static IUrlHelperFactory _urlHelperFactory;
public static void SetHttpContextAccessor(IHttpContextAccessor accessor, IUrlHelperFactory urlHelperFactory) {
_httpContextAccessor = accessor;
_urlHelperFactory = urlHelperFactory;
}
public static IHtmlString CHGridTable<tmodel>(this HtmlHelper<tmodel> htmlHelper, DataTable dt, object htmlAttributes = null)
{
var urlHelper = _urlHelperFactory.GetUrlHelper(_httpContextAccessor.HttpContext);
string urlEdit = urlHelper.RouteUrl("Default");
}
}
In the Startup.ConfigureServices method you can call services.BuildServiceProvider() to get the IServiceProvider to resolve the type you seek. For example:
public void ConfigureServices(IServiceCollection service) {
services.AddMvc();
var serviceProvider = services.BuildServiceProvider();
var accessor = serviceProvider.GetService<IHttpContextAccessor>()
var userHelperFactory = serviceProvider.GetService<IUrlHelperFactory>()
HtmlHelperExt.SetHttpContextAccessor(accessor,userHelperFactory);
}
|
|
|
|
|
Thanks again for your patient. when I code following:
var urlHelper = _urlHelperFactory.GetUrlHelper(_httpContextAccessor.HttpContext);
and got the following error:
Argument 1: cannot convert from 'Microsoft.AspNetCore.Http.HttpContext' to 'Microsoft.AspNetCore.Mvc.ActionContext'
the error was caused by argument: _httpContextAccessor.HttpContext
|
|
|
|
|
Hmm.. it's really hard to test it out without a dev machine. Anyway instead of passing IHttpContextAccessor , try to pass the IActionContextAccessor instead. For example in your Helper class, you can do:
private static IActionContextAccessor _actionContextAccessor;
private static IUrlHelperFactory _urlHelperFactory;
public static void SetHttpContextAccessor(IActionContextAccessor accessor, IUrlHelperFactory urlHelperFactory) {
_actionContextAccessor = accessor;
_urlHelperFactory = urlHelperFactory;
}
then you can do:
var urlHelper = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext);
and finally, configure the IActionContextAccessor in Startup.ConfigureServices method:
var accessor = serviceProvider.GetService<IActionContextAccessor>()
var userHelperFactory = serviceProvider.GetService<IUrlHelperFactory>()
HtmlHelperExt.SetHttpContextAccessor(accessor,userHelperFactory);
You could also try what's suggested by Richard.
|
|
|
|
|
asp.net core - how to get IUrlHelper from inside Html helper - Stack Overflow[^]
Correcting the typo in that answer gives:
public static IHtmlContent CHGridTable<TModel>(this IHtmlHelper<TModel> htmlHelper, DataTable dt, object htmlAttributes = null)
{
var urlHelperFactory = (IUrlHelperFactory)htmlHelper.ViewContext.HttpContext.RequestServices.GetService(typeof(IUrlHelperFactory));
var urlHelper = urlHelperFactory.GetUrlHelper(htmlHelper.ViewContext);
string urlEdit = url.RouteUrl("Default");
...
}
You might also want to consider whether a custom tag helper might be a better choice for what you're trying to do:
Tag Helpers in ASP.NET Core | Microsoft Docs[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks, I corrected error in my custom helper, but when I call the helper from views as following:
@HtmlHelperExt.CHGridTable(Model, new { tablename = "tblTest", defaultcolsort = "3" })
and got following error:
Error CS0411 The type arguments for method 'HtmlHelperExt.CHGridTable<TModel>(HtmlHelper<TModel>, DataTable, object)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
The call on MVC5 works file, How can I use the custom helper on view of Core Web Application (MVC6):
The custom helper code as following:
public static IHtmlContent CHGridTable<tmodel>(this HtmlHelper<tmodel> htmlHelper, DataTable dt, object htmlAttributes = null)
{
var urlHelperFactory = (IUrlHelperFactory)htmlHelper.ViewContext.HttpContext.RequestServices.GetService(typeof(IUrlHelperFactory));
var url = urlHelperFactory.GetUrlHelper(htmlHelper.ViewContext);
......
return new HtmlString(tbBtnAdd.ToString() + tbGridTable.ToString() + script.ToString());
}
|
|
|
|
|
JimFeng wrote: @HtmlHelperExt.CHGridTable(Model, new { tablename = "tblTest", defaultcolsort = "3" })
That should probably be:
@Html.CHGridTable(Model, new { tablename = "tblTest", defaultcolsort = "3" })
You need to call it as an extension method on the IHtmlHelper instance, not call the static method directly.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
@Html.CHGridTable(......) works on MVC5 but not ASP.NET Core MVC.
|
|
|
|
|
|
I added @addTagHelper *, HtmlHelperExt in _ViewImports.cshtml file but still got error:
Error: CS1061 'IHtmlHelper<dataset>' does not contain a definition for 'CHDropdownMenu' and no accessible extension method 'CHDropdownMenu' accepting a first argument of type 'IHtmlHelper<dataset>' could be found (are you missing a using directive or an assembly reference?)
on the View page like this (the same as on MVC 5):
@model System.Data.DataSet
@using HtmlHelperExt;
......
@Html.CHDropdownMenu(Model, "mnuSample1", new { MenuOpenType = "Hover" })
......
My Custom helper like this:
namespace HtmlHelperExt
{
public static class HtmlHelperExt
{
public static IHtmlContent CHDropdownMenu<tmodel>(this HtmlHelper<tmodel> htmlHelper, DataSet ds, string divID, object htmlAttributes = null)
{
......
return new HtmlString(tbDiv_Menu.ToString());
}
}
}
|
|
|
|
|
JimFeng wrote: IHtmlHelper<dataset>' does not contain a definition for 'CHDropdownMenu'
CHDropdownMenu<tmodel>(this HtmlHelper<tmodel> htmlHelper,
You need to declare the helper method as an extension method against the IHtmlHelper interface, not the HtmlHelper class.
public static IHtmlContent CHDropdownMenu<TModel>(this IHtmlHelper<TModel> htmlHelper, ...
IHtmlHelper Interface (Microsoft.AspNetCore.Mvc.Rendering) | Microsoft Docs[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
My assembly is a custom HtmlHelper NOT TagHelper.
|
|
|
|
|
Yes, of course.
You'll want @using statements for your namespace, rather than @addTagHelper statements. Still in the _ViewImports.cshml file, though.
@using HtmlHelperExt
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
@using HtmlHelperExt is already in the _ViewImports.cshml, but got the same error.
|
|
|
|
|
Did you change the first parameter of the extension method, as I suggested yesterday?
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thank you Rick, after I changed the parm type, and the helper works in my ASP.NET Core 2.1 MVC app.
|
|
|
|
|
Hi All,
My application is build in framework 3.5 and now i m converting into 4.5. Here is the code.
Response.Redirect(Request.ApplicationPath + path, true);
While converting this line to 4.5, i m getting "\" in Request.ApplicationPath. But i need application path.
Please anyone tell me why i m getting the "\" insider of the application path.
|
|
|
|
|
If you don't want the "\" then remove it using TrimStart or TrimEnd depending where you want to remove it from.
|
|
|
|
|
Hi,
Getting "\" is not a problem. Insider of getting "\", i need application path.
|
|
|
|
|
What is your definition of the "application path"?
|
|
|
|
|
|
"Website path" means nothing on its own, give me an example. What would the "website path" be for http://www.mysite.com/somefolder/page.aspx?param=1
|
|
|
|
|
In my local
http://localhost:1234/Admin/Home.aspx
Response.Redirect(Request.applicationpath + "Admin/Home.aspx")
Here Request.applicationpath returns "\"
|
|
|
|