Base class for view with RazorGenerator precompiled views - c#

I have console project with some .cshtml files stored in Resources folder, which is built into .cs files with Razorgenerator.MsBuild nuget package.
I need to replace WebViewPage view base class for generated view, but adding web.config file with pageBaseType="ConsoleApp.MyViewBase" option set or changing location of files in different ways did not help me and no any other ways where found.
View class is always generated as:
public partial class _Resources_Index_cshtml :
System.Web.Mvc.WebViewPage<ConsoleApp.ModelClass> { ... }
Hope, there is some way to confgure the class globally for all views, without adding directives at the beginning of every .cshtml file.

It looks that that setting base view in web.config works in latest RazorGenerator.
So update your RazorGenerator package and try to have something like this in web.config:
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="WebApplication2.Views.BaseView2">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization"/>
<add namespace="System.Web.Routing" />
</namespaces>
</pages>
</system.web.webPages.razor>
In my case I was adding precompilation (with RazorGenerator.Mvc and RazorGenerator.MsBuild packages) to old project and it didn't work. The problem was that I had Version=2.0.0.0 in my configSections project and had to change it to Version=3.0.0.0.

If someone finds it helpful, there is a nuget package for this by me. It is same Razorgenerator.MsBuild but with replacing System.Web.Mvc.WebViewPage by Custom.System.Web.Mvc.WebViewPage. So if you want to use custom WebViewPage, install the package and add you class named WebViewPage in namespace Custom.System.Web.Mvc. Like:
namespace Custom.System.Web.Mvc
{
public abstract class WebViewPage<T>
{
...
}
}

Related

Application configuration file error at runtime

The context :
I have an winform application which is launch by users on the local network (path: \\file-01\appsdeploy$\MyApp )
When I launch the app, it's ok it worked well. But on some other computer it does not work. I have this exception :
An error occurred creating the configuration section handler for
MySection: Request failed.
The declaration of the section in the app.config file is :
<configSections>
<section name="MySection" type="MyGenerator.Config.MySection, MyGenerator"/>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="MySectionGenerator.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
</sectionGroup>
</configSections>
Now the section :
<MySection>
<Addresses>
<add Name="1" Text="ADDRESS ONE"/>
<add Name="2" Text="ADDRESS TWO"/>
<add Name="3" Text="ADDRESS THREE"/>
<add Name="4" Text="ADDRESS FOUR"/>
<add Name="5" Text="ADDRESS FIVE"/>
<add Name="6" Text="ADDRESS SIX"/>
<add Name="7" Text="ADDRESS SEVEN"/>
</Addresses>
</MySection>
NOTE : If I copy the executable and the config file on the local computer, it works fine.
Have you got an idea, a clue... ?
Check with allowExeDefinition=machinetoapplication option.

Server responded with 404: Not Found for localhost/undefined

I have been scratching my head for days. I've googled to no avail. I am trying to get stuff from a database with jquery.ajax, based on the information I send over (sorta a post AND a get) everytime though, the server responds with an Error 404: Not Found, and is telling me I asked for Localhost:1986/undefined, which is not the case.
I'm sure exactly where all my folders and files are is important, so I will include as much as I can, feel free to ask for more if it is necessary.
My script is copy pasted and modified from another script I have to post to the database, and that works fine, so why this one doesn't stumps me:
function nextSlide() {
var articleLink = document.getElementsByTagName("a")[0];
$.ajax({
type: 'POST',
url: "../SlideShow/NextArticle",
data: {
slideID: articleLink.getAttribute("id"),
},
success: function (result) {
$(articleLink).id = result[0];
document.getElementById("articleImage").setAttribute("src", result[1]);
document.getElementById("articleTitle").innerHTML = result[2];
document.getElementById("articleText").innerHTML = result[3];
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("Status: " + textStatus); alert("Error: " + errorThrown);
}
});
}
This is the method inside my SlideShowController.cs file I am trying to use:
[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Get)]
public JsonResult NextArticle(string slideID)
{
int ID = int.Parse(slideID);
var articles = db.Slides.ToList();
var currentArticle = db.Slides.First(s => s.SlideId == ID);
int articlePosition = articles.IndexOf(currentArticle);
articlePosition = (articlePosition + 1) >= articles.Count() ? 0 : articlePosition + 1;
var nextArticle = articles.ElementAt(articlePosition);
//nextArticle.Article.ArticleText.Substring(0, 50)+"..."
string[] returnParameters = {
nextArticle.SlideId.ToString(),
nextArticle.Image.ImageURL,
nextArticle.Article.ArticleTitle,
nextArticle.Article.ArticleText
};
return Json(returnParameters);
}
The SlideShowController.cs file is inside a folder named Controllers in the root directory. The script is called from a _SlideShowPartial.cshtml file in a Root/Views/SlideShow folder. That file is loaded in a Index.cshtml file in a Root/Views/Home folder using #html.Partial()
Here is a screenshot of the error that appears in chrome console:
And here is the contents of the Web.Config file inside the Views folder:
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="TIAWebWorkConnect.Models.AppViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization"/>
<add namespace="System.Web.Routing" />
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
</httpHandlers>
<!--
Enabling request validation in view pages would cause validation to occur
after the input has already been processed by the controller. By default
MVC performs request validation before a controller processes the input.
To change this behavior apply the ValidateInputAttribute to a
controller or action.
-->
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<controls>
<add assembly="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>
You're definitely sending url wrongly to the server. try a complete url, or remove url from your $.ajax query.
Consider introducing T4 MVC into your project. This will give you strongly typed access to MVC actions and let you avoid URL strings which looks like your issue here.
https://github.com/T4MVC/T4MVC/blob/master/README.md

Html.ActionLink reference error MVC4 in Areas

I've created an Area in my app called "Admin" and when I attempt to use #html.actionlink() to build some menu items I'm met with a reference error.
system.web.WebPages.Html.HtmlHelper does not contain a definition for ActionLink and the best extension method overload System.Web.Html.LinkExtensions.ActionLink(System.Web.HtmlHelper,string, string, string) has some invalid arguments.
This is the line of code that's generating the error.
#Html.ActionLink("Posts", "Index", new { area = "admin" });
I've googled around and attempted adding using system.web.mvc.html; with no benefit or change in behavior. I've checked the web.config file for the area and confirmed that both system.web.mvc and system.web.mvc.html are included in the namespaces, also to no avail.
You are using actionlink wrongly.
Below is the correct usage of actionlink(i m taking example of any arbitrary actionlink)
Html.ActionLink(article.Title, // <--Link Text
"Item", // <-- ActionMethod
"Login", // <-- Controller Name.
new { id = article.ArticleID }, // <-- Route arguments.
null // <-- htmlArguments
)
This uses the following method ActionLink signature:
public static string ActionLink(this HtmlHelper htmlHelper,
string linkText,
string actionName,
string controllerName,
object values,
object htmlAttributes)
The error is coming in your question because 3rd overload of Actionlink is controller name.
#Html.ActionLink("// Link Text //", "// Action Name //",// controller name //, new { area = "admin" });
You are missing a web.config in your /Areas/Admin/Views folder. Just create the basic one like below, the key part being the added namespaces:
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.Optimization" />
<add namespace="Club.Web" />
<add namespace="Club.Web.Helpers"/>
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.webServer>
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>

Multiple AppSettings files, is it possible?

I want to create 3 AppSettings config files:
Database.config
Messages.config
Global.config
And after add in my App.config:
<appSettings file="Database.config" />
<appSettings file="Messages.config" />
<appSettings file="Global.config" />
But when I try to access a key that there is in one of three files with the ConfigurationManager, I got the following error:
Configuration system failed to initialize. Sections must only appear once per config file.
I cannot have more than one AppSettings config file?
You can't have more than one appsettings because that's the name of a section. You can add a new section though that uses the same kind of section definition as appsettings. E.g.,
<configuration>
<configSections>
<section name="DatabaseConfig" type="System.Configuration.NameValueFileSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</configSections>
....
<DatabaseConfig>
<add key="Whatever" value="stuff"/>
</DatabaseConfig>
</configuration>
Code for separate file:
Web.config:
<configSections>
<section name="DatabaseConfig" type="System.Configuration.NameValueFileSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="MessageConfig" type="System.Configuration.NameValueFileSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="GlobalConfig" type="System.Configuration.NameValueFileSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<DatabaseConfig configSource="database.config">
</DatabaseConfig>
<MessageConfig configSource="message.config">
</MessageConfig>
<GlobalConfig configSource="global.config">
</GlobalConfig>
database.config:
<DatabaseConfig>
<add key="Name" value="ServerName" />
</DatabaseConfig>
etc...
Can be accessed via code like this:
var databaseConfiguration = (NameValueCollection)ConfigurationManager.GetSection("DatabaseConfig");
string name = databaseConfiguration["Name"];

MVC3 Views unable to find added referenced class

My view is having issues finding a class located in one of my references.
This reference is to a dll built outside of the project.
The view always gives error:
The type or namespace name 'Company' could not be found (are you
missing a using directive or an assembly reference)
Here is the controller. No issues there.
using Company.Entities;
public ActionResult Find()
{
Person test = Person.SelectByADDistinguishedName("L*", false);
return View(test);
}
Here is the View. The error occurs in the #Model line.
#model Company.Entities.Person
#{
ViewBag.Title = "Bob";
}
<h2>Find</h2>
My Views/Web.config currently looks like this
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="Company.Entities" />
</namespaces>
</pages>
</system.web.webPages.razor>
I've checked similar threads like this one but to no avail.
Here is the message on the screen
Line 25: using System.Web.Mvc.Html;
Line 26: using System.Web.Routing;
Line 27: using Company.Entities;
Line 28:
Line 29:
Source File: c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET
Files\root\49c9c7db\1f9dd5c8\App_Web_find.cshtml.a8d08dba.xro6gxci.0.cs
Line: 27
If I strip out any mention of the assembly (out of web.config - no #using statments). I get the same error message when loaded but against this line
public class _Page_Views_Home_Find_cshtml : System.Web.Mvc.WebViewPage<Company.Entities.Person> {
After working it with it for awhile, I ended up solving it.
I had to add the assembly under the assemblies section of the main web.config (not the one under the views)
Sample of the web.config.
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="Company, Version=2.0.31.0, Culture=neutral, PublicKeyToken=df9010405db60e6d"/>
</assemblies>
</compilation>
Thanks for people who gave me suggestions.
Be sure to check your views directory for an additional web.config file. I seem to remember running into a similar problem because I hadn't updated the correct web.config. YMMV.
Adding the reference
before where you use your control, in .cshtml file works. Example:
#model IEnumerable<MyApp.Models.MyModel>
#using System.Web.UI.WebControls;
But you can put it in web.config, under namespaces tag.
This way it is global to all views. Also, there is no need to specify the version:
<namespaces>
<add namespace="System.Web.UI.WebControls" />
</namespaces>

Categories

Resources