Have you tried adding the [HttpPost] attribute to your EditProfile method ?
Yes I've tried that already :/
The thing is that I recently found an almost identical MVC setting which works.
The controller inherits the same data in both controllers of the same PageType, the routing matches and the post is also the same, but one of them works while the other one doesn't get currentPage values.
Here's a link to my StackOverflow post about the same issue, I'll add more extensive code here aswell.
Working controller:
namespace BlocketProject.Controllers { public class ProfilePageController : PageController<ProfilePage> { public ActionResult EditProfile(ProfilePage currentPage) { var model = new ProfilePageViewModel(currentPage); model.CurrentUser = ConnectionHelper.GetUserInformationByEmail(User.Identity.Name); return View("EditProfile", model); } } }
"Broken" controller:
namespace Intranet.Controllers { public class ProfilePageController : PageController<ProfilePage> { public ActionResult EditProfile(ProfilePage currentPage) { ProfilePageViewModel model = new ProfilePageViewModel(currentPage); model.currentUser = ConnectionHelper.GetCurrentUserByEmail(User.Identity.Name); return View("EditProfile", model); } } }
Working form(posted from _Layout file):
@using (Html.BeginForm("EditProfile", "ProfilePage", FormMethod.Post)) { <li> <button type="submit" class="dropdownButton"> Redigera Profil </button> </li> }
"Broken" form(posted from a block, but also tried from other pages and _Layout):
@using (Html.BeginForm("EditProfile", "ProfilePage", FormMethod.Post)) { <button type="submit">Redigera profil</button> }
Both have the following MVC routing:
using System; using System.Web.Mvc; using System.Web.Routing; namespace Intranet { public class EPiServerApplication : EPiServer.Global { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); } protected override void RegisterRoutes(RouteCollection routes) { base.RegisterRoutes(routes); routes.MapRoute( "Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = "" }); } } }
And I'm all out of ideas of what could be causing this.
ModelBinding for parameter "currentPage" requires that the request has been routed through a EPiServer route (serving urls like http://mysite/some/cms/structure/page) and will not work for standard MVC routed request like http://mysite/home/edit, where home is home controller and edit an action on home controller).
So could it be that the request controller that have currentPage is requested through an ordinary MVC route?
Maybe, but I find it weird because they are coded the same way and both work towards the url 'ProfilePage/EditProfile', and one of them works while the other one doesn't.
And I cannot exactly see what happens inbetween the post and the retrieval of the currentPage in the controller, which is why it is so hard to locate the problem.
Do you have any suggestions of where I can look for the problem?
When you in ProfileBlockController do a RedirectToAction("Index", model), it will always jump back to the Index method of ProfileBlockController. If you want to redirect to another controller (which seems to be what you want to do), you need to supply the routeValues argument to, indicating which controller you're aiming at.
Also, consider what Johan said earlier. If you're executing ProfilePage/EditProfile, you're essentialy using the default route that you've configured, and this is executed outside Episerver context. CurrentPage will always be null in such a route.
If you want to redirect to an episerver page you need to resolve the URL to that page, see http://stackoverflow.com/questions/22327056/redirect-to-another-any-episerver-page-from-mvc-controller
In this specific scenario I would just add a PageReference property to the start page and browse the profile page (you have one in the site's page tree right?) and use a standard link to the EditProfile action on the profile page. As far as I can see, no form post is required here?
On your start page model:
public virtual PageReference ProfilePageLink { get; set; }
On your block view model:
public PageReference ProfilePageLink { get; set; } // You need to set this property in your block controller by fetching start page and get the value of the property.
And in your block view, if the user doesn't have an image:
<a href="@Url.ContentActionUrl(Model.ProfilePageLink, "EditProfile")">@Model.CurrentUser.FirstName @Model.CurrentUser.LastName har ingen profilbild. Klicka här för att lägga till en.</a>
Url.ContentActionUrl is a custom extension method:
public static string ContentActionUrl(this UrlHelper urlHelper, ContentReference contentLink, string actionName) { var actionUrl = new UrlBuilder(urlHelper.ContentUrl(contentLink)); actionUrl.Path = VirtualPathUtility.AppendTrailingSlash(actionUrl.Path) + actionName; return actionUrl.ToString(); }
I'm having some issues with EPiServer/MVC where my currentPage gets null.
What I'm trying to do is redirect from a ProfileBlock that shows a little information from the Profile of the user, which is located in a ContentArea on the StartPage, to a full ProfilePage with all information about the user, where the user also can edit his/her own information.
But the currentPage is null because I'm trying to retrieve a ProfilePage, but I'm redirected from a ProfileBlock on the StartPage so it always ends up as null.
Is there any good way or 'proper' way of doing this?
Here's my blockcontroller:
And in this block if the user doesn't have an image, this link will be shown:
And when you click it you enter the controller for the ProfilePage:
Any ideas?
Regards
Ludvig Flemmich