views:

320

answers:

1

I have a form for editing gigs.

The initial controller action is called "Edit".

The form posts to a second controller action called "Update"

So, once the form has posted, I use a bespoke ModelBinder which uses bindingContext.ModelState.AddModelError to add validation messages to the modelstate

The Update copntroller action looks this:

[AcceptVerbs("POST")]
    public ActionResult Update(Guid id, FormCollection formCollection)
    {
        Gig gig = GigManager.GetByID(id);
        try
        {
            UpdateModel<Gig>(gig);
            GigManager.Save(gig);
            return RedirectToAction("List");

        }
        catch (Exception e)
        {
           return View(gig);    
        }

    }

If the modelbinder has errors an exception will be thrown by update model.

Which means that RedirectToAction("Edit") is called, so that the original "Edit" controller action is called.

This means I wont see my validation messages and any data the user has added to the form will be reset to the original values!

How should I be approaching this?

I have included the "edit" action below:

[AcceptVerbs("GET")]
    public ActionResult Edit(Guid id)
    {
        Gig gig = GigManager.GetByID(id);

        SelectList days = CreateDays(1, 31, 1,  gig.StartDate.Day);
        ViewData["day"] = days;

        SelectList months = CreateMonths(1, 12, 1, gig.StartDate.Month);
        ViewData["month"] = months;

        SelectList years = CreateYears(DateTime.Now.Year, DateTime.Now.Year + 10, 1, gig.StartDate.Year);
        ViewData["year"] = years;

        string bandNames ="";
        string bandIds = "";
        foreach(Act act in  gig.Acts)
        {
            bandNames += act.Name.Trim() + ", ";
            if (act.Artist != null)
            {
                bandIds += act.Artist.ID + ";";
            }
        }

        ViewData["Bands"] = bandNames;
        ViewData["BandIds"] = bandIds;

        return View(gig);

    }

However, I dont get validation messages th

+1  A: 

Maybe this will help. I just committed a controller which does a listing/edit admin. It uses binding on a class which might be handy. Check out the very end of the file to see a possible way of handling the Get and Post Verbs. Note that UpdateModelStateWithViolations is just a helper for adding errors to the ModelState.

        Controller.ModelState.AddModelError(violation.PropertyName,
            violation.ErrorMessage);

which is Displayed with

<%= Html.ValidationSummary() %>

http://www.codeplex.com/unifico/SourceControl/changeset/view/1629#44699

and the View: http://www.codeplex.com/unifico/SourceControl/changeset/view/1629#54418

    [AcceptVerbs("GET")]
    [Authorize(Roles = "Admin")]
    public ActionResult EditRole(Guid? RoleID)
    {
        Role role = null;
        RoleForm form = new RoleForm { };
        if (RoleID.HasValue)
        {
            role = accountService.GetRole(RoleID.Value);
            if (role == null)
                return RedirectToAction("Roles");

            form = new RoleForm
            {
                RoleID = role.ID,
                RoleName = role.Name,
                Level = role.Level
            };
        }
        else
        {
            form = new RoleForm();
        }

        ViewData.Model = form;

        return this.PluginView();
    }


    [AcceptVerbs("POST")]
    [Authorize(Roles = "Admin")]
    public ActionResult EditRole(Guid? RoleID, [Bind(Include = "RoleID,RoleName,Level", Prefix = "")] RoleForm form)
    {
        Role role = null;
        if (RoleID.HasValue)
        {
            role = accountService.GetRole(RoleID.Value);
            if (role == null)
                return RedirectToAction("Roles");
        }

        ServiceResponse<Role> response = accountService.AttemptEdit(form);

        if (response.Successful)
        {
            TempData["Message"] = "Update Successfull";
        }
        else
        {
            this.UpdateModelStateWithViolations(response.RuleViolations);
        }

        //ViewData["AllRoles"] = accountService.GetRolePage(new PageRequest(0, 50, "Name", typeof(string), true)).Page.ToArray();


        ViewData.Model = form;

        return this.PluginView();
    }
ccook