首页 > 解决方案 > ASP.Net Web API 2 中的无参数构造函数错误

问题描述

我正在尝试按照存储库模式制作 RestFul API。当我使用邮递员访问我的 API 时,我看到了参数少的构造函数错误。我实际上无法找出我错了什么。 错误截图 我正在使用 EntityFramework6 数据库优先方法。我分享了我所有相关的代码示例。这是我的 SSDBEntities.cs

    public partial class SSDBEntities : DbContext
    {
     public SSDBEntities()
        : base("name=SSDBEntities")
      {
      }

     protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
        throw new UnintentionalCodeFirstException();
      }

     public virtual DbSet<Employee> Employees { get; set; }
     public virtual DbSet<Product> Products { get; set; }
}

产品控制器.cs

[RoutePrefix("api/ss/products")]
public class ProductController : ApiController
{
    private readonly IProductService _productService;
    public ProductController(IProductService productService)
    {
        _productService = productService;
    }

    [HttpGet]
    [Route("get-products")]
    public async Task<IHttpActionResult> GetProducts()
    {
        int total = 0;
        List<ProductModel> model = _productService.getProducts();
        return Ok(new ResponseMessage<List<ProductModel>>()
        {
            Result = model
        });
    }
}

IProductService.cs

    public interface IProductService
    {
       List<ProductModel> getProducts();
    }

产品服务.cs

    public class ProductService : IProductService
    {
      private readonly ISSRepository<Product> _productRepository;
      public ProductService(ISSRepository<Product> productRepository)
      {
        _productRepository = productRepository;
      }
      public List<ProductModel> getProducts()
      {
        List<Product> products = _productRepository.Where(x => x.IsActive == true).ToList();
        List<ProductModel> models = ObjectConverter<Product, ProductModel>.ConvertList(products).ToList();
        return models;
      }
     }

ISSRepository.cs

    public interface ISSRepository<TEntity> : IRepository<TEntity> where TEntity : class
    {
      DataTable ExecWithStoreProcedure(string query, IDictionary<string, object> values);
      DataTable ExecWithSqlQuery(string query);
      int ExecNoneQuery(string query);
    }

IRepository.cs

public interface IRepository<T> where T : class
{
    T FindOne(Expression<Func<T, bool>> predicate);

    T FindOne(Expression<Func<T, bool>> predicate, List<string> includeProperties);

    bool Exists(Expression<Func<T, bool>> predicate);

    IQueryable<T> AsQueryable();

    IQueryable<T> Where(Expression<Func<T, bool>> predicate);

    int Count();

    int Count(Expression<Func<T, bool>> predicate);

    int Save(T entity);

    void Insert(T entity);

    int SaveAll(List<T> entity);
    int UpdateAll(List<T> entities);
    int Recreate(List<T> entity);

    int Recreate(List<T> oldEntities, List<T> newEntities);

    int SaveChanges();

    bool Delete(T entity);

    int Delete(Expression<Func<T, bool>> predicate);

    /// <summary>
    /// Add entity to DbSet
    /// </summary>
    /// <param name="entity">Entity to add in DbSet</param>
    void Add(T entity);

    /// <summary>
    /// Add entity collection to DbSet.
    /// </summary>
    /// <param name="entities"></param>
    void AddRange(IEnumerable<T> entities);

    void Remove(T entity);
    int RemoveRange(IEnumerable<T> entities);
    void BlukInsert(IEnumerable<T> entities);
    T FinedOneInclude(Expression<Func<T, bool>> predicate, params string[] include);
    IQueryable<T> FilterWithInclude(Expression<Func<T, bool>> predicate, params string[] include);
    Task<int> SaveAsync(T entity);
    Task<bool> DeleteAsync(T entity);
    Task<bool> DeleteAsync(Expression<Func<T, bool>> predicate);
    Task<int> CountAsync();
    Task<int> SaveAllAsync(List<T> entity);
    Task<int> CountAsync(Expression<Func<T, bool>> predicate);
    Task<bool> ExistsAsync(Expression<Func<T, bool>> predicate);
    Task<T> FindOneAsync(Expression<Func<T, bool>> predicate);
    Task<T> FindOneAsync(Expression<Func<T, bool>> predicate, List<string> includeProperties);
    Task<ICollection<T>> FilterAsync(Expression<Func<T, bool>> predicate);
    Task<int> SaveChangeAsync();
 }

存储库.cs

public abstract class Repository<TDbContext, TEntity> : IRepository<TEntity>
    where TEntity : class
     where TDbContext : DbContext
{
    public readonly TDbContext context;
    private readonly DbSet<TEntity> dbSet;

    protected Repository(TDbContext context)
    {
        this.context = context;
        dbSet = this.context.Set<TEntity>();
        context.Configuration.LazyLoadingEnabled = false;
        context.Configuration.ProxyCreationEnabled = false;
    }

    /// <summary>
    /// Find entity based on lamda-expression
    /// </summary>
    /// <param name="predicate"></param>
    /// <returns></returns>
    public virtual TEntity FindOne(Expression<Func<TEntity, bool>> predicate)
    {
        return dbSet.FirstOrDefault(predicate);
    }

    public virtual TEntity FindOne(Expression<Func<TEntity, bool>> predicate, List<string> includeProperties)
    {
        IQueryable<TEntity> query = dbSet.Where(predicate);

        if (includeProperties != null)
        {
            foreach (var name in includeProperties)
            {
                query = query.Include(name);
            }
        }

        return query.FirstOrDefault();
    }

    /// <summary>
    /// Check entity exists or not based on lamda-expression
    /// </summary>
    /// <param name="predicate">Expression to match</param>
    /// <returns></returns>
    public virtual bool Exists(Expression<Func<TEntity, bool>> predicate)
    {
        return dbSet.Any(predicate);
    }

    public virtual IQueryable<TEntity> AsQueryable()
    {
        return dbSet.AsQueryable();
    }

    /// <summary>
    /// Filters a sequence of values based on a predicate.
    /// </summary>
    /// <param name="predicate">A function to test each element for a condition.</param>
    /// <returns>An System.Linq.IQueryable`1 that contains elements from the input sequence that 
    /// satisfy the condition specified by predicate.
    /// </returns>
    public IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> predicate)
    {
        return dbSet.Where(predicate);
    }

    public virtual int Count()
    {
        return dbSet.Count();
    }

    public virtual int Count(Expression<Func<TEntity, bool>> predicate)
    {
        return dbSet.Count(predicate);
    }

    public virtual int Save(TEntity entity)
    {
        DbEntityEntry<TEntity> entry = context.Entry(entity);

        if (entry.State == EntityState.Detached)
        {
            dbSet.Add(entity);
            entry.State = EntityState.Added;
        }
        else
        {
            dbSet.Attach(entity);
            entry.State = EntityState.Modified;
        }

        try
        {
            return context.SaveChanges();
        }
        catch
        {
            ClearEntityState();
            throw;
        }
    }

    public virtual void Insert(TEntity entity)
    {
        dbSet.Add(entity);
        SaveChanges();
    }

    public virtual int SaveAll(List<TEntity> entity)
    {
        dbSet.AddRange(entity);
        return SaveChanges();
    }

    public virtual int UpdateAll(List<TEntity> entities)
    {
        foreach (TEntity entity in entities)
        {
            DbEntityEntry<TEntity> entry = context.Entry(entity);

            dbSet.Attach(entity);
            entry.State = EntityState.Modified;
        }
        return SaveChanges();
    }

    public virtual int Recreate(List<TEntity> entity)
    {
        DbSet<TEntity> objects = dbSet;
        dbSet.RemoveRange(objects);
        dbSet.AddRange(entity);
        return SaveChanges();
    }

    public virtual int Recreate(List<TEntity> oldEntities, List<TEntity> newEntities)
    {
        dbSet.RemoveRange(oldEntities);
        dbSet.AddRange(newEntities);
        return SaveChanges();
    }

    public virtual bool Delete(TEntity entity)
    {
        dbSet.Remove(entity);
        return SaveChanges() > 0;
    }

    /// <summary>
    /// Will be used for DeleteALL
    /// </summary>
    /// <param name="predicate"></param>
    /// <returns></returns>
    public virtual int Delete(Expression<Func<TEntity, bool>> predicate)
    {
        IQueryable<TEntity> objects = Where(predicate);
        dbSet.RemoveRange(objects);
        return SaveChanges();
    }

    /// <summary>
    /// Save all changes in DbContext
    /// </summary>
    /// <returns></returns>
    public int SaveChanges()
    {
        try
        {
            return context.SaveChanges();
        }
        catch
        {
            ClearEntityState();
            throw;
        }
    }

    private void ClearEntityState()
    {
        List<DbEntityEntry> changedEntries = context.ChangeTracker.Entries().Where(x => x.State != EntityState.Unchanged).ToList();

        foreach (var entry in changedEntries.Where(x => x.State == EntityState.Modified))
        {
            entry.CurrentValues.SetValues(entry.OriginalValues);
            entry.State = EntityState.Unchanged;
        }

        foreach (var entry in changedEntries.Where(x => x.State == EntityState.Added))
        {
            entry.State = EntityState.Detached;
        }

        foreach (var entry in changedEntries.Where(x => x.State == EntityState.Deleted))
        {
            entry.State = EntityState.Unchanged;
        }
    }

    /// <summary>
    /// Add entity to DbSet. SaveChanges requires to update database.
    /// </summary>
    /// <param name="entity">Entity to add in DbSet</param>
    public virtual void Add(TEntity entity)
    {
        dbSet.Add(entity);
    }

    /// <summary>
    /// Add entity collection to DbSet. SaveChanges requires to update database.
    /// </summary>
    /// <param name="entities"></param>
    public virtual void AddRange(IEnumerable<TEntity> entities)
    {
        dbSet.AddRange(entities);
    }

    /// <summary>
    /// Remove entity from DbSet. SaveChanges requires to update database.
    /// </summary>
    /// <param name="entity">Entity to remove from DbSet</param>
    public virtual void Remove(TEntity entity)
    {
        dbSet.Remove(entity);
    }


    public virtual void BlukInsert(IEnumerable<TEntity> entities)
    {
        bool autoDetectChangesEnabled = context.Configuration.AutoDetectChangesEnabled;
        bool validateOnSaveEnabled = context.Configuration.ValidateOnSaveEnabled;

        context.Configuration.AutoDetectChangesEnabled = false;
        context.Configuration.ValidateOnSaveEnabled = false;

        dbSet.AddRange(entities);
        SaveChanges();

        context.Configuration.AutoDetectChangesEnabled = autoDetectChangesEnabled;
        context.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabled;
    }

    public virtual IQueryable<TEntity> GetAllInclude(params string[] include)
    {
        IQueryable<TEntity> query = this.dbSet.AsNoTracking();
        query = include.Aggregate(query, (current, inc) => current.Include(inc));
        return query.AsQueryable();
    }

    public virtual TEntity FinedOneInclude(Expression<Func<TEntity, bool>> predicate, params string[] include)
    {
        IQueryable<TEntity> query = this.dbSet.AsNoTracking();
        query = include.Aggregate(query, (current, inc) => current.Include(inc));
        return query.FirstOrDefault(predicate);
    }

    public virtual IQueryable<TEntity> FilterWithInclude(Expression<Func<TEntity, bool>> predicate, params string[] include)
    {
        IQueryable<TEntity> query = this.dbSet.AsNoTracking();
        query = include.Aggregate(query, (current, inc) => current.Include(inc));
        return query.Where(predicate).AsQueryable();
    }

    public virtual Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate)
    {
        return dbSet.CountAsync(predicate);
    }

    public virtual Task<int> CountAsync()
    {
        return dbSet.CountAsync();
    }


    public async virtual Task<int> SaveChangeAsync()
    {
        try
        {
            return await context.SaveChangesAsync();
        }
        catch (Exception e)
        {

            ClearEntityState();
            throw;
        }
    }

    public virtual Task<int> SaveAsync(TEntity entity)
    {
        DbEntityEntry<TEntity> entry = context.Entry(entity);

        if (entry.State == EntityState.Detached)
        {
            dbSet.Add(entity);
            entry.State = EntityState.Added;
        }
        else
        {
            dbSet.Attach(entity);
            entry.State = EntityState.Modified;
        }

        try
        {
            return SaveChangeAsync();
        }
        catch
        {
            ClearEntityState();
            throw;
        }
    }

    public virtual Task<TEntity> FindOneAsync(Expression<Func<TEntity, bool>> predicate)
    {
        return dbSet.FirstOrDefaultAsync(predicate);
    }

    public Task<TEntity> FindOneAsync(Expression<Func<TEntity, bool>> predicate, List<string> includeProperties)
    {
        IQueryable<TEntity> query = this.dbSet.AsNoTracking();
        query = includeProperties.Aggregate(query, (current, inc) => current.Include(inc));
        return query.FirstOrDefaultAsync(predicate);
    }


    public virtual Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate)
    {
        return dbSet.AnyAsync(predicate);
    }

    public async virtual Task<bool> DeleteAsync(TEntity entity)
    {
        dbSet.Remove(entity);
        try
        {
            var effectedRows = await SaveChangeAsync();
            return effectedRows > 0;
        }
        catch (Exception e)
        {

            throw new Exception("Someting went wrong. Please first delete family information");

        }

    }

    public async virtual Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> predicate)
    {
        IQueryable<TEntity> objects = Where(predicate);
        dbSet.RemoveRange(objects);
        return await SaveChangeAsync() > 0;
    }

    public async virtual Task<ICollection<TEntity>> FilterAsync(Expression<Func<TEntity, bool>> predicate)
    {
        return await dbSet.Where(predicate).ToListAsync();
    }

    public Task<int> SaveAllAsync(List<TEntity> entity)
    {
        dbSet.AddRange(entity);
        return SaveChangeAsync();
    }

    public int RemoveRange(IEnumerable<TEntity> entities)
    {
        dbSet.RemoveRange(entities);
        return SaveChanges();
    }
}

SSRepository.cs

public class SSRepository<T> : Repository<SSDBEntities, T>, ISSRepository<T>
     where T : class
{
    internal SqlConnection Connection;
    public SSRepository(SSDBEntities context) : base(context)
    {
        Connection = context.Database.Connection as SqlConnection;
    }
    public DataTable ExecWithStoreProcedure(string query, IDictionary<string, object> values)
    {

        using (Connection)

        using (SqlCommand cmd = new SqlCommand())
        {
            cmd.CommandText = query;
            foreach (KeyValuePair<string, object> item in values)
            {
                cmd.Parameters.AddWithValue("@" + item.Key, item.Value);
            }
            DataTable table = new DataTable();
            using (var reader = cmd.ExecuteReader())
            {
                table.Load(reader);
                return table;
            }
        }
    }

    public DataTable ExecWithSqlQuery(string query)
    {
        try
        {
            Connection.Open();
            SqlCommand cmd = new SqlCommand(query, Connection);
            DataTable dt = new DataTable();
            SqlDataAdapter dataAdapter = new SqlDataAdapter(cmd);
            dataAdapter.Fill(dt);
            return dt;
        }
        catch
        {
            throw new Exception();
        }
        finally
        {
            if
                (Connection.State == ConnectionState.Open)
            {

                Connection.Close();
            }
        }



    }

    public int ExecNoneQuery(string query)
    {
        try
        {
            Connection.Open();
            using (SqlCommand cmd = new SqlCommand(query, Connection))
            {
                return cmd.ExecuteNonQuery();
            }
        }
        catch
        {
            throw new Exception();
        }
        finally
        {
            if
                (Connection.State == ConnectionState.Open)
            {

                Connection.Close();
            }
        }


    }
}

谁能帮我解决这个问题?

标签: entity-framework-6asp.net-web-api2repository-pattern

解决方案


在这种情况下,错误会准确地告诉您问题所在 - 您的控制器没有采用零参数的构造函数。例如:

public ProductController()
{
}

默认情况下,应用程序不知道如何提供一个IProductService作为参数。
如果您创建一个默认构造函数,您可以在其中创建一个新构造函数IProductService,而不是接受它作为参数或属性初始化。

如果您不想拥有无参数的构造函数,您可以使用某种形式的依赖注入,它会被配置为知道如何创建一个IProductService并将其提供给您现有的构造函数。


推荐阅读