Problema com ModelState "Dropdownlist"

Boa tarde, pessoal.

Estou com o seguinte problema, tenho 3 telas de cadastro:

Usuario - usuarioId , nome, sobrenome, senha, email, ativo, dataCriacao Projeto - projetoId , descricao, sigla, ativo, dataCriacao Modulo - moduloId , descricao, ativo, dataCriacao, projetoId (FK)

Estou tentando criar uma quarta:

Acesso - acessoId, usuarioId (FK), moduloId (FK), dataCriacao, ativo

Associação de usuário x modulo, classes abaixo, carrego 2 dropdownlist, um com usuario e outro com modulo, porém, quando eu tento cadastrar uma nova associacao (acesso), dá erro de ModelState (inválida), ele carrega os dados do usuário que são obrigatórios. Acredito que seja porque no dropdownlist ele só carrega o Id do que foi selecionado para gravar na tabela de associacao, porém, ele me dá o erro abaixo (imagem) dizendo de outros campos obrigatórios, estou começando a aprender agora, então, não tenho NADA de experiência, estou apenas tentando entender tudo. rsrs Se puderem me ajudar, se eu tiro o required do modelo de Usuario, ele funciona, mas não acho que essa seria a solução ideal ou a correta, alguém poderia me ajudar?

Obrigada!!!

Segue o código HTML:

@model CodigoExpresso01.Models.Acesso

@{
    ViewBag.Title = "Acesso";
    Layout = "~/Views/Shared/_Layout.cshtml";

    List<CodigoExpresso01.Models.Usuario> ListaUsuarios = ViewBag.ListaUsuarios;
    List<CodigoExpresso01.Models.Modulo> ListaModulos = ViewBag.ListaModulos;
}

<br />

<div class="row">
    <div class="row-md-12">


        @using (Html.BeginForm("CadastrarAcesso", "Acesso", null, FormMethod.Post, new { Class = "form-horizontal" }))
        {

            @Html.AntiForgeryToken()
            @Html.ValidationSummary(true)

            @Html.HiddenFor(Model => Model.acessoId)




            <fieldset>
                <legend>
                    Cadastro de Acesso
                </legend>

                <div class="well">

                    <div class="row">
                        <div class="col-md-6">
                            @Html.LabelFor(model => Model.dataCriacao)
                            @Html.TextBoxFor(model => Model.dataCriacao, new { Class = "form-control input-sm" })
                            @Html.ValidationMessageFor(model => Model.dataCriacao)
                        </div>
                        <div class="col-md-6">
                            @Html.LabelFor(model => Model.ativo)
                            @Html.EnumDropDownListFor(model => Model.ativo, new { Class = "form-control input-sm", style = "text-transform: uppercase" })
                            @Html.ValidationMessageFor(model => Model.ativo)
                        </div>
                    </div>

                    <br />

                    <div class="row">
                        <div class="col-md-3">

                        </div>

                        <div class="col-md-3">
                            @Html.LabelFor(model => model.Usuario)
                            <select id="Usuario.usuarioId" name="Usuario.usuarioId" class="form-control input-sm">
                                @foreach (CodigoExpresso01.Models.Usuario item in ListaUsuarios)
                                {
                                    <option value="@item.usuarioId"
                                            @if (item.usuarioId == Model.Usuario.usuarioId) { @: selected
                                            }>
                                        @item.nome
                                    </option>
                                }

                            </select>
                        </div>

                        <div class="col-md-3">
                            @Html.LabelFor(model => model.Modulo)
                            <select id="Modulo.moduloId" name="Modulo.moduloId" class="form-control input-sm">
                                @foreach (CodigoExpresso01.Models.Modulo item in ListaModulos)
                                {
                                    <option value="@item.moduloId"
                                            @if (item.moduloId == Model.Modulo.moduloId) { @: selected
                                            }>
                                        @item.descricao
                                    </option>
                                }

                            </select>
                        </div>
                    </div>

                    <br />


                    <div class="row">
                        <div class="col-md-12 text-right">
                            @if (Model.acessoId > 0)
                            {
                                <button class="btn btn-danger btn-xs" type="button" onclick="MensagemConfirma('Confirma?', 'Deseja excluir o Módulo: @Model.acessoId',
                                '@Url.Action("ConfirmaApagaAcesso", "Acesso", new { acessoId = @Model.acessoId })')">
                                    Excluir
                                </button>
                            }

                            <input class="btn btn-success btn-xs" type="submit" value="Salvar" />

                            <a href="@Url.Action("ListarAcessos", "Acesso")" class="btn btn-primary btn-xs">Cancelar</a>
                        </div>
                    </div>

                </div>

            </fieldset>
        }
    </div>
</div>

@section Scripts
{
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/Mascaras")
}

Segue a Controller:

public ActionResult ListarAcessos()
        {
            string mErro = "";

            DAOAcesso daoAcesso = new DAOAcesso();

            List<Acesso> lacesso = daoAcesso.ListarAcessos();

            if (daoAcesso.isErro())
            {
                mErro = daoAcesso.MensagemErroFormatada();
            }

            if (mErro.Length > 0)
            {
                return View(lacesso).Mensagem(mErro);
            }
            else
            {
                return View(lacesso);
            }
        }

        public ActionResult CadastrarAcesso(int acessoId)
        {
            DAOAcesso daoAcesso = new DAOAcesso();
            DAOModulo daoModulo = new DAOModulo();
            DAOUsuario daoUsuario = new DAOUsuario();

            Acesso acesso = new Acesso();

            if (acessoId > 0)
            {
                acesso = daoAcesso.BuscarAcesso(acessoId);
            }
            else
            {
                acesso.dataCriacao = DateTime.Now;
            }

            ViewBag.ListaModulos = daoModulo.ListarModulos(); //combo de modulos
            ViewBag.ListaUsuarios = daoUsuario.ListarUsuarios(); //combo de usuarios

            return View(acesso);
        }

        [HttpPost]
        public ActionResult CadastrarAcesso(Acesso acesso)
        {
            DAOAcesso daoAcesso = new DAOAcesso();
            DAOModulo daoModulo = new DAOModulo();
            DAOUsuario daoUsuario = new DAOUsuario();

            if (ModelState.IsValid)
            {
                if (acesso.acessoId == 0)
                {
                    daoAcesso.IncluirAcesso(acesso);
                }
                else
                {
                    daoAcesso.AlterarAcesso(acesso);
                }

                return RedirectToAction("ListarAcessos", "Acesso").Mensagem(daoAcesso.MensagemErroFormatada());
            }

            ViewBag.ListaModulos = daoModulo.ListarModulos();
            ViewBag.ListaUsuarios = daoUsuario.ListarUsuarios();

            return View(acesso);
        }

        public ActionResult ConfirmaApagaAcesso(int acessoId)
        {
            string mErro = "";

            if (acessoId > 0)
            {
                DAOAcesso daoAcesso = new DAOAcesso();
                daoAcesso.ExcluirAcesso(acessoId);
                mErro = daoAcesso.MensagemErroFormatada();
            }
            return RedirectToAction("ListarAcessos", "Acesso").Mensagem(mErro);
        }

Segue a DAO

Funcoes funcoes = new Funcoes();

        //Modulo = Acesso
        public List<Acesso> ListarAcessos()
        {
            // Instancia nossos objetos
            List<Acesso> lacessos = new List<Acesso>();
            Acesso acesso = new Acesso();

            // Instancia nossa Conexao
            Conexao conexao = new Conexao(TipoConexao.Conexao.WebConfig);

            // Se existe erro na conexao move o erro para a classe de acesso 
            if (conexao.ExisteErro())
            {
                setMensagemErro(conexao.mErro);
                return lacessos;
            }

            try
            {
                SqlDataReader reader;

                // Nosso comando SQL
                string query =
                    "select a.acessoId, a.ativo, a.dataCriacao, " +
                    "       u.usuarioId, u.nome, " +
                    "       m.moduloId, m.descricao, " +
                    "       p.projetoId, descricao_projeto = p.descricao, p.sigla, " +
                    "       u.cpf, u.sobrenome, u.email, u.senha " +
                    "  from modulo m, acesso a, usuario u, projeto p " +
                    " where a.moduloId = m.moduloId " +
                    " and a.usuarioId = u.usuarioId " +
                    " and m.projetoId = p.projetoId " +
                    " ORDER BY u.nome, m.descricao ";

                SqlCommand cmd = new SqlCommand(query, conexao.conn);

                // define que o comando é um texto
                cmd.CommandType = System.Data.CommandType.Text;

                // Abre nossa Conexao
                if (conexao.OpenConexao() == false)
                {
                    setMensagemErro(conexao.mErro);
                    return lacessos;
                }

                reader = cmd.ExecuteReader();

                // recebe os dados de nossa consulta
                while (reader.Read())
                {
                    lacessos.Add(read_Acesso(reader));
                }
            }
            catch (SqlException e)
            {
                // Trata os erros de nossa conexão
                setMensagemErro(e.Message.ToString());
            }

            // Fecha nossa Conexao
            conexao.CloseConexao();

            // Retorna nossa lista de dados
            return lacessos;
        }

        public Acesso BuscarAcesso(int acessoId)
        {
            Acesso acesso = new Acesso();

            // Instancia nossa Conexao
            Conexao conexao = new Conexao(TipoConexao.Conexao.WebConfig);

            // Se existe erro na conexao move o erro para a classe de acesso 
            if (conexao.ExisteErro())
            {
                setMensagemErro(conexao.mErro);
                return acesso; //retorna modelo vazio
            }

            try
            {
                SqlDataReader reader;

                SqlCommand cmd = new SqlCommand("[pcdAcesso_Slc_ID]", conexao.conn);

                cmd.CommandType = System.Data.CommandType.StoredProcedure;

                cmd.Parameters.AddWithValue("@acessoId", acessoId);

                // Abre nossa Conexao
                if (conexao.OpenConexao() == false)
                {
                    setMensagemErro(conexao.mErro);
                    return acesso;
                }

                reader = cmd.ExecuteReader();

                // recebe os dados de nossa consulta
                while (reader.Read())
                {
                    acesso = read_Acesso(reader);
                }
            }
            catch (SqlException e)
            {
                // Trata os erros de nossa conexão
                setMensagemErro(e.Message.ToString());
            }

            // Fecha nossa Conexao
            conexao.CloseConexao();

            // Retorna nossa lista de dados
            return acesso;
        }

        public int IncluirAcesso(Acesso acesso)
        {
            Int32 _return = 0; 
            // Instancia nossa Conexao
            Conexao conexao = new Conexao(TipoConexao.Conexao.WebConfig);

            // Se existe erro na conexao move o erro para a classe de acesso 
            if (conexao.ExisteErro())
            {
                setMensagemErro(conexao.mErro);
                return -1; //retorna modelo vazio
            }

            try
            {
                SqlDataReader reader;

                SqlCommand cmd = new SqlCommand("[pcdAcesso_Ins]", conexao.conn);

                cmd.CommandType = System.Data.CommandType.StoredProcedure;

                cmd.Parameters.AddWithValue("@usuarioId", acesso.Usuario.usuarioId);    
                cmd.Parameters.AddWithValue("@moduloId", acesso.Modulo.moduloId);
                cmd.Parameters.AddWithValue("@ativo", acesso.ativo);
                cmd.Parameters.AddWithValue("@dataCriacao", acesso.dataCriacao);

                // Abre nossa Conexao
                if (conexao.OpenConexao() == false)
                {
                    setMensagemErro(conexao.mErro);
                    return -1;
                }

                reader = cmd.ExecuteReader();

                // recebe os dados de nossa consulta
                while (reader.Read())
                {
                    _return = Convert.ToInt32(reader["retorno"]);
                }
            }
            catch (SqlException e)
            {
                // Trata os erros de nossa conexão
                setMensagemErro(e.Message.ToString());
                _return = -1;
            }

            // Fecha nossa Conexao
            conexao.CloseConexao();

            // Retorna nossa lista de dados
            return _return;
        }

        public int AlterarAcesso(Acesso acesso)
        {
            Int32 _return = 0;
            // Instancia nossa Conexao
            Conexao conexao = new Conexao(TipoConexao.Conexao.WebConfig);

            // Se existe erro na conexao move o erro para a classe de acesso 
            if (conexao.ExisteErro())
            {
                setMensagemErro(conexao.mErro);
                return -1; //retorna modelo vazio
            }

            try
            {
                SqlCommand cmd = new SqlCommand("[pcdAcesso_Upd]", conexao.conn);

                cmd.CommandType = System.Data.CommandType.StoredProcedure;

                cmd.Parameters.AddWithValue("@acessoId", acesso.acessoId);
                cmd.Parameters.AddWithValue("@usuarioId", acesso.Usuario.usuarioId);
                cmd.Parameters.AddWithValue("@moduloId", acesso.Modulo.moduloId);
                cmd.Parameters.AddWithValue("@ativo", acesso.ativo);
                cmd.Parameters.AddWithValue("@dataCriacao", acesso.dataCriacao);

                // Abre nossa Conexao
                if (conexao.OpenConexao() == false)
                {
                    setMensagemErro(conexao.mErro);
                    return -1;
                }

                _return = cmd.ExecuteNonQuery(); //retorna qts registros alterou
            }
            catch (SqlException e)
            {
                // Trata os erros de nossa conexão
                setMensagemErro(e.Message.ToString());
                _return = -1;
            }

            // Fecha nossa Conexao
            conexao.CloseConexao();

            // Retorna nossa lista de dados
            return _return;
        }

        public int ExcluirAcesso(Acesso acesso)
        {
            return ExcluirAcesso(acesso.acessoId);
        }

        public int ExcluirAcesso(int acessoId)
        {
            Int32 _return = 0;
            // Instancia nossa Conexao
            Conexao conexao = new Conexao(TipoConexao.Conexao.WebConfig);

            // Se existe erro na conexao move o erro para a classe de acesso 
            if (conexao.ExisteErro())
            {
                setMensagemErro(conexao.mErro);
                return -1; //retorna modelo vazio
            }

            try
            {
                SqlCommand cmd = new SqlCommand("[pcdAcesso_Del]", conexao.conn);

                cmd.CommandType = System.Data.CommandType.StoredProcedure;

                cmd.Parameters.AddWithValue("@acessoId", acessoId);

                // Abre nossa Conexao
                if (conexao.OpenConexao() == false)
                {
                    setMensagemErro(conexao.mErro);
                    return -1;
                }

                _return = cmd.ExecuteNonQuery(); //retorna qts registros alterou
            }
            catch (SqlException e)
            {
                // Trata os erros de nossa conexão
                setMensagemErro(e.Message.ToString());
                _return = -1;
            }

            // Fecha nossa Conexao
            conexao.CloseConexao();

            // Retorna nossa lista de dados
            return _return;
        }

        //VER
        public Acesso read_Acesso(SqlDataReader reader)
        {
            DAOModulo daoModulo = new DAOModulo();
            DAOUsuario daoUsuario = new DAOUsuario();

            Acesso acesso = new Acesso();
            acesso.acessoId = ConverteReader.ConverteInt(reader["acessoId"]);
            acesso.ativo = funcoes.ConvertEnumAtivo(reader["ativo"].ToString());
            acesso.dataCriacao = ConverteReader.ConverteDateTime(reader["dataCriacao"]);

            acesso.Modulo = daoModulo.read_Modulo(reader);
            acesso.Usuario = daoUsuario.read_Usuario(reader);

            return acesso;
        }

E minha Model:

[Key]
        public int acessoId { get; set; }

        public Ativo ativo { get; set; }

        public DateTime? dataCriacao { get; set; }

        public Usuario Usuario { get; set; }
        public Modulo Modulo { get; set; }

        public Acesso()
        {
            Usuario = new Usuario();
            //Projeto = new Projeto();
            Modulo = new Modulo();
        }

Model da Usuario

//validações 
        [Key]
        [Display(Name ="Identificação do Usuário")]
        public int usuarioId { get; set; }

        [Display(Name = "CPF")]
        [Required(ErrorMessage = "CPF deve ser informado!")]
        public string cpf { get; set; }

        [Display(Name = "Nome")]
        [Required(ErrorMessage = "Nome deve ser informado.")]
        [StringLength(50, MinimumLength = 4, ErrorMessage = "Nome deve ser maior que 4 e menor que 50!")]
        public string nome { get; set; }

        [Display(Name = "Sobrenome")]
        [Required(ErrorMessage = "Sobrenome deve ser informado!")]
        [StringLength(50, MinimumLength = 4, ErrorMessage = "Sobrenome deve ser maior que 4 e menor que 50!")]
        public string sobrenome { get; set; }

        [Display(Name = "E-mail")]
        [EmailBrasil(ErrorMessage ="E-mail inválido!", EmailRequerido = false)]
        public string email { get; set; }

        [Display(Name = "Senha")]
        public string senha { get; set; }

        [Display(Name = "Status")]
        public Ativo ativo { get; set; }

        [Display(Name = "Data da Criação")]
        public DateTime? dataCriacao { get; set; }

inserir a descrição da imagem aqui