loremIpsum1771
loremIpsum1771

Reputation: 2527

Error when controller route is referenced

I have an ASP.NET core MVC app in which users can search for items to purchase. In this process, there is a search page which returns a list of results in a table where each item in the table is linked to a details page. Both the logic for the search page with the table and the logic for details page are contained in one controller. On the details page, I have an add to cart button which the user can click. This button is linked to a separate controller (for the shopping cart) than the one that is used for the actual details page.

For some reason, when I type in the url for the shopping cart controller action, there is the following error:

InvalidOperationException: Unable to resolve service for type 'Models.ResortDataJoinObj' while attempting to activate 'Controllers.ShoppingCartController'.

The model in question here is being used to store data in the controller which is to be sent to the view. The model is working correctly when it's used in the other controller, so I'm not sure what the issue is here. For some reason though, when I click on the "Add to cart" button in the details view, the server can't find the page. What could be causing these problems here?

Below is the relevant code:

routes in starup.cs

app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=resortDeals}/{action=Index}/{id?}");
                routes.MapRoute(
                  name: "shoppingcart",
                  template: "{controller=ShoppingCart}/{action=Index}/{id?}");
            });

relevant controller actions

    public class ShoppingCartController : Controller
    {
public ShoppingCartController(ResortDataJoinObj resortDataJoinObj, ShoppingCart shoppingCart)
            {
                _shoppingCart = shoppingCart;
                _resortDataJoinObj = resortDataJoinObj;

            }
     [Route("shoppingcart")]
    public ViewResult Index()
    {
        ...
    }
    [Route("ShoppingCart/AddToShopingCart/")]
    public RedirectToActionResult AddToShopingCart(int dealId)
    {
         var selectedDeal = (from rd in _db.ResortData
                                join ra in _db.ResortAvailability on rd.RecNo equals ra.RecNoDate
                                where Convert.ToInt32(rd.RecNo) == id
                                select new ResortDealResultsObject
                                {
                                    Name = rd.Name,
                                    ImageUrl = rd.ImageUrl,
                                    ResortDetails = rd.ResortDetails,
                                    RecNo = rd.RecNo,
                                    CheckIn = ra.CheckIn,
                                    Address = rd.Address,
                                    TotalPrice = ra.TotalPrice

                                }
                                );
            ResortDataJoinObj dealJoinObj = new ResortDataJoinObj();
            List<ResortDealResultsObject> selectedDealList = new List<ResortDealResultsObject>();
            foreach (var row in selectedDeal)
            {
                //An example of only selecting certain results
                // if (row.Name == "John" && row.TotalPrice > 15)
                // {
                var tempVm = new ResortDealResultsObject
                {
                    Name = row.Name,
                    ImageUrl = row.ImageUrl,
                    ResortDetails = row.ResortDetails,
                    RecNo = row.RecNo,
                    CheckIn = row.CheckIn,
                    Address = row.Address,
                    TotalPrice = row.TotalPrice
                };
                selectedDealList.Add(tempVm);
                //}
            }
            dealJoinObj.ResDealList = selectedDealList;
            if (selectedDeal != null)
            {
                _shoppingCart.AddToCart(dealJoinObj);
            }
            return RedirectToAction("Index");
    }
}

public class resortDealsController : Controller
    {

  public IActionResult Index()
        {
        }
 public async Task<IActionResult> Details(string id)
        {
        }
   }

details view:

@model Models.ResortDealDetailObject
@{
    ViewData["Title"] = "Details";
}

<h2>Details</h2>

<div>
    @Model.Name

    @Model.Address

    @Model.ResortDetails
</div>

@Html.Partial("AddToShoppingCart", @Model)

partial view:

 <div class="addToCart text-right">
        <p class="button ">
            @*<a class="btn btn-success" id="cartButton" asp-controller="ShoppingCart" asp-action="AddToShoppingCart" asp-route-id="@Model.RecNo">
                Add to cart
            </a>*@
            <button class="btn btn-success" onclick="search(@Model.RecNo)">
                Add to cart
            </button>
        </p>
    </div>
</form>

<script>
    function addToCart(recNo) {
        document.getElementById('cartForm').action = "/ShoppingCart/AddToShoppingCart/" + recNo;
        document.getElementById('cartForm').submit();
    }
</script>

Resort Data Join object:

public class ResortDataJoinObj
    {
        public ResortData ResData { get; set; }
        public ResortAvailability ResAvail { get; set; }
        public string priceLowEnd { get; set; }
        public string priceHighEnd { get; set; }
        public List<ResortDealResultsObject> ResDealList { get; set; }
        public ResortDealDetailObject detailObject { get; set; }
        public ResortDealResultsObject resortDeal { get; set; }
    }

Upvotes: 0

Views: 133

Answers (1)

mvermef
mvermef

Reputation: 3914

Some answers inline

   // could be [Route("[controller]/[action]") or it could left off all together
   [Route("[controller]")]  
   public class ShoppingCartController : Controller
   {
      public ShoppingCartController(ShoppingCart shoppingCart)
      {
         _shoppingCart = shoppingCart;
      }

      // your default route...
      public IActionResult Index()
      {
        ...
       }
    [HttpGet("{id}")] //not entirely necessary either (more of a partially forced route)
     public RedirectToActionResult AddToShoppingCart(int id)
     {
        //since routes are exact missing something like {id} would cause
        //route generator to skip any calls to this without the {id} in place.
     }
  }

this should work... Since you had somethings that didn't include the {id} then the route doesn't match as you have written in the routing map, therefore you will experience what you are currently seeing.

Looking over the information you gleamed from the youtube video, I visited his repository to look at the example. He actually has the ShoppingCart (ref. startup.cs) scoped so that its in what ever form (each individual cart, that is presently filled), via the IOC container.

Also keep in mind some of the configuration will vary now with that repository being about nearly 2 versions of .net core behind somethings with 2.1 are vastly different like not using project.json to reference assemblies for example.

Upvotes: 2

Related Questions