How can I render Razor page from Assembly - asp.net

UPDATE1
I've added RazorGenerator and etc...
After set custom tools, I've seen generated code for my razor pages.
Added this code in assembly
public class MyAreaRegistration : AreaRegistration
{
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute("Dictionary_default", "MyDictionary/{Action}/", new { controller = "DictionaryControllerBase", action = "Index" });
}
public override string AreaName
{
get { return "MyDictionary"; }
}
#endregion
}
But when I open page by url /MyDictionary, i see "Unable to find the resource."
NOTE I use in my project MVC3 and Spring.Net
I use one controller (base controller) in another Assembly with razor pages.
In my project I make controller inherited from base controller, just it make some settings. But razor pages I wish to use from assembly.
How can I do it?

You could the RazorGenerator extension. I have detailed how this can be achieved in the following post. The idea is that the RazorGenerator extension would create a corresponding .cs file for each Razor view and it will update it every-time you make a change to the corresponding view. This way the Razor views will be precompiled in the class library along with their respective controllers and view models. The RazorGenerator.Mvc NuGet will then register a custom virtual path provider which will take care of resolving those views.

Related

Custom Routing in ASP.NET Core 2.2 Razor Pages

I'm having trouble setting up a routing convention for Razor Pages in an ASP.NET Core 2.2 application (I'm migrating from traditional MVC to Razor Pages).
I am using the standard Pages folder structure as recommended in the documentation, but I want to customise the generated routes slightly.
For example, on a Details.cshtml page in the Products folder I have the following directive:
#page "{id:int}
The URL for this page is:
/Products/Details/42
however I want the URL to be:
/Products/42
I want this to be globally applicable, not just on the Product Details page. The documentation is not particularly clear on this.
So this seems to be the way to do it:
https://www.mikesdotnetting.com/article/327/customising-routing-conventions-in-razor-pages
Create a class that implements IPageRouteModelConvention:
public class CustomPageRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
foreach (var selector in model.Selectors.ToList())
{
var template = selector.AttributeRouteModel.Template;
if (template.EndsWith("Details/{id:int}", StringComparison.OrdinalIgnoreCase))
selector.AttributeRouteModel.Template = template.Replace("Details/{id:int}", "{id:int}", StringComparison.OrdinalIgnoreCase);
}
}
}
Register the class in Startup.cs:
services
.AddMvc()
.AddRazorPagesOptions(o =>
{
o.Conventions.Add(new CustomPageRouteModelConvention());
});
Compared to the old MVC way of doing it this seems like a massive effort, but I can see that it allows for a finer level of control.
You need to override the entire route, so this is what you needed -
#page "/Products/{id:int}"

Preparing for Internationalization of Asp.net MVC website

I'm going to start a website which I know is going to be presented in multiple languages. However, for the first version we're only going to need the English version. Once the features are all working, we'll add the other languages.
Unfortunately since there are not enough enough features baked into Asp.Net Core, we have to use the Asp.Net MVC 5 for the website. My question has 2 parts:
Right now, which practice is considered the best approach for this? Using resource files and loading them in razor pages? Using a framework? Can we use the new localization and globalization features of Asp.Net MVC 6 somehow? Or is there a better alternative? I personally hate using the resource files. It adds too much clutter to the code.
Would you suggest just using plane text for now and then adding the Internationalization features to the website or start now and only add the translations?
I would use resource files, seems to be the easiest solution. You can also use a Database resource provider, so you have less clutter.
If you start with plain text, it will get more complicated and cumbersome to add the translations later. So I would not do that.
We use Smart internationalization for ASP.NET.
Features
Localize everything: HTML, Razor, C#, VB, JavaScript, .NET attributes
and data annotations, ...;
SEO-friendly: language selection varies the URL, and Content-Language is set appropriately;
Automatic: no URL/routing changes required in the app;
High performance, minimal overhead and minimal heap allocations; Unit testing support;
Smart: knows when to hold them, fold them, walk away, or run, based on i18n best practices.
How I use i18n in the project step by step:
Add the I18N nuget package to your MVC project.
in Web.config:
Add a folder named "locale" to the root of your site. Create a subfolder for each culture you wish to support. For example, /locale/fr/.
copy i18n.PostBuild.exe into locale folder
Right click on tne project name --> Properties --> Build Events:
in Post-build event command line:
"$(TargetDir)i18n.PostBuild.exe" "$(ProjectDir)\web.config"
In views use [[[some text]]] to translate it later
Build the project
Refresh Solution Explorer and push Show All Files
Include all files in "locale" folder into the project
Provide translation of the words in locale\fr\messages.po
In Global.aspx add :
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
//other app start code
UrlLocalizer.UrlLocalizationScheme = UrlLocalizationScheme.Void;
}
}
Create DefaultController :
public class DefaultController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (Session["currentLanguage"] == null)
{
Session["currentLanguage"] = "en";
}
}
}
In HomeController add inheritance of DefaultController and SwitchLanguage(string lang):
public class HomeController : DefaultController
{
public HomeController() : base()
{
[AllowAnonymous]
public async Task<ActionResult> SwitchLanguage(string lang)
{
LocalizedApplication.Current.DefaultLanguage = lang;
Session["currentLanguage"] = lang;
return Redirect(Request.UrlReferrer.PathAndQuery);
}
}
}
In navigation bar View (_LoginPartial.cshtml in my case) add links to switch between languages:
#if (Session["currentLanguage"].ToString() == "fr")
{
<li class="navItem">#Html.ActionLink("EN", "SwitchLanguage", "Home", new { lang = "en", area = "" }, null)</li>
}
else
{
<li class="navItem">#Html.ActionLink("FR", "SwitchLanguage", "Home", new { lang = "fr", area = "" }, null)</li>
}
Build project, Start in Browser and enjoy!!!
see some help in:
https://www.codeday.top/2017/09/19/42409.html

Insert _ViewStart.cshtml

Is that possible to use viewstart only for a particular controller and view?
I was using only _Layou.cshtml file inside views folder.
Now i added _ViewStart.cshtml as common view inside views folder and moved _Layout to Shared folder.
This is program structure:
Homecontroller
public ActionResult Index()
{
return View();
}
Index.cshtml
#{
Layout = "~/Views/_Layout.cshtml";
}
_Layout.cshtml
{
//design code for Index.chtml
}
as per the above code, _Layout rendered for homecontroller .
When done the changes mentioned at the very first line, I'm getting the controls inside _Layout.cshtml in every controller I use.
I use nearly 6 controllers.
How to make this change without disturbing the entire code.
Please help.
PS: I need to introduce _ViewStart into the program since I'm integrating openid with my already developed project.
You can create another _ViewStart.cshtml (in Views/[controller] a sub-folder for example) that will override the root one, something like:
#{ Layout = null; }
You can simply use the ViewBag to determine whether to use Layout or not:
public ActionResult AnotherAction()
{
....
ViewBag.NoLayout = true;
return View();
}
and in your _ViewStart:
#{
if (ViewBag.NoLayout == null || !ViewBag.NoLayout)
Layout = "~/Views/_Layout.cshtml";
}
You can read more about MVC3 Razor layouts on Scott Guthrie's Blog

How to add a new page in ASP.NET mvc4?

I want to make a new project and I want to add a new page, using the Microsoft sample website as a starting point. The Microsoft sample website already has an About and a Contact page.
How do I add a new page to the sample website using ASP.NET mvc4?
In ASP.NET MVC you work with Models, Controllers and Views. Controllers are classes containing methods called Actions. Each Action is used as an entry point for a given user request. This Action will perform any necessary processing with the model and return a view. So basically you will start with defining a Controller (if not already done) and add Actions to it:
public class HomeController: Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult SomeAction()
{
return View();
}
}
Then you right click on the Action name and select the Add->View option which will create a new View for the given Action in the respective ~/Views folder.
I would recommend that you start by going through the basic tutorials here: http://asp.net/mvc

asp mvc controller creation

i want dynamically create ascx files, to partial render them.
but as i know, ot show them , i at least need dummy method:
public ActionResult test()
{
return PartialView();
}
how can i create this method for each new ascx file?
upd: i need factory?
Why would you create dynamic ascx files?
If you want to create all the layout in the controller you should be able to return it directly.
But then, why would you do that?
This way it will be really hard to do unit testing and refactoring and reuse.
You'd need to create your .ascx controls ahead of time. If you are doing this, I would recommend that you register a new view engine to provide a new PartialView location.
public class MyViewEngine : WebFormsViewEngine
{
public MyViewEngine()
{
PartialViewLocationFormats = new[]
{
"~/Views/{1}/{0}.ascx",
"~/Views/GeneratedControls/{0}.ascx",
"~/Views/Shared/{0}.ascx"
};
}
}
This allows you to write your dynamic views to the /Views/GeneratedControls/ folder. If you need to use a specifically named control (i.e. the control you generate has a random name) then you simply need to adjust your call to PartialView:
public ActionResult test()
{
return PartialView("name-of-control");
}
Otherwise MVC will use the name of the Action as the name of the control to use.

Resources