I'm working on an MVC5 application. On the home screen is a grid allowing users to view Data and be transferred to a number of Views for various actions on each record. One of these is an [EDIT].
The issue I'm encountering is as follows: due to the amount of data it is convenient to Filter the data down (say to a specific location) and then Edit records from there. The filter on this grid (Grid.MVC from CodePlex) performs filtering partially by modifying the URL (http://homeURL/?grid-filter=Location.DEPT__1__accounting) such as 1 being Equals, 2 being Cotains, 3 being StartsWith, and 4 being EndsWith and then after the next 2 underscores being the search criteria.
This functions fine, however upon [POST] return from the Edit the user currently is returned to main Index view without the filtering criteria still set (forcing them to go in over and over and add filtering criteria before performing the similar EDIT on records of the same criteria).
My POST-EDIT method is currently setup to include:
if (ModelState.IsValid)
{
collection.MODIFIED_DATE = DateTime.Now;
collection.MODIFIED_BY = System.Environment.UserName;
db.Entry(collection).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index", "Home");
}
For my attempts I had first thought to return the View with the updated collection (return View(collection)
) but this of course just takes me back to the EDIT view, not the home view with the data grid filtered down as previously specified. I considered adding a field in the database, something like LAST_FILTERED_URL, but this just feels like an overgrown band-aid.
Does anyone know of a clean way to go about this?
EDIT:
I had thought to do something similar to Andrea's suggestion early on, but had not thought of doing an explicit redirect with the Parameter of the url-filter passed in the Redirect. Below is my current code for the GET/POST Edit
:
// GET: ENITTY_Collection/Edit/5
public async Task<ActionResult> Edit(int id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ENTITY_COLLECTION entity_Collection = await db.ENTITY_COLLECTION.FindAsync(id);
if (entity_Collection == null)
{
return HttpNotFound();
}
// Other code for Controls on the View
return View(entity_Collection);
}
// POST: ENTITY_Collection/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Id,One_Id,Two_Id,Three_Id,Four_Id,Five_Id,Six_Id,field7,field8,field9,...field18,created_date,created_by,modified_date,modified_by")] ENTITY_COLLECTION entity_Collection)
{
if (ModelState.IsValid)
{
entity_Collection.MODIFIED_DATE = DateTime.Now;
entity_Collection.MODIFIED_BY = System.Environment.UserName;
db.Entry(entity_Collection).State = EntityState.Modified;
await db.SaveChangesAsync();
//return RedirectToAction("Index", "Home");
return View(entity_Collection);
}
// Other code for if Model is Invalid before returning to View.
return View(entity_Collection);
}
I like Andrea's suggestion, but I still need a good way to store the URL the user has when they first navigate to the GET-Edit View
, and then use that filtered URL value to return the user to that previous location & filter option when the POST-Edit
completes and changes have saved.
Any thoughts?
I'm not sure if this is the most correct way of going about what I'm after, but what appears to be working for me is the use of a
Session
value.In my
GET
method I store the URL:Session["returnURL"] = Request.UrlReferrer.AbsoluteUri;
Then in my
POST
I use this value in aRedirect()
after saving changes to the record:So far all initial testing is resulting in a return to the main view with all sorting/filtering criteria in place before the record was entered into for update.
Have you tried changing passing the current filter to redirect to action as follows? Note: I am assuming that:
you have a controller parameter called currentFilterValue
RedirectToAction("Index", "Home",new { grid-filter = currentFilterValue });
The default LoginController for an MVC project from Microsoft includes a bunch of methods that use a returnUrl parameter. Using this practice, you could include a return URL when opening the editor, that when editing is done, returns the user back to the prior screen with the filters intact (assuming they are in the URL).
My base class for view models has a property for storing the ReturnURL, which is then stored as a hidden if set.
My action that posts from edit then has this logic:
In order to prevent some injections, you will want a validation method (called above) like this for ensuring the URL is valid:
Hopefully this gets you some ideas and on the right track.