13

Here is a paste of the action method MovieCustomer in the EverythingController. The Viewmodel is used to Combine two Models: Customer & Movies, and is populated with information from the Database via the ApplicationDbContext (_context).

The Routeing works successfully and renders the page when there are values for MovieId and CustomerId

e.g. /Everything/MovieCustomer/1/1

I want the page to also load if one or both of the values are null. So far both of the int parameters were made nullable and there is an if statement in the method to change the parameters to 1 if either is null. So far if the values are null the browser returns a 404 error.

How can I get the page to function when one or either of the parameters are null? Thanks

[Route("Everything/MovieCustomer/{movieId}/{customerId}")]
public ActionResult MovieCustomer(int? movieId, int? customerId)
{
    var viewmodel = new ComboViewModel
    {
        _Customers = new List<Customer>(),
        _Movies = new List<Movies>(),
        _customer = new Customer(),
        _movie =  new Movies()
    };
    viewmodel._Customers = _context.Customers.ToList();
    viewmodel._Movies = _context.Movies.ToList();

    if (!movieId.HasValue)
        movieId = 1;

    if (!customerId.HasValue)
        customerId = 1;

    viewmodel._customer = viewmodel._Customers.SingleOrDefault(a => a.Id == customerId);
    viewmodel._movie = viewmodel._Movies.SingleOrDefault(a => a.Id == movieId);

    return View(viewmodel);
}
1

3 Answers 3

33

You can achieve this using separate routes, or change your parameters to be optional.

When using 3 attributes, you add separate routes for each of the options that you have - when no parameters are specified, when only movieId is specified, and when all 3 parameters are specified.

[Route("Everything/MovieCustomer/")]
[Route("Everything/MovieCustomer/{movieId}")]
[Route("Everything/MovieCustomer/{movieId}/{customerId}")]
public ActionResult MovieCustomer(int? movieId, int? customerId)
{
    // the rest of the code
}

Alternatively you an combine change your route parameters to optional (by adding ? in route definition) and this should cover all 3 cases that you have:

[Route("Everything/MovieCustomer/{movieId?}/{customerId?}")]
public ActionResult MovieCustomer(int? movieId, int? customerId)
{
    // the rest of the code
}

Keep in mind that neither sample supports the case where you provide only customerId.

Sign up to request clarification or add additional context in comments.

1 Comment

this is correct one... Mine : [Route("/KodePos/Print/{sKeyword?}")] public IActionResult Print(string? sKeyword) {}
1

Interstingly, I had to add optional parameter to the signature as well for it to work from Angular client like so:

[HttpGet]
[Route("IsFooBar/{movieId?}/{customerId?}")]
[Route("IsFooBar/null/{customerId?}")]
public bool IsFooBar(int? movieId = null, int? customerId = null)
{
    // the rest of the code
}

In Angular

  public IsFoobar(movieId: number | null, customerId: number | null): Observable<boolean> {
    return this.httpService.get<boolean>(`api/IsFooBar/${movieId}/${customerId}`);
  }

Comments

0

Keep in mind that neither sample supports the case where you provide only customerId.

Check it out. I think you can use the multiple route method with EVEN ANOTHER route like this if you do want to provide only customerId:

[Route("Everything/MovieCustomer/null/{customerId}")]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.