How does partial views work? - asp.net-mvc

In a MVC master view I have this:
#Html.Partial("_CreateOrEdit", Model)
and the partial view _CreateOrEdit contains this code block:
#{
var item = Model;
.
.
.
string favouriteId = "fav_" + item.Id + "_comment";
}
Despite ensuring that item.Id > 0 I get a null reference error in pointing at the declaration of favouriteId. The dots mean there are many other similar declarations all with non null reference.
When I replace item.Id by #item.Id, rendering the partial views fail in the master view.
What am I doing wrong? Can someone point to a complete tutorial on code blocks please?
Thanks

Another '#' cannot be used since the statement is already within the razor code block.
In order to avoid the object reference exception, use the below code
string favouriteId = string.Format("{0}_{1}_{2}", "fav", item.Id, "comment");

Related

"No route in the route table matches the supplied values." Error thrown on one view only

I came across a strange problem in my project today: I use this action throughout my website to generate breadcrumbs for a given page:
#Html.Action("BreadcrumbsWithHeader2", "SharedElements", new { pageName = #Model.pageName, department = #Model.department, menuHeading = #Model.menuHeading, id = "EandTHeader" })
Where it just returns a PartialView. This works great on every page except for one, where it began throwing this error:
No route in the route table matches the supplied values.
I've checked for things like spelling errors, etc., but am not sure how to debug this any further. What could cause something in the route table to go missing?
Edit: I've just noticed that any and all ActionLinks on the website pointing to this page (not the #Html.Action shown above, but rather the view where I call this partial) are producing blank href tags. The controller for it (if this helps) is here:
[Route("JobFair/FindAJobFair/{area}")]
public ActionResult FindAJobFair(string area, string sideMenu)
{
ViewBag.sideMenu = sideMenu;
JobFairsViewModel jobFairInfo = new JobFairsViewModel()
{
department = "Foo",
menuHeading = null,
pageName = "Job Fairs"
};
return View(jobFairInfo);
}
This route is typical of what I use elsewhere on the site (attribute routing).
Do you always provide a value for sideMenu? If you don't that may cause your problem. Try to modify your controller like this:
[Route("JobFair/FindAJobFair/{area}")]
public ActionResult FindAJobFair(string area, string sideMenu = null/*default value*/)
{
ViewBag.sideMenu = sideMenu;
JobFairsViewModel jobFairInfo = new JobFairsViewModel()
{
department = "Foo",
menuHeading = null,
pageName = "Job Fairs"
};
return View(jobFairInfo);
}
Hopefully this answer helps someone in the future - the problem had to do with my variable name area that was passed into the controller. Since my project has an 'Areas' folder it was causing an issue with routing. I simply needed to change area to something like region and the issue was solved.

loop through model in mvc razor code behind

I am working on MVC4 App, and I am stuck at one point, I tried using google to help me, but without success. This might be more simple then I think, but coming from web forms and shifting to mvc is "painful" sometime.
I am trying to loop through the model I have and get the values stored in that model. I tried few approaches but I am getting an error everytime. This is what I have:
var modelAgentFilter = from s in _aa.Agents
where s.COUNTER == Convert.ToInt32(AgentID)
select s;
if (modelAgentFilter != null)
{
ViewBag.FirstName = // Get FirstName object here
}
Thanks in advance for your comments.
Laziale
EDIT:
I did include for loop like this:
if (modelAgentFilter != null)
{
foreach (var property in modelAgentFilter)
{
string test = property.ADDRESS;
}
}
But when the compiler will reach the foreach step I am getting this error: "LINQ to Entities does not recognize the method 'Int32 ToInt32(System.Object)' method, and this method cannot be translated into a store expression."
I can get to the properties of the var model using that foreach look but as soon as the compiler will try to loop the model that error pops up.
Thanks again
LINQ to Entities does not recognize any methods. You can't use even ToString() in LINQ expression. You need first convert your value and than add it in LINQ.
In your example you need to do something like following:
var _agentID = int.Parse(AgentID);
var modelAgentFilter = from s in _aa.Agents
where s.COUNTER == _agentID
select s;

Building a URL with ActionLinks from within a Controller in MVC

I'm building a basic flashcard application - a Set contains Cards and other Sets. When navigating to something like Set1 > Set2 > Set3, I want each of the parent "Sets" to link to their respective details page. I'm passing the Details viewModel a string called "breadcrumbs", which contains something like this:
var stringBuilder = "";
var parent = model.ParentSet;
while (parent != null)
{
stringBuilder += "<li><a href=\"#Url.Action('Detail', 'Set', new {SetId = \" + parentSetId + \"}, null)'>" + parent.Name + "</a> <span class='divider'>/</span></li>";
parent = parent.ParentSet;
}
model.Breadcrumbs =
"<li>Home <span class='divider'>/</span></li>" +
stringBuilder + "<li class='active'>New Set</li>";
model.Name = "New Set";
The URLs being generated are literal though - containing "#Url.Action".
Does anyone know how I can get this to work, or if there's a better way to do it?
Just evaluate it:
"<li><a href='" + Url.Action('Index', 'Home') + "'>..."
I think an important question here is, "What does your view look like?"
If your view is using that model.Breadcrumbs field like this:
...
<div id="breadcrumbs">
#model.Breadcrumbs
</div>
...
The #Url.Action call in the string you've built will never be executed. The Razor engine operates on the code it finds in the view file, not on fields within the model.
You need to do one of two things:
Rather put "#Url.Action(...)" into the string you're constructing, figure out what the Url is on the server side using something like Url.Link() and insert that directly.
(and this is better) Pass those parents to the view as part of the view model and loop over them in the view, constructing the tags as you go. Normally you don't want to put html into a model. The model's there to hold data, not presentation code.

Perfomance issue - .Count in MVC view

For several pages I use a .Count inside a foreach loop
#model ICollection<Item>
foreach(var item in Model)
{
#item.Flight.FlightReservations.count
}
Because of lazy loading the EF makes a round trip to the database for this.
Now I want to fix this by using this or linq version:
Include("List.Flight.FlightReservations")
Doing this makes loading my dbSet take even longer than those foreach round trips
How can I 'load' parts of only 1 object?
I would like to use context.Items.Single(p => p.id == id).Include(.....)
So I only load 1 item fully.
Or any other solutions for this?
(A way to force load item.List.item2.List inside controller)
Any suggestions are welcome :) Thanks
EDIT : now using
Where(..).ToDictionary(item => item, item => item.Flight.FlightReservations.Count);
Also noticed adding an index to my 'clustered index' table helped a little.
Still slow though
var f = _pr.FindBy(duifid);
var result = (from p in f.IngeschrevenVluchten
select new PrestatieModel
{
Eindpos = p.Eindpositie,
Locatie = p.Vlucht.Locatie.Naam,
AantalInschrijvingen = p.Vlucht.Inschrijvingen.Count(),
Vlucht = p.Vlucht
});
This query executes very fast, making a IEnumerable<Model>. But still it loads very slow once sent to the view.
return PartialView(result);

will asp.net mvc model binder keep a posted array in the proper order?

so i've got an array of numbers that i'm posting to an asp.net mvc action that has a list(of integer) parameter and it all works great.
my question is this:
Is it safe to assume that the list(of integer) will have the numbers in the same order as they were in the array i posted?
Thanks for your time!
EDIT:
The data being posted looks like this:
POSTDATA=model.LevelIds=6&model.LevelIds=19&model.LevelIds=16&model.LevelIds=21&model.LevelIds=18
I'm using the Tamper Data firefox add on to see it.
I'm using jQuery, in traditional mode.
EDIT:
the action looks something like this:
public function Create(byval model as thecreateviewmodel) as actionresult
the thecreatviewmodel has a bunch of properties, but the interesting one is...
Public Property LevelIdsAs IList(Of Integer) = New List(Of Integer)
on the client side the view model is build with javascript/jquery:
function NewEntityDataBuilder() {
var theData = {
'model.Name' : $('#Name').val(),
'model.Description' : $('#Description').val(),
'model.LevelIds' : $('#LevelIds').val()
};
return theData;
}
that function is called from this bit of javascript which basically goes through the and adds all of the things in the list to a drop down list (select control) and selects them all.
$('#LevelIds').empty();
$('#AddedLevels').children().each(function () {
$('#LevelIds').append("<option value='" + $(this).attr('LevelId') + "'>" + $(this).attr('LevelId') + "</option>");
});
$('#LevelIds').children().attr('selected', 'selected'); //select all the options so they get posted.
var dataToPost = NewEntityDataBuilder();
this seems fairly convoluted when it's put this way, but it's actually fairly simple. it's all part of 2 connected drag and drop lists that are part of a form.
so: if i put the value of a select list with all of it's options selected in a variable and post that to an ilist(of integer) will ilist have them in the same order as they were in the select. It SEEMS like they are. but is that just a coincidence?
Usually the index is part of the parameter name:
ints[0]=0&ints[2]=2&ints[1]=1
And if you have a controller action that looks like this:
public ActionResult Index(List<int> ints)
{
// ints[0] = 0
// ints[1] = 1
// ints[2] = 2
return View();
}
UPDATE:
Let's suppose that you have multiple parameters with the same name in the query string. This query string will be parsed by the ASP.NET engine by the native HttpRequest object be convert into a NameValueCollection and more precisely a custom implementation called HttpValueCollection. This class is internal to ASP.NET which means that it is not documented and it might change with versions of .NET. Looking at it with Reflector there is the FillFromString and the way it is implemented it seems to preserve the order. But this is something I wouldn't rely on.

Resources