简体   繁体   中英

asp.net return same view but delete url?

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. 在此处输入图片说明

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. 在此处输入图片说明

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();
    }

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM