0

So, basically the web site shows the user a drop down list to choose a category. The following action is used to let the user select a category and show the items:

    public ActionResult SelectResourceCategory()
    {
        return View(new ResourceModel());
    }

    [HttpPost]
    public ActionResult SelectResourceCategory(ResourceModel rm)
    {
        Resource r = new Resource();
        r.CategoryID = rm.Categories.Id;
        List<Resource> GetCourses = new UserBL().GetResourcesByCategoryID(r.CategoryID);
        var vRM = new List<ResourceModel>();

        foreach (Resource rs in GetCourses)
        {
            ResourceModel frm = new ResourceModel();
            frm.ResourceID = rs.Id;
            frm.Title = rs.Title;
            frm.Description = rs.Description;
            frm.Price = (float)rs.Price;
            vRM.Add(frm);
        }

        return View("ShowResources", vRM);
    }

    public ActionResult ShowResources()
    {
        return View();
    }

After the user chooses, the webpage then shows the user a list of available resources which the user can buy. Using the link below, I pass the resourceID of the chosen item as parameter:

@Html.ActionLink("Buy", "BuyResource", new RouteValueDictionary(new { id = item.ResourceID }))

and the Action "BuyResource" does the following:

        public ActionResult BuyResource(int id)
    {
        Session["Rid"] = id; //GOTO: RedirectFromPayPal
        Resource r = new UserBL().GetResourceByID(id);
        return View(r);
    }

THE PROBLEM: When the user clicks "Buy", for some reason, the page redirects the user back to the page where he needs to select a category, specifically "SelectResourceCategory" action. It should be redirecting to the "BuyResource" Action and I do not understand why it's not doing so.

EDIT:

The SelectResourceCategory VIEW:

@model SSD.Models.ResourceModel

@{
ViewBag.Title = "SelectResourceCategory";
Layout = "~/Views/Shared/UserPage.cshtml";
}

<h2>SelectResourceCategory</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
    <legend>ResourceModel</legend>

    <div class="editor-field">
        @Html.DropDownListFor(model => model.Categories.Id, Model.CategoryList)
        @Html.ValidationMessageFor(model => model.Categories.Id)
    </div>

    <p>
        <input type="submit" value="Show available resources" />
    </p>
</fieldset>
}

Routing settings:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}", // URL with parameters
            new { controller = "Home", action = "Index", id = "" } // Parameter defaults
        );



    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }
tereško
  • 58,060
  • 25
  • 98
  • 150
GomuGomuZoro
  • 313
  • 1
  • 4
  • 16

2 Answers2

2

Try to include the target controller's name:

@Html.ActionLink("Buy", "BuyResource", "YOUR CONTROLLER NAME", 
                 new { id = item.ResourceID })

Also make sure item.ResourceID is convertable to a int.

UPDATE:

in your:

routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}", // URL with parameters
        new { controller = "Home", action = "Index", id = "" } // Parameter defaults
    );

The id="" is unnecessary, it might disturb your routing. You might want to consider to use the default implementation:

routes.MapRoute(
      "Default",
      "{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional }
   );
Stefan
  • 17,448
  • 11
  • 60
  • 79
  • I don't think that this is the issue. He wouldn't be redirected back to `SelectResourceCategory` if that was the case instead he would probably get YSOD. – rosko May 07 '14 at 12:49
  • This actually redirects me to the correct Action, however 1 problem remains. The parameter is passed as null, it's not passing the resourceId at all now, even though the resourceId is not null. – GomuGomuZoro May 07 '14 at 12:52
  • @rosko: true, but in my experience it may help to refresh a statement to exclude those annoying easy to overlook errors. :) It seems that that's the case. – Stefan May 07 '14 at 13:00
  • using your 2nd actionlink, the problem where it redirects to "SelectResourceCategory" returns. Using your first actionlink, the url looks like this: http://localhost:49702/User/BuyResource?Length=4 (gives null parameter error) – GomuGomuZoro May 07 '14 at 13:02
  • @user2379498: that's strange, i will alter it. – Stefan May 07 '14 at 13:03
  • Try to pass hardcoded id `@Html.ActionLink("Buy", "BuyResource", new { id = 1})` - how does the link looks like now? – rosko May 07 '14 at 13:10
  • @user2379498: I had this same issue once, I noticed that there was a conflict with some libraries and extension methods. I'll try to find the solution. – Stefan May 07 '14 at 13:14
  • @user2379498: btw: did you alter your `routes.MapRoute`? The `id=""` seems unnecessary. – Stefan May 07 '14 at 13:16
  • @Stefan: I recently added iTextsharp library. Could it be causing any conflicts? – GomuGomuZoro May 07 '14 at 13:21
  • @user2379498: No, I don't think that library has Html.ActionLink extensions. Check this http://stackoverflow.com/a/824318/2416958 maybe it will help you. – Stefan May 07 '14 at 13:22
  • @Stefan: I removed the "id = "" " from routes.MapRoute AND IT WORKED!!! I must have added it for some reason some time ago and forgot about it. It's amazing how something so small can create complicated issues haha. Thank you so much :) – GomuGomuZoro May 07 '14 at 13:27
  • @user2379498: I will put the comment in the answer :) – Stefan May 07 '14 at 13:28
  • Your default route should look like this: `routes.MapRoute(name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });` - i didn't see that you edited your question. – rosko May 07 '14 at 13:30
0

As i wrote in my comment under your question.

You can try:

@Html.ActionLink("Buy", "BuyResource", new { id = item.ResourceID })

or

@Html.ActionLink("Buy", "BuyResource", new RouteValueDictionary{ { id = item.ResourceID } })

Note:

The new RouteValueDictionary(new { id = item.ResourceID }) syntax could be wrong, I can't verify if that's the root of your problem but it's always better to use annonymous class when passing action arguments.

Edit:

Some other more complex example if you wish:

@{
    var routeValues = new RouteValueDictionary();
    routeValues.Add("id", item.ResourceID);
}
@Html.ActionLink("Buy", "BuyResource", routeValues)

Be sure that item.ResourceID is of type int and that it's not null. If it meets those requirements it should be working for 100%.

rosko
  • 464
  • 3
  • 16
  • when I tried it hardcoded, the redirection is still the same: http://localhost:49702/User/SelectResourceCategory I will try your last example. Yes resource id is of type int and is not null. I checked that already to make sure – GomuGomuZoro May 07 '14 at 13:19
  • In `http://localhost:49702/User/SelectResourceCategory` is the `User` the correct controller for buying resources? I don't have any other ideas cause this should be plain simple. There may be some other serious problem in your code but I can't think of any right now. – rosko May 07 '14 at 13:22