I don't get why we sometimes use ViewBag without reference (I mean #) to Controller in View, e.g.:
#{
string urlFilter = Url.Action("Index", "Home", new
{
CustID = ViewBag.custid,
Errors = ViewBag.errors
});}
It looks like a part of c# code in view. I know that razor synthax allow us to inject c# code into View but don't understand what's the point of using ViewBag without # in View
In this case it is because it is within the scope of a C# code block (#{ ... }) and not in the HTML markup.
If however, you were trying to reference the ViewBag inline in an HTML block you would need to prefix it with # to make sure it was processed by the Razor engine.
for example:
<p>#ViewBag.Name</p>
ViewBag is a dynamic property on the WebPageView from which the view is derived.
You can learn about the Razor syntax here: https://learn.microsoft.com/en-us/aspnet/web-pages/overview/getting-started/introducing-razor-syntax-c
Related
I am writing a new Razor Pages application (this is my first time with Razor pages rather than MVC), and I came to the point where I was needing to create a link and for the life of me I could not figure out why it was not working even though I tried every single variation of the parameters to the ActionLink method that I could think of. I then instead used the Anchor Tag Helper methodology instead with the exact smae parameters and it worked beautifully.
I was already confused when I scaffolded my views because the code generation uses both the Tag Helpers and the Html Helpers where as my brain tells me you should really pick one or the other and try to be as consistent as possible.
The code in the cshtml file is as follows:
<a asp-page="./DeleteIngredient" asp-route-MenuItemId="#item.MenuItemId" asp-route-IngredientId="#item.IngredientId">Delete</a>
#Html.ActionLink("Delete", "DeleteIngredient", new { MenuItemId = #item.MenuItemId, IngredientId = #item.IngredientId })
#Html.ActionLink("Delete", "./DeleteIngredient", new { MenuItemId = #item.MenuItemId, IngredientId = #item.IngredientId })
The Tag Helper correctly generates the following url:
https://localhost:44308/MenuItems/DeleteIngredient?MenuItemId=c469f993-9cac-4adc-bf63-2aba9be249c9&IngredientId=2f2863b1-27f4-4c62-93d6-84f27acb98fd
The Html Helpers generate the following:
https://localhost:44308/MenuItems/Details/c469f993-9cac-4adc-bf63-2aba9be249c9?MenuItemId=c469f993-9cac-4adc-bf63-2aba9be249c9&IngredientId=2f2863b1-27f4-4c62-93d6-84f27acb98fd&action=DeleteIngredient
Note: the links are on a page with the URL:
https://localhost:44308/MenuItems/Details/c469f993-9cac-4adc-bf63-2aba9be249c9
In summary, am I doing something wrong? Or does this appear to be a bug in the asp net core Html.ActionLink method?
Html.ActionLink is for MVC pattern, it requires Action and Controller names. Since you are using razor pages it will not work because you don't have controllers and action but you have Pages! So, your first approach is correct.
As an alternative you may use Url.Page to generate the link as below:
Delete
Is it possible to define the contents of a lambda expression (delegate, Action, Func<>) with Razor syntax, so that when this model method is executed in the view, it will insert that Razor content?
The intended purpose of this is for our developers to be able to define their own custom content to be inserted at a particular point in the CustomControl's view.
The following is stripped-down example code that mimics my current layout. The particular parts of focus are the RenderSideContent method definition and its executing call.
Index.cshtml
#model My.PageModel
#My.CustomControl(new CustomControlModel
{
AreaTitle = "Details",
RenderSideContent = () =>
{
<div>
#using (My.CustomWrapper("General"))
{
My.BasicControl(Model.Controls[0])
}
</div>
}
})
CustomControl.cshtml
<div>
#Model.AreaTitle
<div class="my-custom-content">
#Model.RenderSideContent()
</div>
</div>
Yes and no. No, you can't just feed it custom Razor like that, because in that context, you're dealing with straight C# and something like <div> is not valid C#. However, you can build an IHtmlString or MvcHtmlString object in the lambda and then return that.
However, you're going to need to create versions of your custom controls that return HTML versus render HTML. Basically, think of Html.Partial vs Html.RenderPartial. The former actually writes to the response while the latter merely returns an MvcHtmlString that can be rendered to the page at will.
It is possible, using Templated Razor Delegates:
#{
Func<dynamic, object> b = #<strong>#item</strong>;
}
<span>This sentence is #b("In Bold").</span>
#<text>...</text> is the format. The razor compiler will create a lambda expression. At the moment I'm using ASP.Net Core, so it looks like this:
item => new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_template_writer) => {...}
So this should work:
#model My.PageModel
#My.CustomControl(new CustomControlModel
{
AreaTitle = "Details",
RenderSideContent =
#<div>
#using (My.CustomWrapper("General"))
{
My.BasicControl(Model.Controls[0])
}
</div>
})
http://haacked.com/archive/2011/02/27/templated-razor-delegates.aspx/
See also: Are lambda expressions supported by Razor?
lets say i have a javascript variable such as:
var something = "information";
I now want to do things with this variable in Razor
#string something2 = something;
I would like to do something similar to the above code, any ideas?
You wont be able to convert JavaScript variable to a Razor variable. Where Razor variable is handled by Razor engine where as JavaScript on the other hand is a client side language running on the client.
Razor is a view engine used by the ASP.NET MVC framework running on the server to produce some HTML template.
I'm getting the dreaded "The parameters dictionary contains a null entry for parameter 'equipmentid' of non-nullable type" error when attempting to pass data through with a form. I've scoured google and stack overflow for answers and explanations, but I've come to the conclusion the problem has to me be not understanding how this stuff works. Coming from a traditional programming background the web stuff just doesn't seem as intuitive to me.
Here is my view code
#using (Html.BeginForm("CreateReservation", "ReservationList", FormMethod.Get, new { #equipmentID = 1 }))
{
<button class="btn btn-blue">Click</button>
}
Here is my controller
public ActionResult CreateReservation(int equipmentid)
{
// TODO: Query the piece of equipment being reserved.
return View();
}
Can anyone tell me what exactly am I doing wrong? From the answers I've read before and the examples I've viewed, I feel as though this should work.
I am assuming from your code that this is an Asp.Net MVC project, using C# as the language.
There are a number of issues. The first is that the equipmentID variable is not being passed to the view. There are a number of ways to do this. The simplest will be to do it in your controller using the ViewData dictionary, as follows:
public ActionResult CreateReservation(int equipmentid)
{
// TODO: Query the piece of equipment being reserved.
ViewData["equipmentID"] = equipmentid;
return View();
}
Once this is done, you could modify your view code to use the value as follows:
#using (Html.BeginForm("CreateReservation", "ReservationList", FormMethod.Get, new { equipmentID = ViewData["equipmentID"] }))
{
<button class="btn btn-blue">Click</button>
}
This is fine for one or two values, but when the view gets more complex, you rather want to create a ViewModel class, and pass that class to your view.
Secondly - your use of the # in front of equipmentID inside your BeginForm call indicates that you probably need to study up a bit on Razor syntax. A good place to start is Phil Haack's Razor Syntax Quick Reference. Razor syntax is what tells the parser which parts of your view are static HTML that it should output as is, and which parts are C# code that it should execute before sending to the browser. If you are using Visual Studio as your IDE, it is pretty good at highlighting which parts of your code are being interpreted as C# code, and which parts as ordinary HTML.
In my screenshot below you can see that VS2012 highlights C# code with a light grey background colour. The # symbol is the start of C# code - so you don't need to use it again unless you break out of the C# block and go back to HTML.
And thirdly, you probably wouldn't want to pass the equipment ID as an HTML attribute inside your form tag. You should rather create a hidden form field inside your form body and set the name to equipmentID, and the value to the variable's value. The way you are currently using it will add an HTML attribute to the form tag, and your generated code will look something like this:
<form action="/ReservationList/CreateReservation" method="get" equipmentID="1">
And this extra attribute will not be retrievable in your code. Rather do something like this in your view:
#using (Html.BeginForm("CreateReservation", "ReservationList", FormMethod.Get, new { name = "myFormName", id = "myFormID" }))
{
#Html.Hidden("equipmentID", ViewData["equipmentID"])
<button class="btn btn-blue">Click</button>
}
I am using ASP.NET MVC 3, with the Razor engine. I have a partial view that contains one line:
#Html.ActionLink(ViewData["UserNameIfLoggedIn"], "Index", "Home")
This partial view is rendered in my _Layout.cshtml view. The snippet that calls the controller/action is this:
#{Html.RenderAction("UserLoggedIn", "User");}
I get a compilation error, stating:
'System.Web.Mvc.HtmlHelper' does not contain a definition for 'ActionLink' and the best extension method overload 'System.Web.Mvc.Html.LinkExtensions.ActionLink(System.Web.Mvc.HtmlHelper, string, string, object)' has some invalid arguments
I have made a similar call (same amount of arguments and same parameter datatypes) in another MVC application (a tutorial) and it executed just fine. What could be causing this?? Why is this not working now?
I know this is probably an extremely rookie MVC question, but I cannot figure this one out.
EDIT: The solution is this:
#Html.ActionLink(ViewData["UserNameIfLoggedIn"].ToString(), "Index", "Home")
I just needed to call the ToString() method to get the parameter as a string.
You need a string as your first parameter in ActionLink, I am not sure but I think ViewData is a dictionary.
Try this just as a test
#Html.ActionLink("test", "Index", "Home")
If that works, then you need to loop through ViewData and get all the single values, and pass them as string. I am not sure what is your ViewData, though.
If you want just a single value, use ViewBag instead.
http://brendan.enrick.com/post/Difference-Between-ViewBag-and-ViewData-in-MVC-3.aspx
It's because ViewData / ViewBag is a dynamic that has no idea what type of data it holds, you need to unbox into a local variable before trying to use it
#{ var foo = ViewData["Title"]; }
#Html.ActionLink(foo.ToString(), "Index", "Home")