Получение сообщения об ошибке: System.Reflection.TargetException: для нестатического метода требуется цель

Я использую Visual Studio 2013 Update 2, и я получаю необработанное исключение в одном из моих контроллеров, и я не могу понять, откуда оно взялось. Это контроллер:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Data.Entity;
using Microsoft.AspNet.Identity;

namespace SophicCeramics.Controllers
{
public class ShopController : BaseController
{
public ActionResult Cart()
    {
        var order = FindOrCreateOrder();
        var m = new Models.Order.Cart();  //
        m.Date = order.OrderDate;
        m.Total = order.OrderLineItems.Sum(i => i.Quantity * i.UnitPrice);
        m.ItemCount = order.OrderLineItems.Count;
        m.Items = order.OrderLineItems.ToList();
        return View(m);
    }
    public async Task<ActionResult> AddItem(int productId)
    {
        var product = _context.Products.FirstOrDefault(p => p.ProductId == productId);
        var order = FindOrCreateOrder();
        var item = order.OrderLineItems.FirstOrDefault(i => i.ProductId == productId);
        if (item != null)
        {
            item.Quantity++;
            await _context.SaveChangesAsync();
        }
        else
        {
            item = new OrderLineItem();
            item.OrderHeader = order;
            item.Product = product;
            item.Quantity = 1;
            item.UnitPrice = product.Price;
            order.OrderLineItems.Add(item);
            await _context.SaveChangesAsync();
        }
        return RedirectToAction("Cart");
    }
    private OrderHeader FindOrCreateOrder()
    {
        var UserName = this.User.Identity.Name;
        var user = UserManager.FindByName(UserName);
        var customer = _context.Customers
            .Include(c => c.OrderHeaders.Select(o => o.OrderLineItems.Select(i => i.Product))).
            FirstOrDefault(c => c.UserId.Equals(user.Id));

        var order = customer.OrderHeaders
            .OrderBy(o => o.OrderDate)
            .LastOrDefault(o => o.Paid == false);

        if(order == null)
        {
            order = new OrderHeader();
            //var Customer = new Customer();
            order.Customer = customer;
            customer.OrderHeaders.Add(order);
            _context.SaveChanges();
        }
        return order;
    }
  }
}

Это модель представления:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SophicCeramics.Models.Order
{
    public class Cart
    {
    public int ItemCount { get; set; }
    public DateTime Date { get; set; }
    public decimal Total { get; set; }
    public List<OrderLineItem> Items { get; set; }
    public decimal UnitPrice { get; set; }
    public int OrderHeaderId { get; set; }
    public string CustomerId { get; set; }
    public System.DateTime OrderDate { get; set; }
    public bool Paid { get; set; }
    public int OrderLineItemId { get; set; }
    public int ProductId { get; set; }
    public int Quantity { get; set; }
    public int CategoryId { get; set; }
    public int ArtistId { get; set; }
    public string Title { get; set; }
    public decimal Price { get; set; }
    public string ProductArtUrl { get; set; }
    public string ProductArtMain { get; set; }
    public string UserId { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    }
}

А это вид:

@model SophicCeramics.Product
@{ ViewBag.Title = "Cart"; }
<div>
<h4>Product</h4>
<hr />
<dl class="dl-horizontal">
    <dt>
        @Html.DisplayNameFor(model => model.Title)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.Title)
    </dd>
    <dt>
        @Html.DisplayNameFor(model => model.Price)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.Price)
    </dd>
    <dt>
        @Html.DisplayNameFor(model => model.ProductArtUrl)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.ProductArtUrl)
    </dd>
    <dt>
        @Html.DisplayNameFor(model => model.ProductArtMain)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.ProductArtMain)
    </dd>
    <dt>
        @Html.DisplayNameFor(model => model.Artist.Name)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.Artist.Name)
    </dd>
    <dt>
        @Html.DisplayNameFor(model => model.Category.Name)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.Category.Name)
    </dd>
</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.ProductId }) |
@Html.ActionLink("Back to List", "Index")
</p>

Представление имеет страницу макета, которая является автоматической. Я продолжаю получать ошибку, указывающую на эту строку кода:

var customer = _context.Customers
        .Include(c => c.OrderHeaders.Select(o => o.OrderLineItems.Select(i => i.Product))).
        FirstOrDefault(c => c.UserId.Equals(user.Id));

Как бы я ни переставлял оператор включения, он просто не сработает. Кроме того, контроллер наследуется от другого, называемого BaseController, который имеет подключение к базе данных через _context. Я также пытался добавить практически все из соответствующих классов в файлы .tt в edmx и все равно получаю ошибку. Кроме того, когда я ставлю точку останова на переменную клиента и прохожу через нее, она переходит прямо к методу dispose в BaseController.


person tdrsam    schedule 14.11.2014    source источник
comment
Является ли user нулевым, когда вы получаете сообщение об ошибке?   -  person ekad    schedule 14.11.2014
comment
Идентичен stackoverflow.com/questions/13717355/   -  person Maarten    schedule 14.11.2014


Ответы (1)


Я предполагаю, что user равно нулю, поэтому вы получаете ошибку при доступе к user.Id внутри лямбда-выражения здесь

var customer = _context.Customers
    .Include(c => c.OrderHeaders.Select(o => o.OrderLineItems
    .Select(i => i.Product)))
    .FirstOrDefault(c => c.UserId.Equals(user.Id));

Вам нужно проверить, является ли user нулевым после этой строки

var user = UserManager.FindByName(UserName);

и выполнять остальную часть кода внутри метода FindOrCreateOrder только тогда, когда user не равно нулю. Вам также необходимо решить, что делать, если user имеет значение null в блоке else следующим образом.

private OrderHeader FindOrCreateOrder()
{
    var UserName = this.User.Identity.Name;
    var user = UserManager.FindByName(UserName);
    if (user != null)
    {
        var customer = _context.Customers
            .Include(c => c.OrderHeaders.Select(o => o.OrderLineItems.Select(i => i.Product))).
            FirstOrDefault(c => c.UserId.Equals(user.Id));

        var order = customer.OrderHeaders
            .OrderBy(o => o.OrderDate)
            .LastOrDefault(o => o.Paid == false);

        if(order == null)
        {
            order = new OrderHeader();
            //var Customer = new Customer();
            order.Customer = customer;
            customer.OrderHeaders.Add(order);
            _context.SaveChanges();
        }
        return order;
    }
    else
    {
        // logic when user is null
    }
}
person ekad    schedule 14.11.2014
comment
Я очень рад, что решил проблему, в решении которой вы помогли с @ekad. Я даже не понял, что пользователь был нулевым. Однажды я понял, что мне нужно полностью перенастроить свою логику, чтобы делать то, что я хотел. - person tdrsam; 15.11.2014