I'm facing the following situation:
Complex MVC application with multiple projects
Should be able to handle multiple languages (not every language is already defined)
The resource keys will always be available, just the values are
different per language
Service layer and web layer needs resources
Resources are in its own project
Resources are public, with build action embedded resource and custom tool PublicResXFileCodeGenerator
The game changer:
The resource texts for each language should be editable in the web frontend and should be on the fly available
And here is the problem. Reading and displaying the contents of each resource in the frontend is no problem.
Reading the localized resource files on behalf of the set CultureInfo:
var resourceSet = ResourceFile.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, false);
Is it possible to change the resource files anyway? What would be another approach? The database way?
I found this approach. But it probably won't work within our environment since we have a seperate project for the resources and needs them in multiple projects.
My (simple) thoughts about the database way:
Every needed string for every ViewModel would be defined in ViewModelBase >:/
Controller gets the needed strings per View and set locale out of repository and sets them into the ViewModel
View would access the resources per ViewModel.Key
Any thoughts?
Thanks!
Is it possible to change the resource files anyway?
No, not with resource files. You could write a custom resource provider and store them in another storage such as a database for example.
Late answer: We stored all the resources in the database and coded a custom resource provider.
Related
I'm unable to get server side includes (*.html files) working in a .net core razor pages web application. I've made sure to have the appropriate handler in my applicationhost.config, but I'm thinking there's a different issue here. Any help is appreciated.
Why am I doing this? I have multiple web applications sharing the server side include files (for navigation bar, footer, head content, etc..). Each of these different applications may be of different Microsoft web architecture. Our goal is to move everything to .net core, but we have lingering web forms projects to deal with along the way.
I have performed a work around by taking the SSI file contents and using #Html.Raw to serve up the content. This is probably wrong also.
I went ahead and changed the file extension of the html files into cshtml which allowed me to treat these files as partial views. I'm using a prebuild event to copy these files from a shared solution folder into my project Pages/Shared/ssi folder. I also copy those partials into wwwroot/ssi for the other applications to use via SSI. Eventually all of the apps will use the partial views instead.
The problem with this solution is that it is not necessarily clear that all edits need to happen in the shared solution folder instead of directly in the project, but the documentation for the project will address this. I tried using linked files, but only one link to a specific file can be made in a project.
Not a perfect solution (to the problem), but this not a perfect website either.
I'm looking at migration strategies for an ASP4/MVC4 application into ASP5/MVC6. Our current implementation relies on loading cshtml views as embedded resources from DLL's, and we use a VirtualPathProvider to find these cshtml files.
Unfortunately, HostingEnvironment.RegisterVirtualPathProvider seems to be gone from MVC6. The closest thing I can find is IEnvironment.WebRootFileProvider, which is an IFileProvider. So I coded up a test class to see if it would work, and unfortunately, the IFileProvider I coded up is never queried for CSHTML files. I get requests for all of the .JS, .CSS, etc files, but no .CSHTML's.
What I'm looking for here is the ability to hook into the razor engine and provide a CSHTML file loaded from an embedded resource (or really, any other source for that matter) when a view is requested. What should I be looking at here?
Thanks!
Alright, I figured it out by digging around in the source code. I can load views from wherever I want by overriding the File Provider on the Razor View Engine options class:
services.AddMvc().AddRazorOptions(x => x.FileProvider = new EmbeddedFileProvider(typeof(Startup).Assembly));
Now the only problem I see is that there appears to be no way to embed resources in an ASP.NET 5 DLL via Visual Studio...
I've created a website in asp.net mvc4 and i've put it online with specific domain name. Now my client asks to replicate same website on different domain name, and change some static texts/images to distinguish the 2 websites. I'd like to handle just one source code and deploy two times. How i can reach this?
We did this a few years ago with a web application. It was a pain in the a**. We had one website running and the resources were loaded after the user has logged in.
During the development you always had to think about that, split the resources always look for the logged in user etc.
It is just easier to copy the published application to a second folder and for the static texts use some kind of resource files that can be replaced on the fly.
As long as you don't have images and files that are a few gigabytes big it should be no problem to copy the compiled source code an the resources.
Though kind of a too late reply, but I just wanted to share some of my experience with you, you can follow these steps, it won't take too much of your time.
Identify the various text / images like logo for branding etc for which you have a requirement to make them tenant specific.
Create a table called tenant settings (tenantid, key, value )
Identify the pages that needs to be tweaked to look up from this setting than a hardcoded value.
Update these pages and provide a UI for each tenant so that they can change the values at any point of time
This way you can achieve the level 4 multi-tenancy with minimal effort to begin with.
HTH
A client wants to be able to add any language to the multilingual MVC-based site I'm currently building.
They would be responsible for providing the translations themselves and while the process doesn't need to be enabled through a GUI it needs to be simple enough, so recompiling the project is a no-go. Editing text files (possibly XMLs) is OK.
Using a semicolon-separated list of language codes in the Web.config file (for example: en-US;de-GE and so forth) and using RESX files inside the App_GlobalResources folder I am able to satisfy the conditions... at least as long as the resources are used inside the Razor pages or MVC controllers.
There is a problem, however - any attempt to use the resources in MVC view model classes (such as the Display attribute or the Compare attribute) throws an error:
System.InvalidOperationException: Cannot retrieve property 'Name' because localization failed. Type '[Resource Type Here]' is not public or does not contain a public static string property with the name '[Resource Name Here]'.
There are several questions dealing with this already on StackOverflow, but ALL of them revolve around turning the resource files from content files into embedded resources. While this might make the code function it's no good for me because the resources can no longer be edited by the client!
What else can I do in this case?
In the end I scrapped using the automated mechanisms of MVC, using #Resources.MyResource.DisplayName in Razor files along with properties such as data-val-required added which can also be supplied with resources.
I'm developing a C# replacement for a legacy VB app for my company. The front end is basically a Web Browser control inside of a Windows form, serving offline content which is sometimes altered to include the user's data. Because there are 100 or more web files in the legacy app, we are going to reuse the web UI from the old application with a new C# wrapper around it, modifying them as needed.
My questions are about how to store and deliver the web content.
Does it make sense to copy the web files to a temporary folder and point the Web Browser control to the file:// address of the temporary folder?
Is there some kind of pre-built offline-friendly server framework that makes more sense than copying the files to a temporary folder?
I have the web source files in my project as resources, but I'm not sure if that is appropriate for my uses. Is it?
The legacy VB implementation alters the web files to inject data using Substring methods; it searches for magic strings and replaces them with the appropriate data. That code smells pretty bad, is there a better, more native data injection strategy I should look at?
Some background:
The data is presented using HTML\CSS\JS and also sometimes XSL.
The browser delivers content that is available at compile time.
I'm going to have to handle some events using c# code when users click on buttons of the page.
I'm free to choose whatever approach is necessary to implement the application.
Hosting
I would probably avoid using a temporary location for the web content it just seems a little crude. If there is no internal linking between your html pages and all the css/js is embedded in one file it may be easier to just use the WebBrowser.DocumentText property.
Another option I have successfully used as a lightweight embedded web server is logv-http, it has a pretty easy to configure syntax. If you want to configure against anything other than localhost it does require administrator privileges but it sounds like everything will be local.
var server = new Server("localhost", 13337);
server.Get("http://localhost:13337" ,(req, res) => res.Write("Hello World!"));
server.Start();
Templating
I think the string replaces aren't necessarily bad depends how many there are and how complicated they are trying to be, but for simple find replace it shouldn't be too hard to manage. If there are lots of replaces wrapping them into a RegEx should help performance.
Storing the web content as embedded resources is probably how I would go that way you can read them out at run-time do you pre-processing and then return either via the the web server method or direct into the DocumentText.