Model does not contain a definition error - asp.net-mvc

I am having an issue in my project and wonder if some can pinpoint me to where i may have gone wrong. so basically in my project i have got an ActionResult method like so:
public ActionResult PartNumberManufacturer(string id)
{
var partNumber = _Context.PartNumberTable.FirstOrDefault(x => x.partNumberId == id);
return PartialView("PartNumberView", partNumber);
}
Then this is my view
#if (Model != null && !string.IsNullOrEmpty(Model.PartNumberManufacturer))
{
#if (Model.PartNumberManufacturer == "Fr")
{
<div>
<p> This product is developed in france </p>
#if (#Model.PartNumberManufacturer == "Ger")
{
<p> This Product is developed in Germany </p>
}
well the above code works fine. but the thing is that if you look back into my ActionResult controller method , i am using :
var partNumber = Context.PartNumberTable.FirstOrDefault(x => x.partNumberId == id);
FirstOrDefault of-course will only return the first found part number in the database.
This isnot what i am looking for i don't want it only to return the first found record , i want it to return all the records that match by the search query in the database. So in order to do and after a few research online i found that i had to return the results into a list and this made me amend my ActionResult method to like this:
public ActionResult PartNumberManufacturer(string id)
{
var _methodOfRepair = Context.PartNumberTable.Where(x => x.PartNumberId == id); // changed thisline
return PartialView("PartNumberView", partNumber);
}
so yeah i get the error message saying that:
{"'System.Data.Entity.Infrastructure.DbQuery' does not contain a
definition for 'PartNumberManufacturer'"}
i made those changes. what am i doing wrong here? or is there a different approach i can be recommended to in order to achieve this?
thank you for your time.

First recommendation, read about implementing the repository pattern.
Second, if you are sending a collection of objects to your View then your View need to be expecting that data type. Change the Model data type that your View is expecting.
Inside your View, you should iterate over every element and render it.

Related

Multiple searching in Asp.net (entity framework) with multiple search boxes

ImageI'm having a problem to develop a form that can be search by multiple search boxes.....when i'm trying to search name and email together ActionResult...compiler says both linq queries cannot be applied with && operator..i don.t know why...
[HttpPost]
public ActionResult Login(string search,string search2)
{
var obj = db.Emps.Where(x => x.Employee_name.StartsWith(search)) && db.Emps.Where(x=>x.Employee_email.StartsWith(search2));
return View(obj);
}
You need to use both conditions inside single Where
[HttpPost]
public ActionResult Login(string search,string search2)
{
var obj = db.Emps.Where(x => x.Employee_name.StartsWith(search) && x.Employee_email.StartsWith(search2));
return View(obj);
}
If you look at your current code, the first part db.Emps.Where(x => x.Employee_name.StartsWith(search)) is going to return a collection, IQueryable<Emp>
and the second part of the expression will also return the same type, IQueryable<Emp>.
So your code is basically trying to execute/compile the expression IQueryable<Emp> && IQueryable<Emp> and since it is not valid, the compiler is telling you that it is not valid.
Ideally, you should have both of your WHERE condition predicates inside the same Where method.
var obj = db.Emps.Where(x => x.Employee_name.StartsWith(search)
&& x.Employee_email.StartsWith(search2));
Keep in mind that, the variable obj is still of type IQueryable<Emp>. If you want to execute your LINQ query, you may call the ToList() method.
List<Emp> = db.Emps.Where(x => x.Employee_name.StartsWith(search)
&& x.Employee_email.StartsWith(search2)).ToList();
If you make the above change, make sure your view is strongly typed to List<Emp> instead of IQueryable

List<class> does not contain a definition for 'property'

So I'm trying to make a simple MVC system that will search through a database of books by author and/or title. I have a model called Book.cs with title and author properties. In my controller I made an ActionResult as follows:
public ActionResult Search(string theAuthor, string theTitle)
{
if (theAuthor == null && theTitle == null)
{
ViewBag.title = "Search for a book by author and/or title";
}
else
{
ViewBag.title = "Results:";
}
List<Book> allBooks = db.Books.ToList();
List<Book> booksFound = new List<Book>();
foreach (Book theBook in allBooks)
{
if (theAuthor != null && theTitle != null)
{
if (theBook.author == theAuthor && theBook.title == theTitle) booksFound.Add(theBook);
}else if (theAuthor == null)
{
if (theBook.title == theTitle) booksFound.Add(theBook);
}else if (theBook == null)
{
if (theBook.author == theAuthor) booksFound.Add(theBook);
}
}
return View("Search", booksFound);
}
Now, this returns a List of books, so I assume that in my view I have to use List<Book> model, and so I did (#model List<Book>). But the problem is how am I going to send data to the action result? I tried using
#Html.TextBoxFor (x => x.author)
But that gives the
'List<Book>' does not contain a definition for 'author' and no extension method 'author' accepting a first argument of type 'List<Book>' could be found (are you missing a using directive or an assembly reference?)
error. Now that makes sense to me because I guess I can't access model class property if my model is a list. So am I doing something wrong or I should use another way to pass data?
Thanks
I didn't get your question when you said "But the problem is how am I going to send data to the action result?" but as much as I could comprehend from your question it seems you want to iterate the model which is a list of 'Book' objects inside MVC view. Controller has passed that list to your view as a model and then you want to create some UI elements based on the elements in the list. Here is how you can do it:
#for (int i = 0; i < Model.Count; i++)
{
#Html.TextBoxFor(x=> x[i].author)
}
To answer your other concern, there is absolutely no error in the way you have passed the model (which is a list) from controller to view but you were trying to access the author property on the list itself when it is available on the list elements. Hope this helps!

OrderByDescending doesn't exist?

I am not sure this is an error in my code or maybe something else messing with it however I have a function were I am creating a simple list from a MVC model in an ActionResult I have others that use OrderByDescending and work but this is throwing an error for some reason.
[Authorize(Roles = "Administrator, Manager, User")]
[SessionExpire]
public ActionResult PrepareShipment(int id,string sortOrder)
{
//ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
//ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
Order orderResult = (from o in db.Orders.Include("OrderItems").Include("OrderItems.Item")
where o.OrderID == id
select o).First();
orderResult = orderResult.OrderByDescending(o => o.Item.ItemName);
return View(orderResult);
}
That is my complete ActionResult the database has a table Order with another object called Item that object has a column called ItemName. I already have a view with a list in it done exclusively in the view but now I have to order that data by the item name. This is so every time an action is done on the page the list stays in the same order as when it first loaded. Right now every time I reload the page the list reorders.
Ok so I solved this in the foreach which I realize now I should have included in the original post
the orginal for each was this
#foreach (OrderItem item in Model.OrderItems) {
I fixed it by doing this to the foreach
#foreach (OrderItem item in Model.OrderItems.OrderBy(m => m.OrderItemID)) {
I never even knew you could add additional information like that to a foreach in c#
Thank you everyone for you patience with me :D

Asp.Net MVC 5 Restriction

I want to make a simple message system.In messaged table there are three significant columns which are;
ID of the message
Sender's UserId
Receiver's UserName
I am getting the message's id from url and checking whether the logged in user is sender or receiver of that message. If not, i don't want them to see the message.
public ActionResult Details(int? id)
{
var result = db.Talep.Where(e => e.ID == id && (e.UserId ==
User.Identity.GetUserId().ToString() || e.Receiver == User.Identity.Name));
if (result == null)
{
return HttpNotFound();
}
Talep talep = db.Talep.Find(id);
return View(talep);
}
The fallowing code is not working, result never becomes null even though the statement is wrong. I tryed to use .Any extension but it didn't work. I hope someone can help.
.Where is going to always return and IEnumerable, which will never be null.
There are 2 ways to handle this:
change your if to this: if (!result.Any()) This will check if there are any items in the return list - if there are no items, you will return your error.
change your LINQ query to use FirstOrDefault() This will return the first item that matches your request, or null if no items match.
Also a side not... If you use FirstOrDefault(), after the if statement to check for null, you will know you have a Talep, so the last call to look up the talep by ID would be a waste. Just return View(result)

Avoid to show Null or specific values to razor view engine

I am working on asp.net mvc3 web application using MS Sql server 2008 express rc2. In my app I have two different brands in DB and one of them have few Null or 'unknown' values (e.g. 'unknown' is added to DB instead of Null). My question is how to pass only non null values to View Engine instead of using If/Else statements in View?
in controller:
var model = _data.GetViewModel(query);
if (model != null)
{
return View(model);
}
else
return View("Error");
in ViewModel;
public int Id { get; set; }
public string Query { get; set; }
public string Brand { get; set; }
public string Family { get; set; }
public string Type { get; set; }
in Model:
public ViewModel GetViewModel(string query)
{
var data = _comp.Get(p => p.Query == query);
if (data == null) return null;
return new ViewModel
{
Id = data.id,
Brand = data.brand,
Family = data.family,
Type = data.type
};
}
in View (I am currently using If statement):
#if (Model.Brand != null)
{
<span class="brand">#Model.Brand</span>
}
#if (Model.Family != null)
{
<span class="family">#Model.Family</span>
}
#if (Model.Type != null)
{
<span class="type">#Model.Type</span>
}
Note: I want to avoid If statement because there are too many values in the Database of each brand, and many of the them are Null, So I don't want to generate Html for those Null values. I am using If/Else statement like above code, and for checking too many values in View using If, it costs Memory on server and processor, and it also slow down server response time.
I want to have an alternative method to do this. Should I use Partial views or anything else?
Please Please help me to solve this, Your help is very appreciated.
Thanks and Regards.
First, some background/context, then my suggestion.
(By the way, this all applies to any version of ASP.NET MVC or ASP.NET NancyFX (yes, there's another option out there!!), etc)
Context / Background
To solve this, people generally fall into two types of categories:
Just get data and let the View decide what to show (common one, not the proper way IMO).
The Controller should handle all the heavy lifting and give the view the exact answer (proper way, IMO).
The first way is quick and dirty. Sure it works, but it puts too much logic into the view. Views are not supposed to do any logic at all (exception: for loops, and maybe the odd if/else, maybe). The main reason for this is testing. Yep, that dirty word which people hate and think it's for hippies only. Or .. I don't have the time to test.. so I manually test, etc.. If you put any business logic into a view, you cannot test that.
The second way might seem a bit slower at first, but that's like anything - the more you practice, the faster you go. This is (IMO) the preferred method of doing things because you can test the controller. The controller should create a view model which will have -the exact- results that the view needs. Not extra. For example, imagine you want to return a list of Brands to the display/view. Most people do (the equivalent of) Get-all-brands into a list, and send that list to the view, even though 80% of those properties are -not- going to be used by that view! Even if ONE property is not going to be used by that view, do not retrieve it nor send it to the view!
So - TL;DR; do all the heavy lifting in the controller. The View is dumb. Just dump the exact view model data, to the view.
Solution to your problem
Ok, so let's roll with idea #2 and get all this stuff happening in the controller.
// Grab the results.
// ASSUMPTION: It is only returning the -exact- data I need. No more, no less.
var results = _data.GetViewModel(query);
if (model == null)
{
// Project the results into a perfectly tight & svelte view model
// 100% specific for this view.
var viewModel = results.
Select(x => new ViewModel
{
Id = x.Id,
Brand = string.IsNullOrEmpty(x.Brand)
? string.Empty
: x.Brand,
Family = string.IsNullOrEmpty(x.Family)
? string.Empty
: x.Family,
Type = string.IsNullOrEmpty(x.Type)
? string.Empty
: x.Type,
}).ToList();
return viewModel;
Testing this..
[Fact]
public void GivenSomeBrands_Index_ReturnsAViewModel()
{
// Arrange.
// NOTE: Our fake repostitory has some fake data. In it ..
// Id: 1, Brand: Gucci.
// Id: 22, Brand: null.
var controller = new BrandController(SomeFakeRepositoryThingy);
// Act.
var result = controller.Index(); // This calls that controller code, above.
// Assert.
Assert.IsNotNull(result); // Controller returned some result.
Assert.IsNotNull(result.Model); // We have some model data.
var model = result.Model as IList<ViewModel>(); // Cast the Model value.
Assert.NotNull(model); // We have a strongly typed view model.
// We check the first brand value.
Assert.Equal("Gucci", model.First().Brand);
// We know this item has a null Brand,
Assert.Equal(string.Empty, model[21].Brand); but the ViewModel converted it.
}
You could write a custom HTML helper:
public static string MyHelper<V>(this HtmlHelper helper, V value, string css)
{
if (value == null)
return "";
return String.Format("<span class='{0}'>{1}</span>", value, css);
}
Then in your view:
#Html.MyHelper(Model.Brand, "brand");
#Html.MyHelper(Model.Family, "family");
#Html.MyHelper(Model.Type, "type");

Resources