Reusing model data in post action

In my view model, I have a list of items that I retrieve from the database and then send them to the view. I would like to know whether it is possible to avoid the need to replenish the options property whenever I click the "Post" action and should return a model (for validation errors and what not)?

In web forms, this is not required.

Change . I was not clear. My problem is with the SelectList options that I use for my DropDownLists. Everything is published, but if I need to return to viewing (the model is not valid), I have to reload the parameters from the database! I want to know if this can be avoided.

My view model:

public class TestModel
{
    public TestModel()
    {
        Departments = new List<SelectListItem>();
    }

    public string Name { get; set; }
    public int Department { get; set; }
    public IEnumerable<SelectListItem> Departments { get; set; }
}

My opinion:

@model MvcApplication1.Models.TestModel    
@using (Html.BeginForm())
{
    @Html.TextBoxFor(m => m.Name)

    @Html.DropDownListFor(m => m.Department, Model.Departments)

    <input type=submit value=Submit />
}

( HttpPost):

public ActionResult Index()
{
    TestModel model = new TestModel
    {
        Name = "Rafael",
        Department = 1,
        Departments = new List<SelectListItem>
        {
            new SelectListItem { Text = "Sales", Value = "1" },
            new SelectListItem { Text = "Marketing", Value = "2", Selected = true },
            new SelectListItem { Text = "Development", Value = "3" }
        }
    };

    // Departments gets filled from a database.

    return View(model);
}

[HttpPost]
public ActionResult Index(TestModel model)
{
if (!ModelState.IsValid)
{
    //Do I have to fill model.Departments again!?!?!?

    return View(model); 
}
else { ...  }
}

.

: FYI, Session.

+5
3

, .

,

@model MyNamesspace.Models.MyModel
...
@using (Html.BeginForm())
{
    ....
}

, .

[HttpPost]
public ActionResult MyAction(MyModel model)
{
    ...
}

EDIT: , , . Razor BTW.

+1

Order MVC (, , AJAX). , , MergeChanges , :

public Order MergeChanges(Order newOrder)
{
    var sessionHistory = (List<string>)Session["sessionHistory"];

    if (sessionHistory == null || sessionHistory.Count == 0)
    return MergeChanges(newOrder, -1);

    return MergeChanges(newOrder, MasterViewController.GetStepNumberByName(sessionHistory.Last()));
}

public Order MergeChanges(Order newOrder, int step)
{
    PreMerge(newOrder);

    Order result = null;
    try
    {
        ApplyLookups(ref newOrder);
        Order oldOrder = (Order)Session["order"];

        if (oldOrder == null)
        {
             Session["order"] = newOrder;
             result = newOrder;
        }
        else
        {
            List<TypeHelper.DecoratedProperty<ModelPageAttribute>> props = null;
            newOrder.GetType().GetDecoratedProperty<ModelPageAttribute>(ref props);
            props = props.Where(p => (p.Attributes.Count() > 0 && p.Attributes.First().PageNumber.Contains(step))).ToList();
            foreach (var propPair in props)
            {
                object oldObj = oldOrder;
                object newObj = newOrder;
                if (!string.IsNullOrEmpty(propPair.PropertyPath))
                {
                    bool badProp = false;
                    foreach (string propStr in propPair.PropertyPath.Split('\\'))
                    {
                        var prop = oldObj.GetType().GetProperty(propStr);
                        if (prop == null)
                        {
                            badProp = true;
                            break;
                        }

                        oldObj = prop.GetValue(oldObj, BindingFlags.GetProperty, null, null, null);
                        newObj = prop.GetValue(newObj, BindingFlags.GetProperty, null, null, null);
                     }
                     if (badProp)
                          continue;
                 }

                 if (newObj == null)
                     continue;

                 var srcVal = propPair.Property.GetValue(newObj, BindingFlags.GetProperty, null, null, null);
                 var dstVal = propPair.Property.GetValue(oldObj, BindingFlags.GetProperty, null, null, null);

                  var mergeHelperAttr = propPair.Property.GetAttribute<MergeHelperAttribute>();
                   if (mergeHelperAttr == null)
                   {
                        if (newObj != null)
                            propPair.Property.SetValue(oldObj, srcVal, BindingFlags.SetProperty, null, null, null);
                   }
                   else
                   {
                       var mergeHelper = (IMergeHelper)Activator.CreateInstance(mergeHelperAttr.HelperType);
                       if (mergeHelper == null)
                           continue;

                       mergeHelper.Merge(context, HttpContext.Request, newObj, propPair.Property, srcVal, oldObj, propPair.Property, dstVal);
                    }
               }
               result = oldOrder;
          }
    }
    finally
    {
    PostMerge(result);
    }
    return result;
}

, , , , , ( , ) ViewController . , , . , , PITA.

0

, , , (IMHO) ​​ : POST Ajax. ,

  • , , . (). , ( -).
  • No coercion to check on the client side. Validation can be 100% server-side (where it should be anyway), and the user interface is almost the same.

Of course, there is some initial work you need to do to create a framework for this, for example, I have a set of types AjaxUpdate, AjaxNothing, AjaxRedirect, AjaxErrors ... ActionResult that handle Json, which is handled by some custom Javascript. But once you get it in place, it will be smooth.

0
source

All Articles