【问题标题】:Error when controller route is referenced引用控制器路由时出错
【发布时间】:2018-06-21 21:40:28
【问题描述】:

我有一个 ASP.NET 核心 MVC 应用程序,用户可以在其中搜索要购买的项目。在这个过程中,有一个搜索页面,它返回一个表格中的结果列表,其中表格中的每个项目都链接到一个详细信息页面。带有表格的搜索页面的逻辑和详细信息页面的逻辑都包含在一个控制器中。在详细信息页面上,我有一个添加到购物车按钮,用户可以单击该按钮。此按钮链接到一个单独的控制器(用于购物车),而不是用于实际详细信息页面的控制器。

由于某种原因,当我输入购物车控制器操作的 url 时,出现以下错误:

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

这里讨论的模型被用来在控制器中存储数据,这些数据将被发送到视图。该模型在另一个控制器中使用时可以正常工作,所以我不确定这里有什么问题。但是由于某种原因,当我在详细信息视图中单击“添加到购物车”按钮时,服务器找不到该页面。 是什么导致了这些问题?

下面是相关代码:

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?}");
            });

相关控制器操作

    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)
        {
        }
   }

详情查看:

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

<h2>Details</h2>

<div>
    @Model.Name

    @Model.Address

    @Model.ResortDetails
</div>

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

局部视图:

 <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 对象:

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; }
    }

【问题讨论】:

  • 请向我们展示ShoppingCartController构造函数。另外,您使用的是哪个 IoC 容器。
  • 当您从控制器加载视图时,我看不到您创建视图模型对象并将其传递给视图的位置。在加载视图的操作中尝试创建resortdatajoinobj并将其传递给视图
  • @mjwills 我刚刚用构造函数更新了帖子。另外,您所说的 IoC 容器是什么意思?我还是 Asp .net 的新手
  • 你的构造函数是你的问题
  • 从构造函数中删除这两个参数,你应该没问题。 Ioc是服务注入常用的依赖注入容器,需要先注册。

标签: c# asp.net-core asp.net-core-mvc


【解决方案1】:

一些内联答案

   // 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.
     }
  }

这应该可行...由于您有一些不包含 {id} 的内容,因此路线与您在路线图中所写的不匹配,因此您将体验到您当前看到的内容。

查看您从 youtube 视频中获得的信息,我访问了他的存储库以查看示例。实际上,他通过 IOC 容器将 ShoppingCart(参考 startup.cs)限定为任何形式(每个单独的购物车,目前已装满)。

另外请记住,现在某些配置会有所不同,因为该存储库大约有 2 个版本的 .net 核心,而 2.1 的某些内容则大不相同,例如不使用 project.json 来引用程序集。

【讨论】:

  • 所以实际上,问题出在 AddToShoppingCart 方法的名称中有错字(检查 OP 中的代码),因此调用该方法的视图(使用了正确的拼写对于该方法)实际上无法调用它。 Idk怎么没有人抓住那个哈哈。我会接受这个答案,因为使用显式路由也是一种选择,但实际上这里最终并不需要它们。我将不得不添加一个服务,以便类中可以有 DI,以便让实际方法中的代码按预期工作。
猜你喜欢
  • 2013-06-22
  • 2018-08-06
  • 1970-01-01
  • 2011-05-09
  • 2022-11-15
  • 1970-01-01
  • 2016-07-23
  • 2015-09-26
  • 1970-01-01
相关资源
最近更新 更多