ElHaix
ElHaix

Reputation: 13006

Appropriate pattern for setting request object properties from POST request with MVC3?

With incoming POST requests to my MVC3 application, I want to validate the incoming request parameters. If an invalid parameter exists, an exception is thrown.

Given the following object:

public class ActionRequest
{
    public string ActionRequestPassword { get; set; }
    public bool EnableNewsfeedAppPool { get; set; }
}

With incoming post requests, I want to initialize the object with the appropriate properties via:

public class NewsfeedAppPoolController : Controller
{
    [ActionName("EnableAppPool"), AcceptVerbs(HttpVerbs.Post)]
    [ValidateInput(false)]
    [NoCache]
    public ActionResult EnableAppPool(FormCollection formCollection)
    {
        Models.ActionRequest actionRequest = ValidatePOSTRequest(formCollection);

        // do things with actionRequest

        return null;
    }

    private Models.ActionRequest ValidatePOSTRequest(FormCollection formCollection)
    {
        try
        {
            Type actionRequestType = typeof(Models.ActionRequest);
            System.Reflection.PropertyInfo propertyInfo = null;
            object systemActivatorObject = Activator.CreateInstance(actionRequestType);

            foreach (var key in formCollection.AllKeys)
            {

                propertyInfo = typeof(Models.ActionRequest).GetProperty(key);
                Type t = propertyInfo.PropertyType; // t will be System.String


                if (t.Name == "Int32")
                {
                    actionRequestType.GetProperty(key).SetValue(systemActivatorObject, Convert.ToInt32(formCollection[key]), null);
                }
                else
                {
                    actionRequestType.GetProperty(key).SetValue(systemActivatorObject, formCollection[key], null);
                }
            }

            return (Models.ActionRequest)systemActivatorObject;
        }
        catch (Exception ex)
        {
            throw ex;
        } 
    }
}

I would like to know if there can be any improvements made to this, or recommendations of how else to accomplish this in an efficient manner.

Thanks.

Upvotes: 0

Views: 180

Answers (3)

VJAI
VJAI

Reputation: 32768

The appropriate pattern is,

[HttpPost]
public ActionResult Save(Employee employee)
{
  if(ModelState.IsValid)
  {
     db.Save(employee);
     RedirectToAction("Index");
  }

  return View();
}

Notes:

The employee instance is automatically created and populated by the default model binder from the values available in the request(form, querystrings, routedata and more)

When the default model binder binds the values to the model it also does the validation and store all the errors in the ModelState dictionary, so by checking the ModelState.IsValid you can know that whether the validation is succeeded or not.

To know more about model binding refer this. To know more about model validation refer this.

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1039298

Simply use the default model binder which will take care of instantiating and binding the ActionRequest from the request parameters:

public class NewsfeedAppPoolController : Controller
{
    [ActionName("EnableAppPool"), AcceptVerbs(HttpVerbs.Post)]
    [ValidateInput(false)]
    [NoCache]
    public ActionResult EnableAppPool(ActionRequest actionRequest)
    {
        // do things with actionRequest

        return null;
    }
}

Upvotes: 1

SLaks
SLaks

Reputation: 887867

ASP.Net MVC already does all of this for you.
Just add a Models.ActionRequest actionRequest parameter to your action.

If you want to add additional validation logic, use System.ComponentModel.DataAnnotations.

Upvotes: 1

Related Questions