0

I have a situation in my MVC5 App (Oracle Backend) wherein I must store the current URL when transferring to the GET of a View (this URL contains the User's previous navigated location as well as any/all sort/filter criteria set forth on the data-grid).

At first I thought I had figured this out by using a Session variable, Session["returnURL"], but while it functioned on my localhost, numerous attempts still lead to my session variable throwing a NullReferenceException during execution on my Production Server. I now have the following on my GET Edit action:

        if (Request.UrlReferrer.AbsoluteUri != null)
        {
            ViewBag.ReturnURL = Request.UrlReferrer.AbsoluteUri;
        }
        else
        {
            ViewBag.ReturnURL = null;
        }

If the above value is not null, I store it in the ViewBag to access on my View (specifying it as the href on an actionlink):

         @{
                if (ViewBag.ReturnURL == null)
                {
                    <span class="btn btn-default">
                        @Html.ActionLink("Back to List", "Index", "Home", new { @class = "btn btn-default" })
                    </span>
                }
                else
                {
                    <a href="@ViewBag.ReturnURL"><span class="btn btn-default">Back to List</span></a>
                }
            }
                     |
                    <input type="submit" value="Save"  class="btn btn-primary" />

My problem now is that when I attempt to Save changes to my record (thereby entering the POST of my Edit Action), I receive:

Server Error in '/' Application. Value cannot be null or empty. Parameter name: url. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.ArgumentException: Value cannot be null or empty. Parameter name: url

The below is the relevant code of my POST Edit Action:

        if (ModelState.IsValid)
        {
            iNV_Assets.MODIFIED_DATE = DateTime.Now;
            iNV_Assets.MODIFIED_BY = System.Environment.UserName;

            db.Entry(my_Model).State = EntityState.Modified;
            await db.SaveChangesAsync();

            var returnURL = ViewBag.ReturnURL;
            return Redirect(returnURL);
        }

The record gets saved with whatever changes I make, but then the error is thrown when attempting to redirect back to the main View with the User's previous URL (and all specified search criteria).

Does anyone know why my ViewBag.ReturnURL is coming through as NULL on the POST Edit Action result? Any thoughts on how to achieve what I'm after with an alternative solution perhaps?

tereško
  • 58,060
  • 25
  • 98
  • 150
Analytic Lunatic
  • 3,853
  • 22
  • 78
  • 120

5 Answers5

6

any values that you want to get posted back need to be in an input field inside your form tag so put this somewhere inside your form

<input type="hidden" value="@ViewBag.ReturnURL" name="returnURL" />

then you need to either add a parameter to your action named string returnUrl or use Request.Form. other option includes adding property to your model and setting it and adding hidden field for that property

I use this from time to time. Change your view to

@if (ViewBag.ReturnURL == null)
{
    <span class="btn btn-default">
        @Html.ActionLink("Back to List", "Index", "Home", new { @class = "btn btn-default" })
    </span>
}
else
{
    <a href="@ViewBag.ReturnURL"><span class="btn btn-default">Back to List</span></a>
    <input type="hidden" value="@ViewBag.ReturnURL" id="returnURL" />
}

then change your edit action to

[HttpPost]
public ActionResult Edit(ModelName my_Model, string returnURL)
{
    if (ModelState.IsValid)
    {
        iNV_Assets.MODIFIED_DATE = DateTime.Now;
        iNV_Assets.MODIFIED_BY = System.Environment.UserName;

        db.Entry(my_Model).State = EntityState.Modified;
        await db.SaveChangesAsync();

        if (!string.IsNullOrEmpty(returnURL))
            return Redirect(returnURL);
    }
    return View(my_Model);
}
user5103147
  • 221
  • 1
  • 6
2

Thats the normal behavior, viewbag is set to null when you redirect.

Solution is to use TempData

meda
  • 45,103
  • 14
  • 92
  • 122
  • 1
    Interesting. Do you have an example of using the TempData solution for the GET/POST action methods? – Analytic Lunatic Jul 10 '15 at 19:16
  • i dont think they are wanting to pass the url from one action to another.. they want to pass the value from contoller to view.. then post back to controller – user5103147 Jul 10 '15 at 19:19
  • this method is covered under the BAD WAY of using TempData section of the article – user5103147 Jul 10 '15 at 19:25
  • @user5103147, do you have a better idea of how to go about this outside of the BAD WAY of using TempData? – Analytic Lunatic Jul 10 '15 at 19:45
  • @user5103147 It could be bad, depending on how you use it, I prefer to use viewmodels anyway – meda Jul 10 '15 at 19:45
  • @meda, I'm getting the same result with `TempData["ReturnURL"]` coming through as NULL on my POST Edit Action just as ViewBag.ResultURL did.....? Actually it even comes through to the View as NULL even though the Controller is correctly specifying it's value using the AbsoluteUri. – Analytic Lunatic Jul 10 '15 at 20:42
0

I ended up being able to use Session["variables"] for my Solution after all. I found the answer in this post (The Session object is null in ASP.NET MVC 4 webapplication once deployed to IIS 7 (W 2008 R2)), wherein I modified my <modules> section to do an add/remove of the below specified values:

  <configuration>
  ...
  <system.webServer>
    ...
    <modules>
      <remove name="Session" />
      <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
      ...
    </modules>
  </system.webServer>
</configuration>

I'm still not entirely sure WHY this is the answer, but it worked for my issue in this case.

Analytic Lunatic
  • 3,853
  • 22
  • 78
  • 120
0

You can also use hidden field in Razor

        @{
            if (ViewBag.ReturnURL == null)
            {
                <span class="btn btn-default">
                    @Html.ActionLink("Back to List", "Index", "Home", new { @class = "btn btn-default" })
                </span>
            }
            else
            {
                <a href="@ViewBag.ReturnURL"><span class="btn btn-default">Back to List</span></a>
            }
        }
                 @Html.Hidden("returnURL", (string)ViewBag.ReturnURL)
                <input type="submit" value="Save"  class="btn btn-primary" />

and in controller

[HttpPost]
public ActionResult Edit(ModelName my_Model, string returnURL)
{
if (ModelState.IsValid)
{
    iNV_Assets.MODIFIED_DATE = DateTime.Now;
    iNV_Assets.MODIFIED_BY = System.Environment.UserName;

    db.Entry(my_Model).State = EntityState.Modified;
    await db.SaveChangesAsync();

    if (!string.IsNullOrEmpty(returnURL))
        return Redirect(returnURL);
}
return View(my_Model);
}
Aitezaz Bilal
  • 13
  • 2
  • 5
0

Storing in Session variable works

eg: Session["OldQuantity"] = purchaseStock.purchase_quantity;

subramanya46
  • 451
  • 6
  • 9