How to execute C# query for request control

Asked

Viewed 330 times

1

I am new to programming and need to add some functionality in a C# Asp.net. One of them is a control that prevents the user from proceeding with the request if he has any pending in the system. I will describe the step by step.

My view

@using Integracao.ImpressoRequests.Model.Entities.ImpressoRequest
@model Request
@{
  ViewBag.Title = "Requisição";
  Layout = "~/Views/Shared/_Layout.cshtml";
}

    ...

    @foreach (RequestItem item in Model.Items)
    {
        <tr>
            <td>
                @Html.DisplayFor(x => item.Usuario.Nome)
            </td>
            <td>
                @Html.DisplayFor(x => item.Date)
            </td>
            <td>
                @Html.DisplayFor(x => item.Unidade.Nome)
            </td>
            <td>
                @Html.DisplayFor(x => item.ResultCenter.Nome)
            </td>
        </tr>
    }
</table>
<div class="formfooter">

    <input type="button" value="Gerar pedido" onclick="window.open('@Url.Action("ProcessRequest", new { requestId = Model.Id })','_blank');window.location.href='@Url.Action("Index", "Home")'" /></div>

Controller

    [HttpGet]
    public ActionResult ProcessRequest(int requestId)
    {
        Request request = _data.Requests.GetByID(requestId);
        if (request.Processed)
            return RedirectToAction("PrintRequest", new { requestId = request });
        foreach (RequestItem item in request.Items.OrderBy(x => x.Usuario_Id))
        {
            AssignImpressos assignIItems = new AssignImpressos(item.Id);
            assignIItems.Assign();
        }
        request.Processed = true;
        _data.Save();
        return RedirectToAction("PrintRequest", new { requestId = request.Id });
    }

Model

    public Request()
    {
        Date = DateTime.Now;
        UsedItems = new List<Impresso>();
        RequestsHistory = new List<RequestHistory>();
        Items = new List<RequestItem>();
    }

    public int Id { get; set; }

    public DateTime? Date { get; set; }

    public string Justification { get; set; }

    public string Usuario_Id { get; set; }

    public virtual Usuario Usuario { get; set; }
    public virtual ICollection<Impresso> UsedItems { get; set; }

    Model Impresso

        public class Impresso : IEntity
{
    public Impresso()
    {
        RequestsHistory = new List<RequestHistory>();
    }

    public int Id { get; set; }

    public int Code { get; set; }

    public string Purpose { get; set; }

    public DateTime? Data_Controle { get; set; }

    public decimal AdjustedValue { get; set; }

    public int Status { get; set; }
    public ItemStatus EnumeratedStatus
    {
        get { return (ItemStatus)Status; }
        set { Status = (int)value; }
    }        
    public string Note { get; set; }

    public string Usuario_Id { get; set; }
    public virtual Usuario Usuario { get; set; }

    public int? Request_Id { get; set; }
    public virtual Request Request { get; set; }

    public string Unidade_Id { get; set; }
    public virtual Unidade Unidade { get; set; }

    public string ResultCenter_Id { get; set; }
    public virtual ResultCenter ResultCenter { get; set; }

    public virtual ICollection<RequestHistory> RequestsHistory { get; set; }

    object IEntity.Id
    {
        get { return Id; }
        set { Id = (int)value; }
    }
}

What I need is the following: For the user to click 'Generate Request' in the view, in my controller class I need to scan the Request table in the database looking if that user already authenticated by the system has in the Printed table the field 'Data_control' null or the Status = 1. If positive, the system shall prevent the continuation by triggering an alert with the information. If false, the program continues and generates the request normally. The question is: I know how to do a select in the database to get it but what is the syntax in c# according to my code to do this control? I thought in query because I work with database and the logic is clearer to me, or if not by query, what would be the best way to achieve this in programming logic anyway? Thank you

Edit

        private string GetUser()
    {
        string userId = string.Empty;
        try
        {
            string id = User.Identity.Name.Split('\\')[1];
            Usuario _currentUsuario = _data.Usuario.GetByID(id);
            userId = _currentUsuario.Id;
            ViewBag.UserName = _currentUsuario.Name;
        }
        catch (Exception ex)
        {
            ModelState.AddModelError("UserName", ex.Message);
        }
        return userId;
    }
  • You want that warning to appear on the screen as?

  • @Ciganomorrisonmendez can be a simple Alert or messagebox... The important thing is to lock the user and go back to the home screen when he gives the ok of aware of not being able to request...

2 answers

2

You can create an Actionfilterattribute for this:

public class VerificarPendencia : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        // Assumindo que você possui um ICollection<Impresso> Impressos para a entidade Usuario, e que esta coleção está populada ao obter o Usuario.
        if (_data.Usuarios.GetByID(GetUser()).Impressos.Any(x => x.Data_Controlle == null && x.Status == 1))
        {
           // Açoes...
        } 
    }
}

Do a little research on Actionfilterattribute to learn the methods you can use. And then you just need to decorate Action with this attribute:

[VerificarPendencia]
[HttpGet]
public ActionResult ProcessRequest(int requestId)

All Actions decorated with this attribute (if you prefer, you can decorate the entire Controller) now go through the methods it creates, such as Onresultexecuting, Onactionexecuted, etc...

  • 1

    I believe the answer would be more useful if the solution provided the steps for the search, not ask the author of the question to search.

  • @I’ve done some research on this method and from what I’ve seen it might be an alternative. But my biggest difficulty is precisely in "// here you do the process".

  • @Ciganomorrisonmendez can give me an example of implementing this response of the Euripedes for me to base myself or another answer that also thinks meets me?

  • Look, I’m not a big fan of this approach to ActionFilters because data validation should be done 1) In Model, or 2) In Controller, when it involves data between two or more Models, which is your case, but it’s a more personal matter. I’ll put two ways to do it, then you choose the best.

  • great :) thank you

  • 1

    @Pfvictor, I understand. From what I saw in the responses, you can use "_data.Usuarios.Getbyid(Getuser()).Impressos.Any(x => x.Data_controlle == null && x.Status == 1", I changed the answer.

  • Thank you @Euripedisloyal!

Show 2 more comments

1

The code is very close to what you need. I imagine that ProcessRequest be that code higher up, so I’d do the following:

[HttpGet]
public ActionResult ProcessRequest(int requestId)
{
    // Estou supondo que aqui você carregue seu usuário dentro de um objeto 'Usuario'
    // var usuario = contexto.Usuarios.SingleOrDefault(u => u.Nome == User.Identity.UserName);
    var usuario = _data.Usuarios.GetByID(GetUser());

    if (contexto.Impresso.Any(i => i.Usuario_Id == usuario.Usuario_Id && (i.Data_Controle == null || i.Status == 1))) {
        ModelState.AddModelError("", "Coloque aqui a mensagem que explica porque o sistema não pode continuar");
        return View();
    }

    Request request = _data.Requests.GetByID(requestId);

    if (request.Processed)
        return RedirectToAction("PrintRequest", new { requestId = request });

    foreach (RequestItem item in request.Items.OrderBy(x => x.Usuario_Id))
    {
        AssignImpressos assignIItems = new AssignImpressos(item.Id);
        assignIItems.Assign();
    }

    request.Processed = true;
    _data.Save();
    return RedirectToAction("PrintRequest", new { requestId = request.Id });
}
  • I have within the same Processrequest controller a Getuser class that identifies the user, which I edited in the question. In that case, the first line I’d trade for var usuario = _data.Usuarios.GetByID(GetUser()); right?

  • @Pfvictor This. By the way, feel free to edit my answer if you want.

  • It worked @Ciganomorrisonmendez. Thanks again.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.