c# – Help with Action Edit and Delete returning null

Question:

I'm developing an application but I have a problem with Actions Edit and Delete. I've looked at the code several times, but when calling the actions mentioned, it gives the following error:

The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Edit(Int32)' in 'appXXX.Presentation.Controllers.XXXController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.

Parameter name: parameters

What I'm noticing is that, for some reason that I haven't been able to identify, the “id” parameter in the aforementioned actions is returning null. can anybody help me? I will post the code below summarized and adapted:

In the DOMAIN layer:

public interface IRepositoryBase<TEntity> where TEntity : class
{
    IEnumerable<TEntity> GetAll();        
    TEntity GetById(int id);
    void Update(TEntity entity);
    void Save();
    void Add(TEntity entity);
    void Delete(TEntity entity);
    void Dispose();
}

public interface IServiceBase<TEntity> where TEntity : class
{
    IEnumerable<TEntity> GetAll();
    TEntity GetById(int id);
    void Update(TEntity entity);
    void Save();
    void Add(TEntity entity);
    void Delete(TEntity entity);
    void Dispose();
}

public class ServiceBase<TEntity> : IDisposable, IServiceBase<TEntity> where TEntity : class
{
    private readonly IRepositoryBase<TEntity> _repository;

    public ServiceBase(IRepositoryBase<TEntity> repository)
    {
        _repository = repository;
    }

    public void Delete(TEntity entity)
    {
        _repository.Delete(entity);
    }

    public TEntity GetById(int id)
    {
        return _repository.GetById(id);
    }

    public IEnumerable<TEntity> GetAll()
    {
        return _repository.GetAll();
    }
}

In the INFRA Layer:

public class RepositoryBase<TEntity> : IDisposable, IRepositoryBase<TEntity> where TEntity : class
{
    protected AppContext context = new AppContext();

    public void Add(TEntity entity)
    {
        context.Set<TEntity>().Add(entity);
    }

    public void Delete(TEntity entity)
    {
        context.Set<TEntity>().Remove(entity);
    }

    public TEntity GetById(int id)
    {
        return context.Set<TEntity>().Find(id);
    }        

    public IEnumerable<TEntity> GetAll()
    {
        return context.Set<TEntity>().ToList();
    }
}

In the APPLICATION Layer:

public interface IAppServiceBase<TEntity> where TEntity : class
{
    IEnumerable<TEntity> GetAll();
    TEntity GetById(int id);
    void Update(TEntity entity);
    void Save();
    void Add(TEntity entity);
    void Delete(TEntity entity);
    void Dispose();
}

public class AppServiceBase<TEntity> : IDisposable, IAppServiceBase<TEntity> where TEntity : class
{
    private readonly IServiceBase<TEntity> _serviceBase;

    public AppServiceBase(IServiceBase<TEntity> serviceBase)
    {
        _serviceBase = serviceBase;
    }

    public void Add(TEntity entity)
    {
        _serviceBase.Add(entity);
    }

    public void Delete(TEntity entity)
    {
        _serviceBase.Delete(entity);
    }

    public TEntity GetById(int id)
    {
        return _serviceBase.GetById(id);
    }

    public IEnumerable<TEntity> GetAll()
    {
        return _serviceBase.GetAll();
    }
}

In the PRESENTATION Layer (CONTROLLER):

public class BankController : Controller
{
    private readonly IBankAppService _bankApp;

    public BankController(IBankAppService bankApp)
    {
        _bankApp = bankApp;
    }

    // GET: Bank
    public ActionResult Index()
    {
        var bankViewModel = Mapper.Map<IEnumerable<Bank>, IEnumerable<BankViewModel>>(_bankApp.GetAll());
        return View(bankViewModel);
    }

    // GET: Bank/Edit/5
    public ActionResult Edit(int id)
    {

        var bankDomain = _bankApp.GetById(id);
        var bankViewModel = Mapper.Map<Bank, BankViewModel>(bankDomain);

        return View(bankViewModel);
    }

    //POST: Bank/Edit/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(BankViewModel _bank)
    {
        if (ModelState.IsValid)
        {
            var bankDomain = Mapper.Map<BankViewModel, Bank>(_bank);
            _bankApp.Update(bankDomain);
            _bankApp.Save();

            return RedirectToAction("Index");
        }

        return View(_bank);
    }


    // GET: Bank/Delete/5
    public ActionResult Delete(int id)
    {
        var bankDomain = _bankApp.GetById(id);
        var bankViewModel = Mapper.Map<Bank, BankViewModel>(bankDomain);

        return View(bankViewModel);
    }

    // POST: Bank/Delete/5
    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(int id)
    {
        var bankDomain = _bankApp.GetById(id);
        _bankApp.Delete(bankDomain);
        _bankApp.Save();

        return RedirectToAction("Index");
    }
}

As you can see the code is a generic repository and some methods I haven't posted to reduce the size. I've done it in several ways based on examples on the internet and projects that I downloaded, but then in execution, when you click on the item (a List-type View), the Action Edit is not called because the id returns null.

The Create Action works and the GetAll() function also works. The problem is with Edit and consequently with Delete tbm. I can't figure out what's wrong.

Answer:

Take a look at your view , when you click the button the id field is going null, probably because you don't have an input name="id" in your view . Or if it has, it has a null value. You can also change the public ActionResult Edit(int id) to public ActionResult Edit(int? id) , which will then accept null values. But since it's for editing, I think you really need to pass the value in the id. Anything posts your view too.

Scroll to Top