How to use compiled global resources in ASP.NET MVC - asp.net-mvc

I want to compile App_GlobalResources/Strings.resx into my assembly (and eventually use satellite assemblies for Strings.es.resx, Strings.fr.resx, etc.) but the following error occurs once the app is published:
"Could not load file or assembly 'App_GlobalResources' or one of its dependencies. The system cannot find the file specified."
Steps to Reproduce:
Create a new ASP.NET MVC project.
Add an App_GlobalResources folder and a Strings.resx file.
Set the file's build action to 'Embedded Resource'
Add a string to Strings.resx and use it in HomeController.Index(), e.g. ViewData["Message"] = Strings.MyTest
F5 to debug, works fine.
Publish to IIS and (since Strings.resx is excluded from publishing) you will get the above error in the published site.
Can ASP.NET MVC projects use string resources compiled into the dll and if so, what am I doing wrong?
Update: Here is what I see in Reflector:
So why is the ResourceManager not finding them? Isn't it supposed to fallback to the main assembly by default?

Here's a good starting point http://odetocode.com/Blogs/scott/archive/2009/07/16/resource-files-and-asp-net-mvc-projects.aspx
I setup a project just like you mentioned and got precisely the same error when I deployed to IIS6. Changing Custom Tool to PublicResXFileCodeGenerator and Custom Tool Namespace to Resources per Scott's suggestions cleared it right up.
I'd also follows Scott's lead with respect to eliminating App_GlobalResources but I got it to work just fine. That might be a matter of personal preference.

Probably there is one more thing one should know about the PublicResXFileCodeGenerator - it does not work with files that has more then one dot in the file name (see http://social.msdn.microsoft.com/Forums/ru-RU/9412f049-acd8-4a77-b73a-f3810df18376/naming-resources-files-issue-aspnet-mvc-3?forum=dlr). So the codebehind for the Strings.es.resx, Strings.fr.resx, etc. remains empty. The easy solution is to rename the files.

Related

MVC5 with VB.NET: "BC30451: 'ViewData' is not declared." when switching to Debug configuration

I have a MVC5 project that is currently set on the "Release Configuration" and it works 100%. However, as soon as I switch the project configuration from Release to Debug, then everything goes wrong... even if I switch it back to Release mode, everything is still broken. Only way I can get the project working again is to restore from a backup.
Here are what is happening.
Firstly, when running the project, I get the following error:
BC30451: 'ViewData' is not declared. It may be inaccessible due to its
protection level.
If I open any view in the project with Visual Studio 2013, I can see that all sorts of things are marked as errors like ViewData, Html, Url, etc.
When referring to #Html or #ViewData in the view, it normally refers to the .Html and .ViewData properties of the view's base class (WebViewPage). However, if I start typing "#Html." in any of the views, I can see in the autocomplete that it is referring to the System.Web.Webpages.Html namespace instead of the WebViewPage.Html property. It is as-if the view isn't inheriting from the System.Web.Mvc.WebViewPage class.
Any guidance as to where I can start looking to get this fixed or why this is happening?
Edit:
So since nobody responded, I went through the long way. I created a brand new MVC5 project, added all the packages via Nuget and then simply copied all my files over from the old project to the new one and now it works.
Does anybody have any idea what the heck could be causing this? I don't want to go through all this trouble again in the future if the project again suddenly decides to stop working.
Ok, I think I've found part of the cause here. Thing is, since the original code is valid (it compiles correctly and intellisense picks it up) and the code used to work and then all of a sudden, one day after compiling, it just stops working.
Anyway, in the view, when specifying the ModelType, if you don't use the full name, this error can occur or occurs eventually.
For example, using:
#ModelType Models.SomeNamespace.SomeClass
will cause the error (even though the Root Namespace for the project is "MyProject") and it can be fixed by simply specifying the full namespace and class name.
#ModelType MyProject.Models.SomeNamespace.SomeClass
It's possible that a debug assembly is locked. Can close Visual Studio, search and delete for all bin folders in the solution directory. Then open and rebuild.
The other options is to go into the MVC project properties and compare the two build configurations. Are you targeting a different .NET framework between Release and Debug? 32 bit vs 64 bit? etc?
Looks like some MVC assemblies are corrupted.
Have you checked your referenced assemblies for some errors?
Try also cleaning all the .NET internal cache. More in this stackoverflow topic: Could not load file or assembly ... The parameter is incorrect
In my case imported ViewModel class name was incorrect, correcting it fixed the issue.

ASP.Net MVC: How to dynamically load assemblies (controllers) without an AppPool restart/recycle

I'm trying to write a module/plugin system for a website I'm working on. The overall goals are:
That the main website does not have to be recompiled every time a new plugin is added.
To be able to dump DLL's and CSHTML files into a set of folders that would basically add a set of routes, controller(s), and any other assemblies that the module depends on (Entity Framework, etc).
To avoid marking plugin files as "embedded resources" -- especially views.
To be able to add and remove these modules/plugins WITHOUT having to restart/recycle the IIS app pool or unload the app domain.
I got #1-3 working by following the example of Umbraco. Basically, I marked a method with the PreApplicationStartMethod attribute, and in it I shadow copy DLLs around, and use a custom ViewEngine to locate the module's CSHTML files. When my website first starts up, my module's controllers and views are working, and assemblies are loaded: Hooray!
However, when it came time to try part #4, I am getting this error when calling BuildManager.AddReferencedAssembly():
This method can only be called during the application's pre-start
initialization phase. Use PreApplicationStartMethodAttribute to
declare a method that will be invoked in that phase
It's been a very frustrating process so far, and my gut tells me that this error signifies a dead end. Is this the case, or is there a clever workaround?
Editing the web.config file when you add the new modules should cause the site to recompile.
You could automate this in a script, forcing your new .dll's to be copied to the live ASP.NET temp files directory.
Check out portable areas. Essentially a regular MVC area (including views, controllers, etc.) gets compiled into a single dll. These dll's (one for each area) can be dropped into a hosting MVC website and can be called like any other MVC area.
Some references to get started:
Portable Areas three years later – Part 5
MvcContrib Portable Areas
"To be able to add and remove these modules/plugins WITHOUT having to restart/recycle the IIS app pool or unload the app domain."
It turns out that this you cannot unload an assembly from an app domain.
How to unload an assembly from the primary AppDomain?

Getting Compilation Error when trying to do Multiple-Project ASP.Net MVC Site

I am getting this error.
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS1704: An assembly with the same simple name 'MyMVCAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null has already been imported. Try removing one of the references or sign them to enable side-by-side.
My solution has 2 ASP.Net MVC projects - splitting the main content and the areas. The main project doesn't have a reference to the 2nd one. Instead, it gets all MVC DLL's in the folder and stores it into the IOC container, which takes care of registering all the controllers.
I get the error when I set the output of my 2nd ASP.Net MVC project into the bin folder of the main one. (I've set all my views in the Areas solution to Copy Always.)
I also tried post-build action of copying the DLL into the main bin instead of setting the output, but the results are the same.
What should I do?
In addition, I have the following setup:
It is set to use the Local IIS Server instead of the VS Dev Server.
In the Output window, I see that the local web server is loading all the DLL's from the GAC and Temporary ASP.Net files folder. The problem I see is that it is also trying to load my DLL file from my Solutions folder.
Any ideas why it is trying to get that sole DLL from the Solution too? It doesn't have that behaviour for the other projects.
UPDATE:
Here's a strange behaviour:
[1] I clear all copies of the offending assembly.
[2] I removed the post-build action that copies that assembly to my main MVC project bin folder.
[3] I run the main project. It works without any issues, but of course the missing assembly does not get loaded.
[4] I manually copy that assembly to the mian MVC project bin folder.
[5] I run the solution. It is getting the error again!
Can someone explain why it is trying to load this very same assembly from two different places?
Ok this may be a clue to the problem: Because I am copying the assembly to the main MVC project's bin folder, it is also getting copied into the Temporary ASP.NEt folder. At the same time, because the project is not being referenced by any other project in the solution, it is also copying the same assembly into IIS. How can I prevent this from happening? If I exclude the step of copying the assembly into the main MVC bin, it does not get loaded into IIS at all. Why is it behaving that way?
This error points out that two references have the same assembly
identity because the assemblies in question lack strong names, they
were not signed, and thus the compiler has no way of distinguishing
between them in metadata. Thus, the run time ignores the version and
culture assembly name properties. The user should remove the redundant
reference, rename one of the references, or provide a strong name for
them.
Can explain that like below.
Below sample creates an assembly and saves it to the root directory.
// CS1704_a.cs
// compile with: /target:library /out:c:\\cs1704.dll
public class A {}
Below sample creates an assembly with the same name as the previous sample, but saves it to a different location.
// CS1704_b.cs
// compile with: /target:library /out:cs1704.dll
public class A {}
Below sample attempts to reference both assemblies.The following sample generates CS1704.
// CS1704_c.cs
// compile with: /target:library /r:A2=cs1704.dll /r:A1=c:\\cs1704.dll
// CS1704 expected
extern alias A1;
extern alias A2;
UPDATE
If both assemblies are strong-named (signed), the CLR will always load from the GAC.
You can follow below mentioned steps :
Determines the correct assembly version by examining applicable
configuration files, including the application configuration file,
publisher policy file, and machine configuration file. If the
configuration file is located on a remote machine, the runtime must
locate and download the application configuration file first.
Checks whether the assembly name has been bound to before and, if so,
uses the previously loaded assembly. If a previous request to load the
assembly failed, the request fails immediately without attempting to
load the assembly.
Checks the global assembly cache. If the assembly is found there, the
runtime uses this assembly.
Probes for the assembly (for more info check below mentioned article )
for more information check How the Runtime Locates Assemblies
I hope this will help to you.
I had a similar problem playing around with a test container project having added the wrong reference. I removed it and found that after a solution clean and a rebuild the issue was two DLL's in the bin directory clashing. Having removed them and rebuilt everything was fine.

Adding a service reference in ASP.NET MVC 4

I have two projects: Mvc3TestSvcRef & Mvc4TestSvcRef.
Mvc3TestSvcRef is from the ASP.NET MVC 3 template for an intranet application.
Mvc4TestSvcRef is from the ASP.NET MVC 4 template for an intranet application.
I'm trying to add a service reference.
In Mvc3TestSvcRef, I right-click the project (or the References folder) and choose Add Service Reference. I point to the URL, click Go. When the reference is resolved, I enter a namespace and click OK. As expected, I see the section added to config with the bindings and client tags completed.
I can import: "using Mvc3TestSvcRef.MySvcRef;"
And write code like:
using (var cl = new MyServiceClient())
{
cl.DoStuff();
}
In Mvc4TestSvcRef, I follow the same steps, but there is no system.servicemodel added to config. Additionally the import: "using Mvc4TestSvcRef.MySvcRef;" cannot be resolved.
I've tried this for MVC 4 from both Visual Studio 2010 and Visual Studio 2012.
Was there a major change to the process for adding service references in ASP.NET MVC 4 project type, or am I missing something or have corrupt install?
There was no code in Reference.cs, just comments:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.17929
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
I copied the reference.cs from the project that worked and modified the namespace, then added the section from the working project into the MVC 4 project and was still having an issue.
I tried to build and I got several warnings and an error. Failed to generate code for the service reference 'MySvcRef'. Please check other error and warning messages for details.
That led me to this article: Service Reference Error: Failed to generate code for the service reference
So I unchecked the Reuse types in all referenced assemblies from the Advanced section.
This seems to have generated a good service reference. Although, I should point out that if you have something in say System, like System.TimeSpan for example, that is used as a DataMember in one of your DataContracts, the reference will now have TimeSpan in the reference namespace, not from it's origin. So, the client would see any System.Timespan properties as ReferenceNameSpace.Timespan, which may throw off comparisons and such. The better answer here is to include specific assemblies from the reference and don't check the box for System.Web.Http, as pointed out in the comments below
I don't know if it is too late, but here is the solution "When you add the reference, on advanced setting remove the reuse types checkbox."

In an MVC web.config file what does the setting compilation debug='true' do?

For performance reasons an MVC app should have compilation debug='false' set in its web.config.
What benefits does having it set to 'true' during development give? I know that it 'inserts debugging symbols into the compiled page' but what is that for?
Check out this quite interesting link (very old, but still pertaining), which tries to explain in more detail the workings of either compilation mode, or, at least contrast between them well.
In an attempt to directly answer your question regarding what debugging symbols are used for - these give extra information about the compiled code and allow for interrogation of the executing code-base when a debugger is attached; allowing you to step through the source, for instance, as the binary can now be mapped back to it's location in the source file, variable names etc.
This is used for the code that is compiled on the fly (such as aspx and ascx pages) and will instruct the compiler how to compile the files.
Rest of the files such as models, global.asax, etc will be compiled to bin folder.

Resources