0
votes

I have a Details page which displays the event details.

There is a Register button at the bottom of this page.

@using (Html.BeginForm("Register", "Events", new { eventId = Model.Id }, FormMethod.Post, null))
{
    @Html.AntiForgeryToken()
<div id="">
    <p>
        @*<button type="submit" class="btn btn-default" id="btnEnrol" name="btnEnrol" value="@Model.Id" title="Register">Register</button>*@
        <input type="submit" class="btn btn-default" id="btnEnrol" name="btnEnrol" value="Register" />
    </p>
</div>
}

Here is my controller method:

[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult Register(int eventId)
{
    if (eventId == 0)
        return View("Index");

    var now = DateTime.Now;

    var userId = User.Identity.GetUserId();

    var registration = this.repo.GetRegistration(eventId, userId);

    if (registration != null)
    {
        ViewBag.Registered = true;
    }
    else
    {
        var successful = this.repo.RegisterEvent(eventId, userId);

        if (successful)
        {
            return View();
        }
        else
        {
            return View();
        }
    }
    return View();
}

And here is the link after clicked the Register button

http://localhost/lrc/Events/Register?eventId=7

And here is the RouteConfig.cs

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

    //routes.MapRoute(
    //    name: "Home",
    //    url: "Home/{action}/{id}",
    //    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    //);

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

I have read through many posts on SO, but none of them solve my problem.

Something I have also tried:

removed the [HttpPost] annotation, I don't think it helps but it's just a desperate attempt.


Update 1

I added 1 more route in the RouteConfig.cs before the default route:

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

    //routes.MapRoute(
    //    name: "Home",
    //    url: "Home/{action}/{id}",
    //    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    //);url: "Event/Register/{eventId}"

    routes.MapRoute(
        name: "myRoute",
        url: "Events/Register/{eventId}",
        defaults: new { controller = "Events", action = "Register", eventId = UrlParameter.Optional }
    );

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

And then I finally got something different, but it's still an error:

Server Error in '/lrc' Application.

The current type, Microsoft.AspNet.Identity.IUserStore`1[lrc.Models.ApplicationUser], is an interface and cannot be constructed. Are you missing a type mapping?

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.InvalidOperationException: The current type, Microsoft.AspNet.Identity.IUserStore`1[lrc.Models.ApplicationUser], is an interface and cannot be constructed. Are you missing a type mapping?

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[InvalidOperationException: The current type, Microsoft.AspNet.Identity.IUserStore1[lrc.Models.ApplicationUser], is an interface and cannot be constructed. Are you missing a type mapping?]
Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForAttemptingToConstructInterface(IBuilderContext context) +192 lambda_method(Closure , IBuilderContext ) +40
Microsoft.Practices.ObjectBuilder2.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context) +48
Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +323
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +349
Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +254 lambda_method(Closure , IBuilderContext ) +200
Microsoft.Practices.ObjectBuilder2.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context) +48
Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +323
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +349
Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +254 lambda_method(Closure , IBuilderContext ) +202
Microsoft.Practices.ObjectBuilder2.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context) +48
Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +323
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +349
Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable
1 resolverOverrides) +442

[ResolutionFailedException: Resolution of the dependency failed, type = "lrc.Controllers.AccountController", name = "(none)". Exception occurred while: while resolving. Exception is: InvalidOperationException - The current type, Microsoft.AspNet.Identity.IUserStore`1[lrc.Models.ApplicationUser], is an interface and cannot be constructed. Are you missing a type mapping? ----------------------------------------------- At the time of the exception, the container was:

Resolving lrc.Controllers.AccountController,(none) Resolving parameter "userManager" of constructor lrc.Controllers.AccountController(lrc.ApplicationUserManager userManager, lrc.ApplicationSignInManager signInManager) Resolving lrc.ApplicationUserManager,(none) Resolving parameter "store" of constructor lrc.ApplicationUserManager(Microsoft.AspNet.Identity.IUserStore1[[lrc.Models.ApplicationUser, lrc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] store) Resolving Microsoft.AspNet.Identity.IUserStore1[lrc.Models.ApplicationUser],(none) ] Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable1 resolverOverrides) +550
Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name, IEnumerable
1 resolverOverrides) +20
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +78

[InvalidOperationException: An error occurred when trying to create a controller of type 'lrc.Controllers.AccountController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +256
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +169
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +270 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +147
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +12289179 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.34248


Update 2

Here is my EventsController constructor

    private ILRCRepository repo;

    public EventsController(ILRCRepository repository)
    {
        this.repo = repository;
    }

I searched the UserStore throughout the entire project and found it at only one place (inside the IdentityConfig.cs):

// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }
2
what is Irc? are you using areas? - user3559349
hi @StephenMuecke it's just the name of my website - Franva
Does not look to be anything wrong with the code. You have the [Authorize] attribute but the method is named Register suggesting the user is not yet logged in (so would no be authorized). Have you tried with [AllowAnonymous]? - user3559349
hi@StephenMuecke I agree that the code should be alright. I need [Authorize] as only registered users can register an event. - Franva
Have you tried creating a specific route (before the default) - with url: "Event/Register/{eventId}", - user3559349

2 Answers

1
votes

Post will work fine. And as @Stephen noted in the comments, post with an action parameter should work just fine.

As an alternative, if for some reason it doesn't work, you can use a hidden field for the event ID:

Html.Hidden("eventId", Model.Id)

And this will post to the action just fine.

0
votes

I'm suspecting the resource cannot be found has to do with your RouteConfig.cs expecting an {id} and your EventsController expecting an {eventId}.

Change your EventsController method to have int id as the input parameter:

[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult Register(int id)
{
    if (id == 0)
        return View("Index");

    var now = DateTime.Now;

    var userId = User.Identity.GetUserId();

    var registration = this.repo.GetRegistration(id, userId);

    if (registration != null)
    {
        ViewBag.Registered = true;
    }
    else
    {
        var successful = this.repo.RegisterEvent(id, userId);

        if (successful)
        {
            return View();
        }
        else
        {
            return View();
        }
    }
    return View();
}

Or alternately, you could update your RouteConfig.cs to include a route with {eventId}:

        routes.MapRoute(
            name: "Event",
            url: "{Irc}/Events/Register/{eventId}",
            defaults: new { controller = "Events", action = "Register", eventId = UrlParameter.Optional }
        );