Write query for search functionality in C#/ASP.NET MVC - asp.net-mvc

I'm trying to include a search functionality in a ASP.NET Web Application using a search textbox. I have a controller (HomeController) which include an Index (list all data) and a Search (based on user input) Action Method but I'm having trouble writing the code/query for the Search Action Method. Any help would be appreciated. Thanks
//textbox from the View
#using (Html.BeginForm("Search", "Home"))
{
#Html.Editor("SearchBox")
<input type="submit" value="Search" />
}
//The model
public class EventViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime StartDateTime { get; set; }
public TimeSpan? Duration { get; set; }
public string Author { get; set; }
public string Location { get; set; }
public static Expression<Func<Event, EventViewModel>> ViewModel
{
get
{
return e => new EventViewModel()
{
Id = e.Id,
Title = e.Title,
StartDateTime = e.StartDateTime,
Duration = e.Duration,
Location = e.Location,
Author = e.Author.FullName
};
}
}
}
public class UpcomingPassedEventsViewModel
{
public IEnumerable<EventViewModel> UpcomingEvents { get; set; }
public IEnumerable<EventViewModel> PassedEvents { get; set; }
}
//controller
public class HomeController : BaseController
{
public ActionResult Index()
{
var events = this.db.Events
.OrderBy(e => e.StartDateTime)
.Where(e => e.IsPublic)
.Select(EventViewModel.ViewModel);
var upcomingEvents = events.Where(e => e.StartDateTime > DateTime.Now);
var passedEvents = events.Where(e => e.StartDateTime <= DateTime.Now);
return View(new UpcomingPassedEventsViewModel()
{
UpcomingEvents = upcomingEvents,
PassedEvents = passedEvents
});
}
public ActionResult Search(string SearchBox)
{
}

Related

Search / Filtering multiple fields in mvc 5

I am new in mvc 5. I want to have a search using multiple fields. I have this code but I don't know how to pass the values from the view
View:
<input type="text" name="Id">
<input type="text" name="Price">
<input type="text" name="Name">
Product Class:
public class Product
{
public int Id { get; set; }
public int Price { get; set; }
public string Name { get; set; }
}
ProductSearchModel:
public class ProductSearchModel
{
public int? Id { get; set; }
public int? PriceFrom { get; set; }
public int? PriceTo { get; set; }
public string Name { get; set; }
}
ProductBusinessLogic:
public class ProductBusinessLogic
{
private YourDbContext Context;
public ProductBusinessLogic()
{
Context = new YourDbContext();
}
public IQueryable<Product> GetProducts(ProductSearchModel searchModel)
{
var result = Context.Products.AsQueryable();
if (searchModel != null)
{
if (searchModel.Id.HasValue)
result = result.Where(x => x.Id == searchModel.Id);
if (!string.IsNullOrEmpty(searchModel.Name))
result = result.Where(x => x.Name.Contains(searchModel.Name));
if (searchModel.PriceFrom.HasValue)
result = result.Where(x => x.Price >= searchModel.PriceFrom);
if (searchModel.PriceTo.HasValue)
result = result.Where(x => x.Price <= searchModel.PriceTo);
}
return result;
}
}
Product Controller:
public ActionResult Index(ProductSearchModel searchModel)
{
var business = new ProductBusinessLogic();
var model = business.GetProducts(searchModel);
return View(model);
}

Asp mvc 5 relationship many-to-many

How to display all of the materials in the table Material on the page, as well as a number of related data from the Teacher table?
How do I best remake?
Here I describe the models
Models:
public class Teacher
{
public int TeacherId { get; set; }
public string TeacherName { get; set; }
public virtual ICollection<Material> Materials { get; set; }
public Teacher()
{
Materials = new List<Material>();
}
}
public class Material
{
public int MaterialId { get; set; }
public string MaterialName { get; set; }
public string MaterialDescription { get; set; }
public virtual ICollection<Teacher> Teachers { get; set; }
public Material()
{
Teachers = new List<Teacher>();
}
}
The connection to the database
EfdbContext
public class EfDbContext : DbContext
{
// For Science Controller
public DbSet<Teacher> Teachers { get; set; }
public DbSet<Material> Materials { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Teacher>().HasMany(c => c.Materials)
.WithMany(s => s.Teachers)
.Map(t => t.MapLeftKey("TeacherId")
.MapRightKey("MaterialId")
.ToTable("TeacherMaterials"));
}
}
Controller:
public class ScienceController : Controller
{
EfDbContext context = new EfDbContext();
// GET: Science
public ActionResult ScienceResult()
{
IQueryable<Material> materials = context.Materials.Include(p => p.Teachers);
IQueryable<Teacher> teachers = context.Teachers.Include(p => p.Materials);
MateriaLTeacherListView materiaLTeacher = new MateriaLTeacherListView()
{
Materials = materials.ToList(),
Teachers = teachers.ToList()
};
return View(materiaLTeacher);
}
}
View:
#using Diploma.Domain.Entities
#model Diploma.WebUI.Models.MateriaLTeacherListView
#{
ViewBag.Title = "ScienceResult";
}
<div>
#foreach (var p in Model.Materials)
{
<p>#p.MaterialDescription</p>
foreach (Teacher t in Model.Teachers)
{
<li>#t.TeacherName</li>
}
}
</div>
this might work:
#foreach (var p in Model.Materials)
{
<p>#p.MaterialDescription</p>
foreach (Teacher t in p.Teachers)
{
<li>#t.TeacherName</li>
}
}

MVC ASP.net Multiple Views trying to store tags

Model:
public class PublishedSongViewModel
{
public int Id { get; set; }
[Required(AllowEmptyStrings = false)]
public string SongName { get; set; }
//...
[Required]
public IEnumerable<string> Category { get; set; }
}
public class CategoryViewModel
{
public short Id { get; set; }
public string Title { get; set; }
public virtual ICollection<SongCategoryViewModel> SongCategory { get; set; }
}
public class SongCategoryViewModel
{
public int Id { get; set; }
[Required]
public int PublishedSongId { get; set; }
[Required]
public short CategoryId { get; set; }
}
View:
#model IList<PublishedSongViewModel>
#using (Html.BeginForm("PublishMusic", "Publish", FormMethod.Post, new { #enctype = "multipart/form-data", #id = "form-upload" }))
{
#Html.DropDownListFor(x => Model[i].Category, new SelectList(//Categories list here), new { #class = "form-control dl_Categories ", Multiple = "Multiple" })
}
Controller:
[HttpPost]
public ActionResult PublishMusic(IEnumerable<PublishedSongViewModel> songDetails)
{
if (songDetails != null)
{
IEnumerable<PublishedSongViewModel> savedSongs = (IEnumerable<PublishedSongViewModel>)(Session["UserSongs"]);
var lookupDetails = songDetails.ToDictionary(song => song.Id, song => song);
if (savedSongs != null)
{
foreach (var publishedSong in savedSongs)
{
var key = publishedSong.Id;
if (lookupDetails.ContainsKey(key))
{
var details = lookupDetails[key];
publishedSong.SongName = details.SongName;
}
db.SongCategories.Add(new SongCategoryViewModel { PublishedSongId = key, CategoryId = //categories id that user typed in on editorFor});
db.PublishedSongs.Add(publishedSong);
db.SaveChanges();
}
}
}
return View("Index");
}
I'v filled CategoryViewModel table up with data in my SQL.
1) How do I get the titles of CategoryViewModel and pass them in the SelectList(//Here) parameter in my viewmodel?
2) In the PublishMusic Action, how do I get the CategoryId for the SongCategoryViewModel from the one or more categories that the user selected from songDetails.Category?
I am not sure if I am on the right track with this. basically the categories are like tags, the user can select more than one. I'v also cut out unessential code to make easier to read.

Object Reference not set to an instance of object in asp.net mvc

I'm creating new product belonging to the category model.When i execute my Create method, the error invoke that
"Object Reference not set to instance of object" on "model" object
My Controller class:
public ActionResult CreateProduct()
{
SetCateProductViewBag();
return View(new CateProdViewModel());
}
[HttpPost]
public ActionResult CreateProduct(CateProdViewModel model)
{
var ValidImageTypes = new String[]
{
"image/gif",
"image/jpeg",
"image/jpg",
"image/pjpeg",
"image/png"
};
if (model.ImageUpload == null || model.ImageUpload.ContentLength == 0)
{
ModelState.AddModelError("ImageUpload", "This Field is required.");
}
else if (!ValidImageTypes.Contains(model.ImageUpload.ContentType))
{
ModelState.AddModelError("ImageUload", "Please choose either a GIF,jpg or png type of file.");
}
if (ModelState.IsValid)
{
var prod = new Product
{
// CategoryName =model.category.CategoryName,
//CategoryDescription=model.category.CategoryDescription,
//CategoryId=model.CategoryId,
ProductName = model.ProductName,
ProductDescription = model.ProductDescription,
Model = model.Model,
ProductPrice = model.ProductPrice,
AvailableForSale = model.AvailableForSale,
Shippable = model.Shippable,
AvailableStock = model.AvailableStock,
ProductPicture = model.ProductPicture
};
SetCateProductViewBag(prod.CategoryId);
if (model.ImageUpload != null && model.ImageUpload.ContentLength > 0)
{
var UploadDir = "~/Uploads";
var ImagePath = Path.Combine(Server.MapPath(UploadDir), model.ImageUpload.FileName);
var ImageUrl = Path.Combine(UploadDir, model.ImageUpload.FileName);
model.ImageUpload.SaveAs(ImagePath);
prod.ProductPicture = ImageUrl;
}
productContext.product.Add(prod);
productContext.SaveChanges();
return RedirectToAction("CategoryIndex");
}
return View(model);
}
CateProdViewModel class:
public class CateProdViewModel
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public string CategoryDescription { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public int AvailableStock { get; set; }
public decimal ProductPrice { get; set; }
public string Model { get; set; }
public bool AvailableForSale { get; set; }
public bool Shippable { get; set; }
[DataType(DataType.ImageUrl)]
public string ProductPicture { get; set; }
public int SelectedValue { get; set; }
[DataType(DataType.Upload)]
public HttpPostedFileBase ImageUpload { get; set; }
public virtual Category category { get; set; }
[Display(Name="Product Categories")]
public virtual ICollection<Category> categories { get; set; }
}
Entity classes for Category and Product:
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public int AvailableStock { get; set; }
public decimal ProductPrice { get; set; }
public string Model { get; set; }
public bool AvailableForSale { get; set; }
public bool Shippable { get; set; }
public string ProductPicture { get; set; }
public int CustomerId { get; set; }
public int CategoryId { get; set; }
public virtual Category category { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public string CategoryDescription { get; set; }
public virtual ICollection<Product> product { get; set; }
}
My View:
#model SmartShoppingCart.Models.CateProdViewModel
#{
ViewBag.Title = "CreateProduct";
}
<h2>Create Product</h2>
<form action="" method="post" enctype="multipart/form-data">
<div>
#Html.LabelFor(m=>m.CategoryId,"Category")
#Html.DropDownList("CategoryId",ViewBag.categories as SelectList, string.Empty)
#Html.ValidationMessageFor(m=>m.CategoryId)
</div>
<div>
#Html.HiddenFor(m=>m.CategoryId)
</div>
<div>
#Html.LabelFor(m=>m.ProductName)
#Html.TextBoxFor(m=>m.ProductName)
#Html.ValidationMessageFor(m=>m.ProductName)
</div>
<div>
#Html.LabelFor(m=>m.ProductDescription)
#Html.TextBoxFor(m=>m.ProductDescription)
#Html.ValidationMessageFor(m=>m.ProductDescription)
</div>
<div>
#Html.LabelFor(m=>m.Model)
#Html.TextBoxFor(m=>m.Model)
#Html.ValidationMessageFor(m=>m.Model)
</div>
<div>
#Html.LabelFor(m=>m.ProductPrice)
#Html.TextBoxFor(m=>m.ProductPrice)
#Html.ValidationMessageFor(m=>m.ProductPrice)
</div>
<div>
#Html.LabelFor(m=>m.AvailableForSale)
#Html.TextBoxFor(m=>m.AvailableForSale)
#Html.ValidationMessageFor(m=>m.AvailableForSale)
</div>
<div>
#Html.LabelFor(m=>m.Shippable)
#Html.TextBoxFor(m=>m.Shippable)
#Html.ValidationMessageFor(m=>m.Shippable)
</div>
<div>
#Html.LabelFor(m=>m.AvailableStock)
#Html.TextBoxFor(m=>m.AvailableStock)
#Html.ValidationMessageFor(m=>m.AvailableStock)
</div>
<div>
#Html.LabelFor(m=>m.ImageUpload)
#Html.TextBoxFor(m => m.ImageUpload, new {type="file" })
</div>
<div>
<button type="submit" value="Add" ></button>
</div>
</form>
private void SetCateProductViewBag(int? CateId = null)
{
if (CateId == null)
{
ViewBag.Categories = new SelectList(productContext.category, "CategoryId", "CategoryName");
}
else
{
ViewBag.Categories = new SelectList(productContext.category.ToArray(),"CategoryId","CategoryName",CateId);
}
}
Your error occurs because your model is null on post back. The model is null because it contains a property named Model and the parameter name of the action method is also named model which is confusing the poor DefaultModelBinder. Either change the name of the property to something else or change the parameter name in your post action method to something else.
Why don't you change the first action to:
public ActionResult CreateProduct(CateProdViewModel model)
{
SetCateProductViewBag();
return View(model);
}
And your DefaultModelBinder will instantiate the model so it's never null.
Other than that, I need to know what you mean by saying When i execute my Create method. Since you don't have a Create method there. You have CreateProduct and you got 2 of them. Is this a POST or GET request?

The model item passed into the dictionary is of type 'ViewModels.SiteModel',

I'm newbie to MVC architecture.When I'm trying to update, its showing error ,Its totally strange but the data is updating.
The model item passed into the dictionary is of type 'CMS.Domain.Models.Site', but this dictionary requires a model item of type 'CMS.Web.ViewModels.SiteModel'.'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The model item passed into the dictionary is of type 'CMS.Web.ViewModels.SiteModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[CMS.Web.ViewModels.SiteModel]'.
My code looks like:
ViewModels:
namespace CMS.Web.ViewModels
{
public class SiteModel
{
public SiteModel()
{
SiteStatus = new List<SelectListItem>();
}
[Key]
public int ID { get; set; }
[Required(ErrorMessage = "Site Name is required")]
[Display(Name = "Site Name")]
public string Title { get; set; }
[Display(Name = "Require Login")]
public bool RequiresLogin { get; set; }
[Display(Name = "Force HTTPS")]
public bool ForceHTTPS { get; set; }
[Display(Name = "Enable Approval")]
public bool Approval { get; set; }
[AllowHtml]
public IList<SelectListItem> SiteStatus { get; set; }
public bool Deleted { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn
{
get { return _createdOn; }
set { _createdOn = value; }
}
private DateTime _createdOn = DateTime.Now;
public string LastUpdatedBy { get; set; }
public DateTime LastUpdatedOn
{
get { return _lastUpdatedOn; }
set { _lastUpdatedOn = value; }
}
private DateTime _lastUpdatedOn = DateTime.Now;
[Display(Name = "Site State")]
public string SiteState { get; set; }
}
}
Model:
namespace CMS.Domain.Models
{
public partial class Site : Model
{
public string Title { get; set; }
public bool Approval { get; set; }
public bool RequiresLogin { get; set; }
public bool ForceHTTPS { get; set; }
public virtual string SiteStatus { get; set; }
public bool Deleted { get; set; }
}
}
Controller:
public ActionResult Index()
{
var _sites = _siterepository.FindAll();
return View(_sites);
}
public ActionResult Add()
{
var model = new SiteModel();
var _SiteStatus = _siterepository.GetSiteStatus();
foreach (var _sitestatus in _SiteStatus)
{
model.SiteStatus.Add(new SelectListItem()
{
Text = _sitestatus.StatusName,
Value = _sitestatus.StatusName.ToString()
});
}
return View(model);
}
[HttpPost]
public ActionResult Add(SiteModel _sitemodel)
{
var model = _sitemodel.ToEntity();
_siterepository.Add(model);
return View(model);
}
public ActionResult Edit(int id)
{
var model = new SiteModel();
var Site = _siterepository.Find(id);
model = Site.ToModel();
var _SiteStatus = _siterepository.GetSiteStatus();
foreach (var _sitestatus in _SiteStatus)
{
model.SiteStatus.Add(new SelectListItem()
{
Text = _sitestatus.StatusName,
Value = _sitestatus.StatusName.ToString(),
Selected = _sitestatus.StatusName == Site.SiteStatus
});
}
return View(model);
}
[HttpPost]
public ActionResult Edit(SiteModel _sitemodel)
{
var model = _sitemodel.ToEntity();
_siterepository.Update(model);
return View(model);
}
I'm struggling to resolve this , please help.
Check your View's model declaration. It is expecting an enumerable list (IEnumerable<CMS.Web.ViewModels.SiteModel>), but you are passing it a single instance of CMS.Web.ViewModels.SiteModel

Resources