0

I am new with MVC and I am trying to edit a tutorial I completed to understand how everything works. Originally, the tutorial had a search function that let you search by two string parameters, one that check the movie title and one that checks the movie genre, returning the query of any matching values with those parameters.

I am trying to make an actors search which searches by actor name and actor age (an int). I keep getting non-nullable type issues with age, and I have tried everything from declaring age as int?, to .ToString()'ing the IsNullOrEmpty, but nothing has worked.

Can someone show me how to go about this?

Below is the tutorial's searchIndex function. (two strings)

public ActionResult SearchIndex(string movieGenre, string searchString)
    {
        var GenreList = new List<String>();
        var GenreQry = from d in db.Movies orderby d.Genre select d.Genre;

        GenreList.AddRange(GenreQry.Distinct());
        ViewBag.movieGenre = new SelectList(GenreList);


        var movies = from m in db.Movies select m;

        if (!String.IsNullOrEmpty(searchString))
        {
            movies = movies.Where(s => s.Title.Contains(searchString));
        }

        if (string.IsNullOrEmpty(movieGenre))
        {
            return View(movies);
        }
        else
        {

            return View(movies.Where(x => x.Genre == movieGenre));
        }

    }

below is my version (int Age and a string)

public ActionResult SearchIndex(int ageValue, string searchString)
        {
            var AgeList = new List<int>();
            var AgeListQry = from d in db.Actors orderby d.Age select d.Age;

            AgeList.AddRange(AgeListQry.Distinct());
            ViewBag.ageValue = new SelectList(AgeList);

            var actors = from a in db.Actors select a;

            if (!String.IsNullOrEmpty(searchString))
            {
                actors = actors.Where(s => s.Name.Contains(searchString));

            }

            if ("Trying to see if Age is null - this fails on page load")
            {
                return View(actors);
            }
            else
            {
                return View(actors.Where(x => x.Age == ageValue));
            }
        }

My initialization of int Age in the Model is:

public DateTime BirthDate { get; set; }//user input
public int Age
            {
                get { 
                    return (int)(DateTime.Now - BirthDate).TotalDays / 365; 
                }

My View of Age (not sure how to fully implement an int here

<p>
    @Html.ActionLink("Create New", "Create")
    @using (Html.BeginForm("SearchIndex","Movies",FormMethod.Get)){  
        <p>Age: @Html.TextBox("ageValue") 
         <p> Title: @Html.TextBox("SearchString")<br />  
         <input type="submit" value="Filter" /></p> 
        }
</p>

Any help would be greatly appreciated as I am brand new to all of this.

Thank you!

tereško
  • 58,060
  • 25
  • 98
  • 150
Austin
  • 3,010
  • 23
  • 62
  • 97
  • Please post your view where SearchIndex(int ageValue, string searchString) is called from, or ageValue is being read properly? and where does your BirthDate is coming from? – Matas Vaitkevicius May 14 '14 at 16:12
  • @LIUFA added, sorry about that I am still wrapping my head around MVC in general and just realized I needed to this in the View as well. – Austin May 14 '14 at 16:43
  • "SearchString" should be "searchString". So while debugging is ageValue being passed properly to the method? also why are you using GET to submit form? – Matas Vaitkevicius May 14 '14 at 16:48
  • I actually can't even hit the method yet. When I run debug then navigate to SearchIndex, I get "The parameters dictionary contains a null entry for parameter 'ageValue' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult SearchIndex(Int32, System.String)' in 'MvcMovie.Controllers.ActorsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters" – Austin May 14 '14 at 16:52
  • 1
    I see: firstly you want to use POST: add attribute on method [AcceptVerbs(HttpVerbs.Post)]public ActionResult SearchByAge(int ageValue, string searchString) second you are not allowed to have multiple methods with same name, I am assuming SearchIndex is taken. Is your method in MoviesController? – Matas Vaitkevicius May 14 '14 at 16:57
  • Okay I added the Accept Verbs to SearchByAge, I also just changed my View too: @using (Html.BeginForm("SearchByAge","Actors",FormMethod.Get)) As I did make a Controller called ActorsController – Austin May 14 '14 at 17:02
  • Change FormMethod.Get to Post or remove completely, form submit defaults to POST – Matas Vaitkevicius May 14 '14 at 17:07
  • Okay I did that, I am navigating to ~/Actors/SearchByAge/ or ~/Actors/SearchIndex/, I am getting a resource cannot be found now. the BeginForm's first string is the page addres right? So SearchByAge, right? – Austin May 14 '14 at 17:11
  • Yes. If you are in Actors controller already you don't even need to specify Controller. View is in Directory Actors/Views/SearchByAge.cshtml right? – Matas Vaitkevicius May 14 '14 at 17:15
  • @LIUFA Sorry had to step away for a meeting. I do not have an actual SearcByAge.cshtml, I have a Views Folder, holding a Actors directoy though, that has Create/Delete/Details/Edit/Index/SearchIndex.cshtml, so what do I need to do for that? It is the same format as the Movies folder the tutorial had me due, but under Views->Movies, rather than Views->Actors. Thank you for the help so far! – Austin May 14 '14 at 19:54
  • To add on... So SearchIndex is what contains my @Html Action Link stuff that I posted above. – Austin May 14 '14 at 19:56

1 Answers1

0

The problem was that variable Age did not have a pre-made {get; set;} it was manually mapped like this

public DateTime BirthDate { get; set; }
        public int Age
        {
            get
            {
                DateTime today = DateTime.Today;
                int age = today.Year - BirthDate.Year;
                if (BirthDate > today.AddYears(-age)) age--;
                return (int)age;
            }

        }

Thus Age did not exist in the table, it is considered non-mapped, and you must use a different mapped item (a variable with a {get; set;}) to determine your non-mapped variable.

In this scenario I used BirthDate, to calculate my Age within my controller.

Austin
  • 3,010
  • 23
  • 62
  • 97