Not invocable Model Variable on controller Where Statement - c#

i have a really silly question but i cant find my self to know why Visual Studio give me this Error.
I maked a filter Text box in my View and i pass the String to my controller to make a where statement using one of my Model Strings and i get the error on my model String saying its not Invocable..
This is my View part of textbox
#using (Html.BeginForm())
{
<p>
Filtro Descripcion: #Html.TextBox("SearchString")
<input type="submit" value="Seach" />
</p>
}
This is my model:
public partial class Pos
{
public System.DateTime Fecha { get; set; }
public string Rid { get; set; }
public string Pdv { get; set; }
public string Pla { get; set; }
public string Descripcion { get; set; }
public decimal Total { get; set; }
public int Cantidad { get; set; }
}
This is my Context:
public partial class ArponClientPosContext : DbContext
{
static ArponClientPosContext()
{
Database.SetInitializer<ArponClientPosContext>(null);
}
public ArponClientPosContext()
: base("Name=ArponClientPosContext")
{
}
public DbSet<Pos> Pos { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new PosMap());
}
}
}
And this is my controller Index Method that give me the error on my where statement
public ActionResult Index(string searchString)
{
var db = new ArponClientPosContext();
var students = from s in db.Pos
select s;
if (!String.IsNullOrEmpty(searchString))
{
db = db.Pos.Where(s => s.Descripcion(searchString));
}
return View("~/Views/HomePos/Index.cshtml", db.Pos.ToList());
}
exactly this part : db.Pos.Where(s => s.Descripcion(searchString));
it says "Description" is not an invocable object
Can someone explain my why i have this problema or what did i did wrong?
Any help wil be apreciated

Are you trying to compare Descripcion to your searchString? Do you want something a perfect match? If so use .Equals(). If you want it to search Descripcion for anything that "Contains" that text then use .Contains. If you want to be type insensitive then use a .ToLower on both values within the Where.
public ActionResult Index(string searchString = "")
{
var db = new ArponClientPosContext();
var lowerSearch = searchString.ToLower();
var students = from s in db.Pos
where s.Descripcion.ToLower().Contains(lowerSearch)
select s;
return View("~/Views/HomePos/Index.cshtml", students.ToList());
}
The code I used to work this out.

Related

Pass parameter from Htmldropdownlistfor to controller

I have a model passed from controller to view in my asp.net mvc5 website. Then I show the dropdownlist using the model and I want to pass an id back when submitting the form. Here is my model :
public class SiteDirectionModel
{
public int id { get; set; }
public string name { get; set; }
}
Then in the model, I use a List<SiteDirectionModel> to which I add new instances of each item I need. I fill up both these lists and then pass my model to the view.
#model List<SiteDirectionModel>
#using (Html.BeginForm("GetSiteRF", "Create", FormMethod.Post))
{
#Html.DropDownListFor(x => x.name,new SelectList(Model.name,"Sites"));
<input type="button" value="Selectionner" class="btn btn-primary"/>
}
Then how to retrieve the ids for each name ? And how to pass it as a parameter to my controller? Such that I would have :
public ActionResult GetSiteRF(int id)
{
int newId = id;
//Call method to searchId ...
return View("CreateADUser");
}
I have given how to bind and get value from dropdown. Please use your own BL in this.
Your model should be like this.
public class Something
{
public int Id { get; set; }
public string Name { get; set; }
}
public class SiteDirectionModel
{
public SelectList MyDropDown { get; set; }
public int SelectedValue { get; set; }
}
You BL should be like this.
public List<Something> GetListofSomething()
{
//your logic.
}
Your Get method should be like this.
public ActionResult MyGetMethod()
{
SiteDirectionModel model = new SiteDirectionModel();
model.MyDropDown = new SelectList(GetListofSomething(), "key_field_name", "value_field_name", "default_value");
}
Then finally HTML
#Html.DropDownListFor(x => x.SelectedValue,Model.MyDropDown)

Search method by string value MVC 5

A a part of my project i need to find a way to search my object by a string and show a result in view. Your help is appreciated.
in my MainMedia view i have a sidesection were i manually pass a string value to a SearchMedia method:
#section SideBar{
<ul>
<li> #Html.ActionLink("Astronomy", "SearchMedia", new {searchString = "Astronomy" })</li>
<li> #Html.ActionLink("World", "SearchMedia", new { searchString = "World" })</li>
<li> #Html.ActionLink("Movies", "SearchMedia", new { searchString = "Movies" })</li>
</ul>
}
This method should check every object if TagsEnum string and then display an object in SearchMedia view.
Here is my Media class
public class Media
{
public int Id { get; set; }
public string title { get; set; }
public string description { get; set; }
public string body { get; set; }
public string ImagePath { get; set; }
public string VideoLink { get; set; }
public string Source { get; set; }
public string tags { get; set; }
public TagsEnum TagsEnum { get; set; }
}
TagsEnum Class
public enum TagsEnum
{
[Display(Name = "Astronomy and space")]
Astronomy,
[Display(Name = "World around us")]
World,
[Display(Name = "Movies, video")]
Movies
}
and finaly MediaMainController SearchMedia method
public ActionResult SearchMedia(string searchString)
{
db.Medias.Where(i => i.TagsEnum.ToString() == searchString);
return View(db.Medias.OrderBy(it => it.Title));
}
As i understand .Where() should find a match and return an object, however it is not working. How i can sort it out? Perhaps there are other ways to do it? Thank you
Update
I have changed it like this:
var result = db.Medias.Where(TagsEnum => TagsEnum.ToString() == searchString);
return View(result.OrderBy(it => it.title));
but i still dont see the results to be sorted by search
Update 2
I have a class MediaViewModel which i use to create a list of objects, it looks like this:
public class MediaViewModel
{
public List<Media> media { get; set; }
public List<Video> video { get; set; }
}
If i set up SearchMedia View like this
#model PhClub.Models.MediaViewModel
#foreach (var b in Model.media)
{}
i'm getting an error:
The model item passed into the dictionary is of type System.Linq.Enumerable+WhereListIterator 1[PhClub.Models.Media], but this dictionary requires a model item of type PhClub.Models.MediaViewModel.
If i set it up as
`#model IEnumerable<PhClub.Models.Media>
#foreach (var b in Model)
{}`
it is saying Values of type 'Media' can not be converted to string.
I think i need to change SearchMedia method to support MediaView class, but i didnt figure it out yet. Help is appreciated
You should assign it to a variable and use it,
var result = db.Medias.Where(i => i.TagsEnum.ToString() == searchString);
return View(result.OrderBy(it => it.Title));

Trouble with MVC 4 DropDownListFor

I am having trouble with displaying Dropdownlist in MVC 4 application.
It looks straightforward, However something is still missing which is not getting hold of.
ViewModel
public class vendorModel
{
public int vendorID { get; set; }
public int vendorTypeID { get; set; }
public string vendorName { get; set; }
public IEnumerable<vendorTypeModel> vendorTypes { get; set; }
}
public class vendorTypeModel
{
public int vendorTypeID { get; set; }
public string vendorTypeName { get; set; }
}
Controller
[HttpGet]
public ActionResult Vendor() {
vendorModel oVendor = new vendorModel();
oVendor.vendorTypes = blVendor.getAllVendorTypes();
return View(oVendor);
}
getAllVendorTypes Method
This is where I am fetching records from database and building and returning a List<vendorTypeModel> object.
and Finally on View am using following code.
#Html.DropDownListFor(m => m.vendorTypeID, new SelectList(Model.vendorTypes,"vendorTypeID","vendorTypeName"))
What am I doing wrong? I am getting following results on screen.
Instead of names of vendors.
Please suggest whats wrong with my code.
I suspect that oVendor.vendorTypes = blVendor.getAllVendorTypes(); may return a wrong list back. Set a breakpoint and check the oVendor.vendorTypes please.
According to https://stackoverflow.com/a/15195354/6741868, you could try alternative syntax such as:
#Html.DropDownListFor(m => m.vendorTypeID, Model.vendorTypes.Select(vendor => new SelectListItem()
{
Text = vendor.vendorTypeName,
Value = vendor.vendorTypeID
})

MVC3 POST model binding not working for particular complex model

For some reason, when I post this view model back to the controller and add in the model for binding, it ends up being null. The application that I am working with is a massive one. Also I haven't written much of the code so this model is massive so I will just add the parts that matter, but could other properties be preventing the model binding?
I do know that it has been working but in the last little bit it started not. Maybe it's not even something with the model, would just love some help debugging it.
POST Action:
[HttpPost]
public ActionResult Categories(int applicationId, SqsApplicationViewModel model)
{
// Save away the ids they chose
_sqsApplicationCategoryService.SaveCategories(applicationId, model.Display_Categories.Where(i => i.Selected).Select(i => i.CategoryId).ToList());
// Complete the step
_sqsApplicationStepService.CompleteStep(applicationId, SqsStep.Categories);
return RedirectToAction("Documents");
}
View Model:
public class SqsApplicationViewModel : IMappable
{
public int Id { get; set; }
public int SupplierId { get; set; }
public int? SqsApprovalLevelId { get; set; }
// Other properties .....
public List<SqsChosenCategoryViewModel> Display_Categories { get; set; }
// Other properties .....
}
public class SqsChosenCategoryViewModel
{
public int CategoryId { get; set; }
public string Name { get; set; }
public string CategoryAmountString { get; set; }
public bool Selected { get; set; }
public IList<SqsDocumentComplianceViewModel> Documents { get; set; }
}
View:
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.Id)
#if (Model.Display_Categories != null && Model.Display_Categories.Count() > 0)
{
for (var i = 0; i < Model.Display_Categories.Count; i++)
{
#Html.HiddenFor(m => m.Display_Categories[i].CategoryId)
#Html.CheckBoxFor(m => m.Display_Categories[i].Selected)
#Model.Display_Categories[i].Name
}
}
}
Also, the values being sent back in firebug are:
Id:1061
Display_Categories[0].CategoryId:4
Display_Categories[0].Selected:true
Display_Categories[0].Selected:false
Display_Categories[1].CategoryId:1
Display_Categories[1].Selected:false
Display_Categories[2].CategoryId:2
Display_Categories[2].Selected:false
Display_Categories[3].CategoryId:3
Display_Categories[3].Selected:false
Display_Categories[4].CategoryId:6
Display_Categories[4].Selected:true
Display_Categories[4].Selected:false
Display_Categories[5].CategoryId:8
Display_Categories[5].Selected:false
Display_Categories[6].CategoryId:10
Display_Categories[6].Selected:false
Display_Categories[7].CategoryId:7
Display_Categories[7].Selected:false
Display_Categories[8].CategoryId:9
Display_Categories[8].Selected:false
Display_Categories[9].CategoryId:11
Display_Categories[9].Selected:false
Display_Categories[10].CategoryId:5
Display_Categories[10].Selected:true
Display_Categories[10].Selected:false
-------------EDIT----------------
I tried using the following test models and it worked. Is it possible that another property in the Model could be hindering the binding? I added some random ones in these too and it still worked.
public class TestViewModel
{
public int Id { get; set; }
public IList<TestSubViewModel> Display_Categories { get; set; }
public string TestProp { get { return "asdfasdfasdf"; } }
public TestSubViewModel TestGetFirst { get { return this.Display_Categories.FirstOrDefault(); } }
}
public class TestSubViewModel
{
public int CategoryId { get; set; }
public string Name { get; set; }
public string CategoryAmountString { get; set; }
public bool Selected { get; set; }
public IList<SqsDocumentComplianceViewModel> Documents { get; set; }
}
So I'm just going to answer my own question, though it isn't solved as much as there is another way to do it.
I believe that when you typehint the model and it binds it, in the background it uses "TryUpdateModel()" and so I just called this in the controller and for some reason it worked. Not sure if I miss out on anything else by doing it this way, but it has worked for me.
Also you can debug what might be the issue by doing it this way by the following:
var model = new ViewModel();
var isSuccess = TryUpdateModel(model);
if (!isSuccess)
{
foreach (var modelState in ModelState.Values)
{
foreach (var error in modelState.Errors)
{
Debug.WriteLine(error.ErrorMessage);
}
}
}
Taken from this post: How to find the exceptions / errors when TryUpdateModel fails to update model in asp.net mvc 3

MVC Add and remove items from subcollection

I'm having trouble binding data to a collection item's collection (I'm also having trouble wording my problem correctly). Let's just make thing easier on everyone by using an example with psudo models.
Lets say I have the following example models:
public class Month()
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Week> Weeks { get; set; }
}
public class Week()
{
public int ID { get; set; }
public int MonthID { get; set; }
public String Name { get; set; }
public virtual ICollection<Day> Days { get; set; }
}
public class Day()
{
public int ID { get; set; }
public String Name { get; set; }
}
...and an example viewmodel:
public class EditMonthViewModel()
{
public Month Month { get; set; }
public List<Week> Weeks { get; set; }
public List<Day> AllDays { get; set; }
}
The purpose of the Edit Action/View is to enable users to edit a month, the weeks assigned to the month, and add and remove days from weeks of a certain month. A view might help.
#model myProject.ViewModels.EditMonthViewModel
//...
#using (Html.BeginForm())
{
//Edit Month Stuff...
#for(int i = 0; i < Model.Weeks.Count(); i++)
{
<h2>#Model.Weeks[i].Name</h2>
#Html.EditorFor(model => Model.Weeks[i].Name)
//loop through all possible days
//Select only days that are assigned to Week[i]
#for(int d = 0; d < Model.AllDays.Count(); d ++)
{
//This is the focus of this question.
//How do you bind the data here?
<input type="checkbox"
name="I have no idea"
#Html.Raw(Model.Weeks[i].Days.Contains(Model.AllDays[d]) ? "checked" : "") />
}
}
}
Controller Action methods
public ActionResult Edit(int id)
{
var viewModel = new EditMonthViewModel();
viewModel.Month = db.Months.Find(id);
viewModel.Weeks = db.Weeks.Where(w => w.MonthID == id).ToList();
viewModel.AllDays = db.Days.ToList();
}
[HttpPost]
public ActionResult Edit(EditMonthViewModel viewModel)
{
var monthToUpdate = db.Months.Find(viewModel.Month.ID);
//...
if(viewModel.Weeks != null)
{
foreach (var week in viewModel.Weeks)
{
var weekToUpdate = monthToUpdate.Weeks.Single(w => w.ID == week.ID);
//...
/*So, I have a collection of weeks that I can grab,
but how do I know what was selected? My viewModel only has a
list of AllDays, not the days selected for Week[i]
*/
}
}
How can I ensure that when I submit the form the selected days will bind to the week?
It looks like the easiest thing to do is to make it a goal for your form to populate a data structure of the type IEnumerable<DayModel>, where DayModel is defined as:
public class DayModel
{
public int WeekId { get; set; }
public int DayId { get; set; }
public bool IsIncluded { get; set; }
}
You could keep your Razor code as is for the most part, but then when it comes to rendering the checkboxes, you can do something like this:
#{
var modelIdx = 0;
}
// ...
<input type="hidden" name="days[#modelIdx].WeekId" value="#Model.Weeks[i].Id" />
<input type="hidden" name="days[#modelIdx].DayId" value="#Model.AllDays[d].Id" />
<input type="checkbox" name="days[#modelIdx].IsIncluded" value="#(Model.Weeks[i].Days.Contains(Model.AllDays[d]) ? "checked" : "")" />
#{ modelIdx++; }
Then, your controller action you post to could have this signature:
[HttpPost]
public ActionResult Edit(IEnumerable<DayModel> days)
{
//...
}
Something that helps me is to never confuse view models, which should only be used for the model for views (GET actions generally) and non-view models (what we call plain models). Avoid having your POST actions try to bind to view models, and it will simplify your life greatly.

Categories

Resources