Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Posting data when my view model has a constructor does not work

I have the following code:

[HttpGet]
public ActionResult Edit(int req)
{
    var viewModel = new  EditViewModel();
    viewModel.RequestId = int;
    return View(viewModel);
}

[HttpPost]
Public ActionResult Edit(EditViewModel viewModel)
{
// some code here...
}

It works fine: when the edit form is posted, I have the action controller who is called.

Now I modify some little bit my code like this:

[HttpGet]
public ActionResult Edit(int req)
{
    var viewModel = new  EditViewModel(req);
    return View(viewModel);
}

[HttpPost]
Public ActionResult Edit(EditViewModel viewModel)
{
// some code here...
}

public class EditViewModel()
{
    public EditViewModel(int req)
    {
        requestId = req; 
    }
    ...
}

In this new version, I have a view model with a contructor.

This time, when my form is posted back, the action controller is never triggered.

Any idea?

Thanks.

like image 568
Bronzato Avatar asked Feb 23 '12 12:02

Bronzato


1 Answers

Asp.Net Core version

public class EditViewModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException(nameof(bindingContext));
        }

        var req = bindingContext.ValueProvider.GetValue("req");
        if (req == ValueProviderResult.None || string.IsNullOrEmpty(req.FirstValue))
        {
            bindingContext.ModelState.TryAddModelError("req", "Missing req parameter");
        }

        int reqValue;
        if (!int.TryParse(req.AttemptedValue, out reqValue))
        {
            bindingContext.ModelState.TryAddModelError($"The req parameter contains an invalid value: {req.AttemptedValue}");
        }

        var model = new EditViewModel(req.FirstValue);

        bindingContext.Result = ModelBindingResult.Success(model);
        return Task.CompletedTask;
    }
}

You don't need to register anything with startup.cs anymore. Just assign the binder to your ViewModel and you're away.

[ModelBinder(BinderType = typeof(EditViewModelBinder))]
public class EditViewModel
like image 133
Red Avatar answered Oct 26 '22 12:10

Red