ViewBag doesn't load - razor

I'm beginning to learn ASP.NET MVC 5, and I'm just trying to make random things to get myself familiar with the system. I tried executing the following code in a standard environment (more or less exactly what you get when you load of a new blank project), but some reason I can't pass a string to my ViewBag properly.
Controller
public ActionResult News(String date)
{
ViewBag.Message = Server.HtmlEncode(date);
return View();
}
View
#{
ViewBag.Title = "News";
}
<h2>News</h2>
<div class="jumbotron">
<h1>#ViewBag.Message</h1>
<p class="lead">This is my new website. I hope that I learn to develop the appropriate skills to create it.</p>
</div>
Some reason it just doesn't show anything for the area where I designated the ViewBag message to go. What's up with it?
Also, as I curiosity question, I noticed some code where they use things like "class = "btn btn-primary btn-lg"" but I couldn't find anywhere that they actually defined the class. How does this work and where is the class declaration?
Thanks for your time!
EDIT: OK, my mistake was pretty stupid. I forgot that you need to pass ?date= when the variable isn't named id.
I see in the comments that the "btn" class is a CSS class not a C# one, but nonetheless, where would I go if I wanted to edit it and/or make my own similar classes?
Thanks again!

I would suspect that the date parameter your passing through is not been matched by the Action method.
Simply Debug you code and check the value of date before it is assigned to the Viewbag.
Also, you could show the code that calls the 'News' Action Result.

Related

Add components based on string variables in Blazor

We're creating a dynamic page of components in Blazor. The intention is to have dynamic applets displayed on a page. The idea is that we have a list of strings which correspond to Component names. We read through the string list and for each one, instantiate a blazor component or render fragment. These are just simple components, no passed in parameters or the like. ie:
string[] componentsStrings = {"Component1", "Component2"};
Expected output:
<Component1 />
<Component2 />
We can't come up with a way to do this. It seems like a fairly standard thing to do, but perhaps not? Does anyone know if this is even possible?
You will have to programmatically create a component which adds your custom components on the page using RenderTreeBuilder.
Chris Sainty has a blog post on this which you can read here: https://chrissainty.com/building-components-via-rendertreebuilder/
Basically there is an override for BuildRenderTree in the ComponentBase class which can be used:
public class Menu : ComponentBase
{
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
base.BuildRenderTree(builder);
builder.OpenElement(0, "nav");
builder.AddAttribute(1, "class", "menu");
}
}
Here is another tutorial.
Some tips from here:
Place base.BuildRenderTree(builder); at the start of the
BuildRenderTree method , not at the end.
Always start with the value 0 for the sequence parameter.

table division text dissapears after validation is run on submit

In my razor page I've got several check boxes arranged in a table. I've got some other #Html.EditorFor elements that are required inputs. When I submit, and the validations are run, the page refreshes with the eoor messages and the text next to my check boxes in the table disappears. What's up with that?
My checkboxes are made with #Html.CheckBoxFor
I'm not using any special stylings or class attributes or anything right now.
You are correct. When the form is posted, you will lose all of that data provided you do not resend it back into your view. In your controller, you need to return the model along with the view. Without seeing your code, I can't give a specific answer but it should look something like this:
public ActionResult DoSomethingWithFormPostData(Model yourModel)
{
//Do whatever you need to do.
return PartialView("_yourView", model);
}
Alternatively, I like to have a method in my controllers to I use for the sole purpose of populating a page. If you have something like that, you can refer back to that sending the model as a routevalue in this way:
public ActionResult DoSomethingWithFormPostData(Model yourModel)
{
//Do whatever you need to do.
return RedirectToAction("_yourView", "YourController", model);
}

Simplifying ASP.Net MVC Razor Code

I'm looking for suggestions on how to simplify/optimize a piece of code in one of my view files in my ASP.Net MVC project. The code works, but I'm not sure if I've written it the best way.
Basically, the code is used to display a list of links to documents, with little thumbnails to the left of each link. The main problem, is that there are two different types of documents, and each type has to have it's thumbnail image stored in a different location, this is a project requirement and can't be changed.
I'm currently accomplishing this with the view code shown below.
// Display a link to every document.
foreach (var document in documentList)
{
<a href="#Url.Content("~/Document/DownloadDocument/" +
document.documentid)" target="_blank">
#{
// This will be the root of all the paths.
var path = "~/Document/DisplayImage/";
// If it's a Type 1 document, we need to use a different path.
if (document.documentType == "Type 1") {
path += "Path/To/Image/Folder";
<img id="imageHolder" src="#Url.Content(path)"
onerror="imgError(this);" />
#document.documentname
}
else {
path += "Path/To/Different/Image/Folder";
<img src="#Url.Content(path)" />
#document.documentname
}
}
</a>
<br />
}
Like I said, the code works, but I'm not too happy with how it's written. Does anyone have any suggestions?
When working with MVC, it's best to keep your Views dumb (no logic, simply rendering).
You can accomplish this by using a strongly-typed View and performing all of the logic in the Controller. It looks like you may already be doing this since you have a documentList.
In this case, documentList should be a list of View Model objects that already have the appropriate image path already set on them from the controller.
I would suggest moving the path to your document image into your model. That way you can just display the image from the path in the model and you wouldn't have to put any logic in your view.

Binding dynamically within an ng-repeat expression

For a TV Guide, I am trying to create a dynamic expression within an ng-repeat directive as follows:
<div ng-repeat="programme in programmes['{{channel}}-wed-jan-14']" alt="{{channel}}">
{{channel}} in my controller should evaluate to something like "eTV". The binding is working fine with the alt="{{channel}}" instance but not with the array instance. Angular simply serves up the line of code commented out. If I hardcode the "eTV" string in place of the {{channel}}, it works fine.
Am I trying to ask Angular to do what it is not designed for, or is it possibly my array handling which is dodgy?
Okay, not sure if I just asked a dumb question, but in the absence of responses, I managed to figure out a solution by writing a filter as follows:
Template:
<div ng-repeat="programme in programmes | getChannelDay:channel:dayString" alt="{{channel}}">
Controller filter:
app.filter('getChannelDay', function() {
return function(programmes, channel, dayString) {
return programmes[channel + dayString];
};
});
The issue with my initial problem
<div ng-repeat="programme in programmes['{{channel}}-wed-jan-14']" alt="{{channel}}">
is that I was trying to put {{channel}} inside the expression, but that is the format for markup.
I tried to use the following instead:
<div ng-repeat="programme in programmes['channel + daystring']" alt="{{channel}}">
but I am doing something wrong here. I am pretty sure there is a way to get this to work - if anyone knows, please comment.

MVC Razor view make image invisible based on model item condition

I have some razor code like:
foreach (var item in projectGroup) {
<tr>
...
<td>
<label id="#( "fieldapprovallabel" + #item.InvoiceLineId)">#item.FieldUserName</label>
#if(item.FieldApproved != null) {
<img src="../../Content/Images/stock_lock.gif" alt="locked" class="lockicon" />
}
</td>
...
}
So basically the lock image is only visible based on a condition. I understand it is not good to have logic like this in the view. Can anyone suggest a better way of doing this?
I don't believe there is anything wrong with simple boolean logic or null checking in the view.
The only alternative would be to hide it all in some helper class that would return the html (or an empty string), which I think adds unnecessary complexity in a simple case like this.
You could create a view model with a property called IsLocked. This abstracts the business logic used to make the "IsLocked" determination, and doesn't state how the view should behave, just informs the view that the item is in a particular state.
The subsequent binding code would be similar, but doesn't require the view to know that item.FieldApproved equals a locked condition.
Of course, in the context of your application item.FieldApproved may already be a clean separation of concerns, in which case I think it's fine as is.