object does not contain definition for pageNumber - asp.net-mvc

I am trying to simply run a foreach loop inside my view of my MVC application. But, in debug mode I can see it got the list successfully. However, I get an error saying object does not contain definition for pageNumber. Please, note pageNumber is available on each of those list. What am I doing wrong?
MVC View code:
#foreach (var button in ViewBag.PageButtons)
{
<li class="page-item"><a class="page-link" href="#">#button.pageNumber</a></li>
}

Your error dialog and the message show the type of button is an object in the View. As the error states, the .NET object does not contain a definition of pageNumber indeed. In the View, you need to cast button to your type.
The new code may look like this (CRLFs are for readability):
#foreach (var button in ViewBag.PageButtons)
{
<li class="page-item">
<a class="page-link" href="#">
#(((YourClassNameHere)button).pageNumber)
</a>
</li>
}
You need to replace YourClassNameHere with whatever class name you used to define an element of the list you send to the View.

ViewBag is dynamic, so you'll need to cast your button for the call to .pageNumber to work:
#((button as PageButton).pageNumber)
or
#(((PageButton)button).pageNumber)

Related

Is it ok to put controller name as string?

I was wondering if is it OK to put the controller name as a string, like in the following example.
Also, should I put the action as a string instead?
Is there any better approach?
My concert is that if I change the controller's name for any reason, my best option is to do a "find-replace" in the whole project as it is now.
Many thanks!
In general, we directly use the name of the controller and action as strings, as shown below:
(However, this wording cannot be changed automatically after you change the controller name, you need to modify manually)
<a class="nav-link text-dark" asp-controller="Operation" asp-action="Index"> </a>
1. According to your current wording, you can update the code as follows:
(This will change dynamically as you change the name of the controller)
<a class="nav-link text-dark" asp-controller="#nameof(OperationController).Replace("Controller","")" asp-action="#nameof(OperationController.Index)"> link </ a>
2. As an alternative solution, you can add the Route attribute to the action specified by the a tag and set the route name.
In the a tag, you only need to use asp-route to link the corresponding action.
Please refer to this.
<a class="nav-link text-dark" asp-route="MyRouteName"> link </a>
Controller:
public class OperationController: Controller
{
[Route ("CustomControllerName/Index", Name="MyRouteName")]
public IActionResult Index ()
{
return View ();
}
}
Yes, that is exactly how you use the anchor tag helpers. At least to me that asp-action seems convoluted and I would simply have written it as:
<a asp-controller="Operation" asp-action="Index">...</a>
If you do change your controller name (which should not happen very often), then you would have to update the links.
For further reference see https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/built-in/anchor-tag-helper?view=aspnetcore-3.1: "If the asp-controller attribute is specified and asp-action isn't, the default asp-action value is the controller action associated with the currently executing view. [...] If the asp-action attribute value is Index, then no action is appended to the URL, leading to the invocation of the default Index action. The action specified (or defaulted), must exist in the controller referenced in asp-controller."

How to send number with country code to url of browser from mvc application

I Wrote this code in view
#foreach (var item in Model.CDR)
{
<tr>
<th>
<a class="facebook" rel="nofollow" target="_blank" href="https://www.facebook.com/search/top/?q=#item.BNumber">Facebook</a>
<a class="facebook" rel="nofollow" target="_blank" href="https://www.truecaller.com/pk/#item.BNumber">True Caller</a>
</th>
When I click on this number,
it gets automatically send to url and
url automatically identify this number's country code ...
My Problem :
When I send the number Url is not identifying its country code.
Tell me how is it possible ?
The first few things to check would be the standards, how are you passing this modal. In the controller or do you have a separate ViewModel class?
Something you might want to add is a check
Assuming Model.CDR is a List or Enumerable
Another thing you should do is have the type of CDR.
Easiest way to do this if you are struggling is (If using Visual Studio) put a break point in at the #foreach line and in your watch, call Model.CDR to see what type it is passing back.
That will allow you to strongly type it in your foreach statement, makes the whole thing a heap easier.
#if (Model.CDR.Length != 0)
{
#foreach (object //CHANGE OBJECT TO YOUR TYPE// item in Model.CDR){
}
}
If you send in a little more info on what your Model looks like, how the CDR object is constructed I could help you a little more.

Accessing a single value using foreach loop in view coming from the view model in durandal

I have a Project Title, what I want to do is when I click on the title, all of the associated activities are displayed, I have an API, which brings all the associated activities,API is developed in YII framework, the API is called in view model and all the activities are accessible in the view through foreach loop, what I want to do is to display a single activity a time, at the moment when i click on project title, all activites are displayed, I want one activitiy to be displayed when clicked once. Please if any one can answer.
this is my viewModel...
function fetchProjectActivities() {
var self = this;
// this.current_activities.length=0;
dataservice.projectactivities(self.id()).then(function (data) {
//self.current_activities().clear();
for (x in data) {
self.current_activities.push(new Activity(data[x].activity.id, data[x].user_id, data[x].user.first_name, data[x].user.last_name, data[x].activity.message, new Date(data[x].create_date), data[x].time_spent, data[x].tags, null, data[x].activity.status,
self.name()));
}
console.log("aaa" + self);
});
}
and this is my view...
<div class="grid-item project-item clearfix">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12"><h3>
<div data-bind="foreach:projects">
<div data-bind="foreach: current_activities">
<span data-bind="text: title()"></span>
</div>
</div>
</div>
</div>
and here is the function which gets invoked when I click on Projects title.
Project Name: <a data-bind="click: $root.fetchProjectActivities"><span data-bind="text: name()">
There are a couple of thing that I can see.
there is a rogue <h3> tag in the html that will cause grief with knockoutjs. that will need to be closed or removed.
the for loop in the view model really should be for (var x in data) {...} otherwise you will end up with x declared as a variable on the global scope.
Now to cycle through the activities of the project, what you are effectively doing is paging through current_activities array, one at a time. You will need to keep track of the currently selected activity and a way to go forward with each click and a list of all the activities.
so you will need a pager view model. there is a very basic one on the knockoutjs site that you could use and modify to your needs.

ASp.NET MVC 4 RAZOR - Best way to create a search page

I have a search page using MVC4 with Razor. Details as bellow:
Whole page is divided in to two part.
Left panel contains total 5 search section like search by product, search by city etc. Each section have check box list. So user can select multiple option from each section.
Search panel is a partial view with a submit button. As given below
#using (Html.BeginForm("ModelsList", "Model"))
{
<div class="ModelListSearch
Panel" style="width: 309px; float: left">
<div class="heading">
By Budget
<div class="clear">
</div>
</div>
<!--heading-->
<ul>
#{
for (int i = 0; i < Model.BudgetDescription.Count; i++)
{
<li>
#Html.HiddenFor(m => m.BudgetDescription[i].BudgetId)
#Html.HiddenFor(m => m.BudgetDescription[i].Description)
#Html.CheckBoxFor(m => m.BudgetDescription[i].Selected)#Model.BudgetDescription[i].Description
</li>
}
}
</ul>
Action methods are as below
public ActionResult ModelsList(int? brandId, int? bodyStyleId, int? fuelTypeId, int?
transmissionTypeId, int? budgetID)
{
// this is called when first time page is loaded
}
[HttpPost]
public void ModelsList(NewCarSearchContainer searchData)
{
// this is called on click of search button
}
On click of search button search result is shown in right panel.
When we click on search button it post whole search object (NewCarSearchContainer) to action method & we find out the selected item from this object & get data from DAL layer accordingly.
This page is working fine BUT problem is that URL does not updated as per user selected search option. I think as we are using post it does not update url. We can not used GET as GET pass all check box item as query string header which has a specific limit.
One option is using action link instead of submit button. But in that case i dont know how pass selected item of search panel to action method.
We need to updated URL as per selected search option to optimize SEO.
Please take a look of Datatable Jquery Grid. Click Here.

Removing items from list in form in ASP.NET MVC without using JS

I am trying to implement a form with a list of parameters which can be added and removed by the user. The catch is that I want to do this without javascipt. This is to be done in ASP.NET MVC 3.
I have a form like this (simplified code, so might not be quite right, it is just to illustrate what I have got):
#using (Html.BeginForm("New", "Films", FormMethod.Post, new { id = "NewFilmForm" }))
{
#if (Model.Any())
{
<!-- List of directors that have already been added -->
<div id="AddedDirectors">
#foreach (var director in Model)
{
<span>
#Html.Hidden("AddedDirectors", #director)
#Html.Raw(director)
<!-- JQuery button to remove director -->
<button class="deleteButton" type="button">x</button>
</span>
}
</div>
}
<!-- Interface for adding a new director -->
<div id="AddDirectorInterface">
<!-- Jquery show/hide add single director interface -->
<button type="button" id="AddDirectorButton">+ &nbsp Add a director</button>
<div>
#Html.TextBox("AddDirector")
<!-- Post add button -->
<button name="SubmitButton" value="#Html.Encode(NewFilmActions.AddDirector)">Add</button>
</div>
</div>
<button type="submit" name="SubmitButton" value="#Html.Encode(NewFilmActions.Save)">Save film</button>
}
I have two submit buttons here. Which are handled via a switch statement in the controller and identified via the value attribute which is set based on the NewFilmActions Enum.
Pressing the button with the AddDirector value posts to the controller, adds the name entered in the AddDirector textbox to the model and returns the view with the form again, adding the name specified by the user to the list of directors which have already been added (see commented section).
I would like to add a button allowing me to delete names which have already been added by the user...
I could put in one single button to delete all of them in one go very easily, but if posible I would like to add individual buttons. I can't figure out how to do it though.
One solution I can think off would be to append the name to the value and then in the switch statement have a default and check if the value contains a specified enum value, but that sounds a little like a botched together approach.
Can anybody either tell me how to do this or point me to some tutorial/explanations on how to implement this?
Just to emphasize: I know this can easily be done using JS, but I am looking at doing this entirely serverside for basic functionality and for my personal education.
I think you should reduce the scope of your form so it doesn't include the list.
Then you can put delete forms within you for loop, as shown below;
#foreach (var director in Model)
{
<span>
#Html.Raw(director)
#using (Html.BeginForm("Delete", "Films", FormMethod.Post, new { id = director.Id })){ <button name "DeleteButton" value="Delete">Delete</button>}
</span>
}
An example of this is also shown in this blog

Resources