0

I have a project where I report time on diffrent projects, and I am working on so I can delete a report incase I do it wrong, which is working decent. When I go to the summery page of all my reports it lists all the dates, I click the date and it sends it to the TimeReport view like this:

http://localhost:9061/Reports/TimeReport/b604a74a-2034-4916-9534-57788db1e8e2

And than it checks if the ReportId has a value like this:

                                @if (Model.ReportId.HasValue)
                            {
                                <button type="button" class="btn btn-danger" data-toggle="modal" data-target="#basic">Ta bort!</button>
                            }

And if it exists a Remove button will appear, I click the remove button and it will remove the report. but the URL is still the same, so if I refresh the site my application will crash because it that ID no longer exists in the database.

            if (form != null && form.AllKeys.Contains("delete"))
        {
            new DatabaseLayer().DeleteTimeReport(Guid.Parse(form["ReportId"]));
            LoadDefaultSettings(projectData);
            ViewData.Model = projectData;
            ViewData["deleted"] = true;
            return View();
        }

This is the model that check if if the GUID exists.

public void SaveToDatabase(Guid consultantId)
        {
            using (DatabaseLayer db = new DatabaseLayer())
            {
                //Time report exists, delete it.
                if (ReportId.HasValue)
                {
                    db.DeleteTimeReport(ReportId.Value);
                }
                //Time report does not exist, create a new one.
                else
                {
                    ReportId = Guid.NewGuid();
                }


                Report report = new Report
                {
                    FK_ConsultantID = consultantId,
                    FK_UserID = Constants.UserTreetop,
                    Date = Date,
                    TimeReportID = ReportId.Value
                };

                TimeReportData reportData = new TimeReportData
                {
                    Absent = 0,
                    Description = "",
                    StartHour = Times.StartHour,
                    StartMinute = Times.StartMinute,
                    EndHour = Times.EndHour,
                    EndMinute = Times.EndMinute,
                    BreakHour = Times.BreakHour,
                    BreakMinute = Times.BreakMinute,
                    FK_TimeReportID = ReportId.Value,
                    TimeReportDataID = Guid.NewGuid()
                };

                TimeReportProject[] reportProjects = new TimeReportProject[Projects.Count];
                for (int i = 0; i < Projects.Count; i++)
                {
                    reportProjects[i] = new TimeReportProject
                    {
                        Description = Projects[i].Description,
                        FK_ProjectID = Projects[i].ProjectId,
                        FK_TimeReportID = ReportId.Value,
                        Hours = Projects[i].Hours.GetValueOrDefault(), //Projects[i].Hours.Value,
                        HourRate = db.GetProjectHourRate(Projects[i].ProjectId, Date, Projects[i].Hours.GetValueOrDefault()),
                        TimeReportProjectID = Guid.NewGuid()
                    };
                }

                db.InsertTimeReport(report, reportData, reportProjects);
            }
        }

And as it exists it does this

        public void DeleteTimeReport(Guid timeReportId)
    {

        db.ExecuteStoreCommand(
            @"  DELETE FROM [Salesweb].[dbo].[TimeReportProject] WHERE FK_TimeReportID = @id;
                DELETE FROM [Salesweb].[dbo].[TimeReportData] WHERE FK_TimeReportID = @id;
                DELETE FROM [Salesweb].[dbo].[TimeReport] WHERE TimeReportID = @id;"
            , new SqlParameter("@id", timeReportId));

        db.SaveChanges();
    }

This is the view when I pass in the guid I Want to delete as the guid has a value the remove button will appear. enter image description here

But as I delete the project it will return to the same view. Like we can see the tabs is not showing up, so if I want the to show again I have to go to another view, and than back to the same view. And if I refresh it will crash due the guid dosen't exist in the DB. enter image description here

And here is the whole controller, it's a bit messy right now.

public ActionResult TimeReport(FormCollection form, Guid? id)
    {
        ViewDataDictionary vd = new ViewDataDictionary
        {
            ["projects"] = new DatabaseLayer().GetConsultantProjects(Constants.CurrentUser(User.Identity.Name)),
            ["id"] = 1,
            ["showDescription"] = true
        };
        ViewData["vd"] = vd;

        NewTimeReportModel projectData = new NewTimeReportModel();

        if (form != null && form.AllKeys.Contains("delete"))
        {
            new DatabaseLayer().DeleteTimeReport(Guid.Parse(form["ReportId"]));
            LoadDefaultSettings(projectData);
            ViewData.Model = projectData;
            ViewData["deleted"] = true;
            return RedirectToAction("Index");
        }

        if (id.HasValue && (form == null || form.AllKeys.Length == 0))
        {
            using (DatabaseLayer db = new DatabaseLayer())
            {
                var timeReport = db.GetTimeReport(id.Value);
                projectData = new NewTimeReportModel(timeReport);
                if (projectData.Projects.Count == 1)
                    projectData.Projects[0].Hours = null;
            }
        }
        else if (form == null || form.AllKeys.Length == 0)
        {
            LoadDefaultSettings(projectData);
        }
        else
        {
            //Get's all the dates from the view and formates them to look like yy-mm-dd so we can parse it to a datetime.
            string[] dates = FormateDate(form["date"]);
            //Loops over all the dates and saves the dates to the database.
            projectData = ReportDates(form, projectData, dates);
            //Loads default settings if all dates been reported.
            LoadDefaultSettings(projectData);
        }
        //Get's and lists all the missing days
        ListAllMssingDays();
        ViewData.Model = projectData;
        return View();
    }

2 Answers 2

1

Recommended thing to do in such cases is run redirect to some default URL, like the summary page. Guessing that you have Summary action, that should be something like:

if (form != null && form.AllKeys.Contains("delete"))
{
    new DatabaseLayer().DeleteTimeReport(Guid.Parse(form["ReportId"]));
    return RedirectToAction("Summary", "Reports");
}

Note that this will do a client-side redirect, so to say - this will do a response with code 302 and new URL /Reports/Summary. This is usually a desired behavior though.

Sign up to request clarification or add additional context in comments.

3 Comments

This still makes it so it reloads with the ID that is being sent it, and since the ID no longer exist the application crashes.
@JoakimCarlsson, but why are you reloading the same page with deleted id?
@JoakimCarlsson, anyway, you can do SingleOrDefault and if result is null do the same redirect
0

The exception you're getting is because your code assumes the item you're deleting will exist.

Change

return db.TimeReports.Where(x => x.TimeReportID == timeReportId).Single();

To

return db.TimeReports.Where(x => x.TimeReportID == timeReportId).SingleOrDefault();

Which will return null if your Where clause returns 0 items.

Then wherever in your code you're calling GetTimeReport() you need to check for and handle null.

4 Comments

It kinds works, but the URL is still with the GUID and as long as my GUID is in the url it dosen't load the dates that I have not reportet a time for, so I have to go another view, and than back to the same view to see those dates. Or edit the URL manualy.
Can you include the entire controller action?
Sorry I mean the controller action for your delete requests and also the controller action for the normal requests.
Done, I am sorry for the delay my internet went offline for a couple of hours.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.