简体   繁体   中英

Object as a parameter for an action controller?

Is it possible for an action controller to accept a literal object. For example, I have several views in which I would like to post various models from to a single controller that can then determine the incoming model object for further processing.

Model sample:

public class Model1
{
   // properties, etc.
}

public class Model2
{
   // properties, etc.
}

public class Model3
{
   // properties, etc.
}

controller sample:

[HttpPost]
public ActionResult ProcessModel(Object anyModel)
{
   // determine the model
   if((anyModel as Model1) != null)
   {
     var model1 = anyModel as Model1;
     // continue with code
   }
   else if((anyModel as Model2) != null)
   {
     var model2 = anyModel as Model2;
     // continue with code
   }
   // continue with model check, etc.       
}

I've tried, but my controller does not appear to be picking up the model as my object parameter remains empty. Is this possible?

Have a quick read about how model binding works ... The model binder (which takes whatever is posted to your Action and turns it into the anyModel parameter uses the type of the parameter to determine what to do.

Since the type is Object it can't do anything.

My guess (depending on what you're trying to achieve) is that you can have several Action overloads each with a different type of Model as the parameter which then call common code.

[HttpPost]
public ActionResult ProcessModel(Model1 anyModel){}

[HttpPost]
public ActionResult ProcessModel(Model2 anyModel){}

[HttpPost]
public ActionResult ProcessModel(Model3 anyModel){}

That said it's a bit odd to have one action which takes lots of different models. There's a good chance you're better off doing something else.

Your question might gather a better answer if you say what you're trying to achieve

The Default Asp.NET ModelBinder cannot bind generic Objects this way. You should take a look here to understand how the model will be build back in the server by the DefaultModelBinder: Understanding ASP.NET MVC Model Binding .

Given that your form has many Models, you should encapsulate them into a ViewModel to do this kind of operation.

The ViewModel should looks like this:

public class MyViewModel
{
  public Model1 Model1 {get; set;}
  public Model1 Model2 {get; set;}
  public Model1 Model3 {get; set;}
}

And the controller:

[HttpPost]
public ActionResult ProcessModel(MyViewModel myViewModel)
{
  // determine the model
  if(myViewModel.Model1 != null)
  {
    // continue with code
  }
  else if(myViewModel.Model2 != null)
  {
    // continue with code
  }
  // continue with model check, etc.       
}

Recently I faced the same issue and resolved it as below:

Step 1: From javascript pass 2 parameter :

First, pass model name as String for identification which model is coming

Second, Pass data from javascript using JSON.stringify(data) . where your data can be from Model1, Model2 , Model3 etc.

Step2: In your controller:

[HttpPost]
public ActionResult ProcessModel(string modelName, string anyModel)
{
   switch(modelName)  {
      case "Model1":
             var modelValue= JsonDeserialize<Model1>(anyModel);
              // do something 
           break;
     case "Model2": 
            var modelValue= JsonDeserialize<Model2>(anyModel); 
            // do something
           break;
    }
}

You Need One method like below:

public T JsonDeserialize<T>(string jsonModel){
return JsonConvert.DeserializeObject<T>(jsonModel, jsonSettings);
}

JsonConvert need namespace "Newtonsoft.Json".

You also need to declare jsonSettings as below

         JsonSerializerSettings jsonSettings= new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.All,
        DefaultValueHandling = DefaultValueHandling.Ignore
    };

This solution is kind of workaround. There is one more solution. you can check that also: How can I make a Controller Action take a dynamic parameter?

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM