Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to convert formcollection to model in mvc

Is it possible to convert formcollection to a 'model' known?

[HttpPost]
    public ActionResult Settings(FormCollection fc)
    {
    var model=(Student)fc; // Error: Can't convert type 'FormCollection' to 'Student'
    }

NOTE : for some reasons i can't use ViewModel instead.

Here is my code VIEW: Settings.cshtml

@model MediaLibrarySetting
@{
ViewBag.Title = "Library Settings";
var extensions = (IQueryable<MediaLibrarySetting>)(ViewBag.Data);    
}
@helper EntriForm(MediaLibrarySetting cmodel)
{   

<form action='@Url.Action("Settings", "MediaLibrary")' id='[email protected]' method='post' style='min-width:170px' class="smart-form">
    @Html.HiddenFor(model => cmodel.MediaLibrarySettingID)
    <div class='input'>
        <label>
       New File Extension:@Html.TextBoxFor(model => cmodel.Extention, new { @class = "form-control style-0" })
        </label>
        <small>@Html.ValidationMessageFor(model => cmodel.Extention)</small>
    </div>
    <div>
        <label class='checkbox'>
            @Html.CheckBoxFor(model => cmodel.AllowUpload, new { @class = "style-0" })<i></i>&nbsp;
            <span>Allow Upload.</span></label>
    </div>
    <div class='form-actions'>
        <div class='row'>
            <div class='col col-md-12'>
                <button class='btn btn-primary btn-sm' type='submit'>SUBMIT</button>
            </div>
        </div>
    </div>
</form>
}
<tbody>
@foreach (var item in extensions)
 {
  if (item != null)
   {                                    
    <tr>
     <td>
      <label class="checkbox">
       <input type="checkbox"  value="@item.MediaLibrarySettingID"/><i></i>
        </label>
          </td>
           <td>
             <a href="javascript:void(0);" rel="popover" class="editable-click"
            data-placement="right"
            data-original-title="<i class='fa fa-fw fa-pencil'></i> File Extension"
            data-content="@EntriForm(item).ToString().Replace("\"", "'")" 
            data-html="true">@item.Extention</a></td>
                    </tr>
                    }
                }
                </tbody>

CONTROLLER:

[HttpPost]
public ActionResult Settings(FormCollection fc)//MediaLibrarySetting cmodel - Works fine for cmodel
{
        var model =(MediaLibrarySetting)(fc);// Error: Can't convert type 'FormCollection' to 'MediaLibrarySetting'
}

data-content and data- attributes are bootstrap popover.

like image 217
sridharnetha Avatar asked Dec 04 '22 23:12

sridharnetha


2 Answers

Another approach in MVC is to use TryUpdateModel.

Example: TryUpdateModel or UpdateModel will read from the posted form collection and attempt to map it to your type. I find this more elegant than manually mapping the fields by hand.

[HttpPost]
public ActionResult Settings()
{
    var model = new Student();

    UpdateModel<Student>(model);

    return View(model);
}
like image 175
Marty A Avatar answered Dec 28 '22 06:12

Marty A


Nice question! Had same in the quest of making a universal base controller, model independent. Thanks to many people, the last one was @GANI, it's done.

Type ViewModelType is set in subclassed controller to anything you want.

public ActionResult EatEverything(FormCollection form)
        {    
            var model = Activator.CreateInstance(ViewModelType);
            Type modelType = model.GetType();

        foreach (PropertyInfo propertyInfo in modelType.GetProperties())
        {
            var mykey = propertyInfo.Name;
            if (propertyInfo.CanRead && form.AllKeys.Contains(mykey))
            {
                try
                {
                    var value = form[mykey];
                    propertyInfo.SetValue(model, value);
                }
                catch 
                {
                    continue;
                }
            }
        }

now that everything you received from an unknown form is in your real model you can proceed to validation from this post https://stackoverflow.com/a/22051586/7149454

like image 36
Nick Kovalsky Avatar answered Dec 28 '22 07:12

Nick Kovalsky