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));
Related
I'm deserializing the following JSON and having trouble with the categories/WebFilters section. I want to be able to loop through it but get the
Cannot deserialize current JSON object into type - c#´
CS1579 foreach statement cannot operate on variables of type 'WebFilters' because 'WebFilters' does not contain a public definition for 'GetEnumerator'
error when I run my code. Eventually I need to make a list of the keys and values in each of the categories as I'm using it to create a dynamic results filter - I don't know at this stage what or how many filters they'll be.
I tried changing my json, but that doesn't achieve what I want it to. I think I need to give WebFilters the ability to be iterated over...
Thanks.
{
"Webinars": [
{
"date":"2017-11-08T19:21:46Z",
"title":"Americano",
"desc":"Nondisp fx of prox phalanx of l mid fngr, 7thG",
"startTime":"5:39 PM",
"endTime":"5:19 PM",
"categories":{
"category":"introduction",
"timeZone":"Europe/Stockholm",
"language":"English"
}
},...
Model
public class Rootobject
{
public Webinar[] Webinars { get; set; }
public ELearning[] ELearning { get; set; }
}
public class Webinar
{
public DateTime Date { get; set; }
public string Title { get; set; }
public string Desc { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
public WebFilters Categories { get; set; }
}
public class WebFilters
{
public string Category { get; set; }
public string TimeZone { get; set; }
public string Language { get; set; }
}
View
#foreach (var webinar in Model.Webinars)
{
<li>#webinar.Title</li>
<ul>
#{
var categories = webinar.Categories;
}
#foreach (var cat in categories)
{
<li>#cat</li>
}
</ul>
}
Controller
public ActionResult Dashboard_Portal()
{
// Example JSON
var webClient = new WebClient();
var json = webClient.DownloadString(#"http://elliottjbrown.co.uk/portal/js/data.json");
var webinars = JsonConvert.DeserializeObject<Rootobject>(json);
return View(webinars);
}
Your Categories Property in your Webinar class is not a collection of any kind, so you can't iterate over it.
You may be looking to either make it a collection:
public WebFilters Categories[] { get; set; } or
public WebFilters List<Categories> { get; set; }
If you actually want a collection of categories, you'll either need to have a partial view configured to render a given Category object, or you'll need to provide specific rendering inside your for loop. Something like this (note the below code will only show the one property):
#foreach (var cat in categories)
{
<li>#cat.Category</li>
}
If you only expect one category for each webinar, then you'll need to refer to each property individually in the View. Here's a .NET Fiddle showing a simple render with Categories as a single object, rather than a collection Simple Display Render With Non-Collection Categories Property
<ul>
<li>#webinar.Categories.Category</li>
<li>#webinar.Categories.TimeZone</li>
<li>#webinar.Categories.Language</li>
</ul>
UPDATE
Here's a link to a .NET fiddle that shows what this might look like if you're just trying to iterate through the Categories and display them: Simple Display Render With Category Collection. You'll notice that the Webinars and Elearning properties of the Rootobject are still arrays (not List<T>), as originally defined, and the the Rootobject does not implement IEnumerable as was suggested in other answers. There's no need for those changes.
Now, if you're looking for an edit page of some kind where the user can actually select a single category from a list of options, that's a different issue and wasn't clear from your OP.
Convert the Rootobject class properties into List<> as follows:
public class Rootobject
{
public List<Webinar> Webinars { get; set; }
}
Update 1:
Note: Make sure Categories in the Webinar class implements the IEnumerable interface or list collection as the Json data returns an array.
Update 2: I've updated your code and made it work using the following:
The Webinar Class:
public class Webinar
{
public DateTime Date { get; set; }
public string Title { get; set; }
public string Desc { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
public WebFilters[] Categories { get; set; } //Converted it into a collection
}
The Controller:
public ActionResult Dashboard_Portal()
{
var webClient = new WebClient();
var json = webClient.DownloadString(#"http://elliottjbrown.co.uk/portal/js/data.json");
var webinars = JsonConvert.DeserializeObject<Rootobject>(json);
return View(webinars);
}
Finally, The View:
#model DemoApp.Models.Rootobject
#{
Layout = null;
}
<div>
#foreach (var webinar in Model.Webinars)
{
<h3>#webinar.Title</h3>
<ul>
<li>#webinar.Categories[0].TimeZone</li>
</ul>
}
</div>
See the output with a screenshot:
according to JSON-RPC spec , json is case senitive.
all of your c# class properties start with uppercases, but your json propertise with lowercases.
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
})
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.
I tried to access the property of model (FilePath) in my Render action, but without success.
I have these models:
public class Offer
{
public int OfferID { get; set; }
public string Reference { get; set; }
public string Title { get; set; }
public virtual ICollection<FilePath> FilePaths { get; set; }
}
public class FilePath
{
public int FilePathId { get; set; }
public string FileName { get; set; }
public virtual Offer Offer { get; set; }
}
In controller offer:
public PartialViewResult Category()
{
var offers = db.Offers
.Include(i => i.FilePaths)
// i tried with .Include(“FilePaths”) with no sucess
.ToList();
return PartialView("_OfferBoxList", offers);
}
Showing with:
#{Html.RenderAction("Category", "Offer");}
The problem is in partial action view:
#foreach (var item in Model)
{
#item.Title // This work
#item.FilePath.FileName // This NOT work
}
Output error:
'System.Data.Entity.DynamicProxies.Offer_278BF6A1F89FB9514329AC922E992AEBD19368D66A4460B6BEBA1BB2256CAFC3' does not contain a definition for 'FilePath'
Thanks for help.
Each Offer has a list of FilePath instances (ICollection<FilePath> FilePaths), so you can't just access the Offer.FilePath.FileName property, you have to get for instance the first one (depending on what you need), using something like:
#foreach (var item in Model)
{
#item.Title // This work
#item.FilePaths.First().FileName // Take the first FilePath object from the collection
}
You should really not be loading your entities into views..
I generally create Data Transfer Objects (DTOs) for a multitude of purposes. Not only does it help me shape the query expression (IQueryable<T>), but I also use so that I have concert types (instead of generated dynamic proxy class types - like the type you're seeing in your runtime exception) in control properties, like dataItem and dataSource, which are often used in runtime bindable dynamic/reflective controls (grids, listviews)..
Note
It is possible to disable the generated dynamic proxy types by declaring and passing your own DbContextConfiguration instance to EntityFramework; However, doing so will affect EntityFramework supporting features.
public class OfferDTO
{
public int OfferID { get; set; }
public string Reference { get; set; }
public string Title { get; set; }
public IEnumerable<string> FileNames { get; set; }
}
you controller function would then look like:
public PartialViewResult Category()
{
var offers = db.Offers.Select<Offer, OfferDTO>( (entity) => new OfferDTO() {
OfferID = entity.OfferID,
Reference = entity.Reference,
Title = entity.Title,
FileNames = entity.FilePaths.Select<FilePath, string>( filePath => filePath.FileName).AsEnumerable()
});
return PartialView("_OfferBoxList", offers.ToList());
}
then,
#{Html.RenderAction("Category", "OfferDTO");}
#foreach (var item in Model) // Model is IEnumerable<OfferDTO>
{
#item.Title
#item.FileNames.First()
}
Additionally,
you can create an IQueryable<IQueryable<TEntityDTO>> to suit your purposes and perform a SelectMany on it to flatten the results.
public class OfferTitleFilenameDTO
{
public string Title {get;set;}
public string Filename {get;set;}
}
public PartialViewResult Category()
{
var offers = db.Offers.Select<Offer, IQueryable<OfferTitleFilenameDTO>>( (entity) => entity.FilePaths.Select<FilePath, OfferTitleFilenameDTO>(filePath => new OfferTitleFilenameDTO() {
Filename = filePath.FileName,
Title = entity.Title
})
});
return PartialView("_OfferBoxList", offers.SelectMany(dtos => dtos));
}
then,
#{Html.RenderAction("Category", "OfferTitleFilenameDTO");}
#foreach (var item in Model) // Model is IEnumerable<OfferTitleFilenameDTO>
{
#item.Title
#item.Filename
}
So i have a viewmodel that contains a list of tags List<Tag> tags {get; set;}
public class BlogVM
{
public List<Blog> Blogs { get; set; }
public List<Tag> Tags { get; set; }
}
private EFMTMContext db = new EFMTMContext();
// GET: /Blog/
public ActionResult Index()
{
BlogVM viewModel = new BlogVM();
viewModel.Blogs = db.Blogs.ToList();
viewModel.Tags = db.Tags.ToList();
return View(viewModel);
}
the database of tags is stored into the viewModel.Tags and passed into the view.
The problem I am having is displaying them with the Html.DropDownList. what is displayed is
EFTest.EntityFramwork.Tag, EFTest.EntityFramwork.Tag, EFTest.EntityFramwork.Tag.
(Namespace.Folder.Tag) I was expecting the dropdownlist to populate
Football, Rugby, Tennis etc
#model EFManyToManyTest.ViewModels.BlogVM
#Html.DropDownList("tags", new SelectList(Model.Tags), "---", false)
What is the right way of accessing each of the tags from the viewmodel?
Hopefully someone can help.
Thanks!
Thought I'd add, i can loop through the contents of Model.Tags using,
#foreach (var item in Model.Tags)
{
#item.Name
}
no problem. This works, it's just the dropdownlist that doesnt
This now works using
public class Tag
{
public int **TagID** { get; set; }
public string **Name** { get; set; }
public List<Blog> Blogs { get; set; }
}
#Html.DropDownList("tags", new SelectList(Model.Tags, **"TagID"**, **"Name"**), "---", false)
TagID because that's the ID property in the class definition
You didn't specify value and text fields, take a look at this constructor of the SelectList:
public SelectList(
IEnumerable items,
string dataValueField,
string dataTextField
)
For instance
#Html.DropDownList("tags", new SelectList(Model.Tags, "Id", "Name"), "---", false)