MVC 4 Variables in _Layout.cshtml - asp.net-mvc-3

In MVC 3 I was able to put:
#{
string rootPath = HttpContext.Current.Request.ApplicationPath;
if (rootPath == "/")
{
rootPath = rootPath.Replace("/", "");
}
}
in my _Layout.cshtml file and then use rootPath in any of my other views to get the site root.
I tried the same thing in a MVC 4 app and it doesn't work unless I put the above code in the same view file I'm trying to use rootPath in.
Has anyone else bumped into this issue?

Depending on what you are doing, you can just put that logic in an html helper which can then be called from anywhere.

Related

Return html view from controller

Since I upgraded my application to .Net Core 3.0, I can't return a html view from a controller.
If I call View("Views/test.html"), it says it doesn't find the file. In 2.2, it worked well...
Any idea on the breaking change that made my code broken ?
If you want to be able to request static HTML files, add them under wwwroot or create a directory inside it , for example , html folder , and serve that as well via the static files middleware . Then you can return the html to view with text/html content-type :
public IActionResult Index()
{
return File("/html/test.html", "text/html");
}
Thanks.
Finally, I modifier StaticFiles Middleware configuration to serve also html files that are not in the wwwroot folder using this code :
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "MyFiles/MyAngularJSApplication")),
RequestPath = "/app",
});
see : https://learn.microsoft.com/fr-fr/aspnet/core/fundamentals/static-files?view=aspnetcore-3.0

Images with razor asp.net mvc inside JS

I need to dynamically insert an image in my JS code. In my Razor template I have:
#section Includes {
<script type="text/javascript">
var imgPath = "#Url.Content("~/Content/img/")";
alert(imgPath);
</script>
}
Then in my JS I have:
insertImg = "";
if (response[i].someFlag == 'Y') {
insertImg = "<img src=\"" + imgPath + "/imgToInsert.gif\" width=\"6px\" height=\"10px\" />";
}
But it doesn't work - it will not find the image. The image is stored in /Content/img folder...
What am I doing wrong? I am guessing it is because it is mapping the image from Js script..looks like I will have to hardcode it?
Alert or console.log the following to see if there are too many slashes
" + imgPath + "/imgToInsert.gif"
It might be advantageous to use the MVC TagBuilder Class to build your image tags instead of using a string concatenations. Lets you build tags dynamically and makes sure they are well-formed. Most likely your tag is not well-formed.

Nested _ViewStart ignoring Layout setting

In my Views root folder I have _ViewStart.cshtml, which has:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
Page.Title = "Using Root ViewStart!";
}
Then in a nested Views\ProjectCharter folder, I have another _ViewStart.cshtml, which looks like this:
#{
Layout = "~/Views/Shared/_ProjectLayout.cshtml";
Page.Title = "Using Nested ViewStart!";
}
(note that both the _Layout.cshtml and the _ProjectLayout.cshtml file are in the same folder, called Views\Shared).
The problem I'm having is that the views in my Views\ProjectCharter folder are NOT using the _ProjectLayout.cshtml Layout...instead they are still using the root _Layout.cshtml (even though they are correctly picking up the "Using Nested ViewStart" title).
What's interesting is that if I change my ActionMethod to return the View using
return View("Create","~/Views/Shared/_ProjectLayout.cshtml",newProjectCharter);
instead of just
return View(newProjectCharter);
then the view does indeed use the _ProjectCharterLayout.cshtml layout. Any idea what I am missing? I don't want to have to change all my ActionMethods to use this more verbose overload.
As I can see from your post you are referring to _ProjectLayout.cshtml being in "
Views\ 'PROJECTCHARTER'
but in the code you are saying that it is in the shared folder:
Layout = "~/Views/ 'SHARED' /_ProjectLayout.cshtml";
Hope that will sort it out

Dynamic change ViewStart layout path in MVC 3

In my MVC project has 2 Areas which is Admin and Client and I need to dynamic config Layout for Client side, In _ViewStart (in client) file will set layout for all of client page.
Layout = "~/Views/Shared/_Layout.cshtml";
So if we need to change client layout we can change Layout path of cshtml file in _ViewStart file right? I cant find how to change inside ViewStart file or Is there another solution in this case.
Thanks for your Help :)
Remember that anything within the #{ ... } is treated as code. So, it should be a simple matter of placing a condition in there to change how it's inherited:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
if (User.Current.IsAuthenticated) {
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
}
Though you're probaby better off looking at Themes (and have an admin/user theme). Alternatively, you can make your _Layout.cshtml smarter and have it handle the different views based on conditions as well.
See Also: MVC3 Razor - Is there a way to change the Layout depending on browser request?
Your question has not enough information to give you a complete code sample.
But basicly you can do this
if (InsertIsAdminLogicHere) {
Layout = "~/Views/Shared/_AdminLayout.cshtml";
} else {
Layout = "~/Views/Shared/_Layout.cshtml";
}
If you show us how you determine admin or not, we can provide more help.
hope this helps
You can take advantage of Nested Layouts. Create a base controller and drive all controllers from this one.
public class ControllerBase : Controller
{
public ControllerBase()
{
ViewBag.Theme = "~/Views/Shared/Default/Views/_Layout.cshtml";
}
}
public class HomeController : ControllerBase
{
public ActionResult Index()
{
return View();
}
}
_ViewStart.cshtml (don't make any changes in this file)
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
Views/Shared/_Layout.cshtml
This is default Layout file of Asp.NET Mvc. Empty this and replace these lines.
#{
Layout = ViewBag.Theme;
}
#RenderBody()
You can Modify this way for Areas. You can fetch active template info in BaseController from database or wherever you want.
Btw, if you want to put your views outside of ~/Views folder search for ThemeableRazorViewEngine
in Views/_ViewStart.cshtml
#{
object multiTenant;
if (!Request.GetOwinContext().Environment.TryGetValue("MultiTenant", out multiTenant))
{
throw new ApplicationException("Could not find tenant");
}
Layout = "~/Views/"+ ((Tenant)multiTenant).Name + "/Shared/_Layout.cshtml";
}

Issue with wrong controller being called in jquery ajax call

My issue is for some strange reason it seems stuck in the page controller so instead of getting out and going into the ajax controller I have it trying to go down that route in the page controller
1st try
http://localhost:2185/Alpha/Ajax/GetBlah_Name/?lname=Ge&fname=He
2nd try
http://localhost:2185/Patient/~/Ajax/GetBlah_Name/?lname=Ge&fname=He
Objective
http://localhost:2185/Ajax/GetBlah_Name/?lname=Ge&fname=He
Page button to call jquery
<a style="margin-left: 310px;" href="javascript:void(0)" onclick="getBlah()"
class="button"><span>Lookup</span></a>
Jquery code
1st try
{
$.getJSON(callbackURL + 'Ajax/GetBlah_Name/?lname=' + $('#Surname').val() + '&fname=' + $('#FirstName').val(), null, GetResults)
}
2nd try
{
$.getJSON(callbackURL + '~/Ajax/GetBlah_Name/?lname=' + $('#Surname').val() + '&fname=' + $('#FirstName').val(), null, GetResults)
}
In summary I don't know why it won't break out of the controller and go into the Ajax controller like it has done so in all the other projects I've done this in using the 1st try solution.
It seems you want to cal a controller at ~/Ajax. Is it? If yes, you should use this code:
$.getJSON(callbackURL + '/Ajax/GetBlah_Name/?lname=' + $('#Surname').val() + '&fname=' + $('#FirstName').val(), null, GetResults)
UPDATE:
This will work for your Q, but the complete solution is #Darin Dimitrov's answer. I suggest you to use that also.
UPDATE2
~ is a special character that just ASP.NET works with it! So http doesn't understand it. and if you start your url with a word -such as Ajax-, the url will be referenced from where are you now (my english is not good and I can't explain good, see example plz). For example, you are here:
http://localhost:2222/SomeController/SomeAction
when you create a link in this page, with this href:
href="Ajax/SomeAction"
that will be rendered as
http://localhost:2222/SomeController/Ajax/SomeAction
But, when url starts with /, you are referring it to root of site:
href="/Ajax/SomeAction"
will be:
http://localhost:2222/Ajax/SomeAction
Regards
There are a couple of issues with your AJAX call:
You are hardcoding routes
You are not encoding query string parameters
Here's how I would recommend you to improve your code:
// Always use url helpers when dealing with urls in an ASP.NET MVC application
var url = '#Url.Action("GetBlah_Name", "Ajax")';
// Always make sure that your values are properly encoded by using the data hash.
var data = { lname: $('#Surname').val(), fname: $('#FirstName').val() };
$.getJSON(url, data, GetResults);
Or even better. Replace your hardcoded anchor with one which will already contain the lookup url in its href property (which would of course be generated by an url helper):
<a id="lookup" href="Url.Action("GetBlah_Name", "Ajax")" class="button">
<span>Lookup</span>
</a>
and then in a separate javascript file unobtrusively AJAXify it:
$(function() {
$('#lookup').click(function() {
var data = { lname: $('#Surname').val(), fname: $('#FirstName').val() };
$.getJSON(this.href, data, GetResults);
return false;
});
});
Now how your urls will look like will totally depend on how you setup your routes in the Application_Start method. Your views and javascripts are now totally agnostic and if you decide to change your route patterns you won't need to touch jaavscript or views.

Resources