【问题标题】:Object as a parameter for an action controller?对象作为动作控制器的参数?
【发布时间】:2015-07-29 12:40:36
【问题描述】:

动作控制器是否可以接受文字对象。例如,我有几个视图,我想在其中发布各种模型到单个控制器,然后可以确定传入模型对象以进行进一步处理。

模型样本:

public class Model1
{
   // properties, etc.
}

public class Model2
{
   // properties, etc.
}

public class Model3
{
   // properties, etc.
}

控制器样本:

[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.       
}

我已经尝试过了,但我的控制器似乎没有拾取模型,因为我的对象参数仍然为空。这可能吗?

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    有一个quick read about how model binding works... 模型绑定器(它获取发布到您的 Action 的任何内容并将其转换为 anyModel 参数,使用参数的类型来确定要执行的操作。

    由于类型是Object,它不能做任何事情。

    我的猜测(取决于您要实现的目标)是您可以有多个动作重载,每个重载都使用不同类型的模型作为参数,然后调用公共代码。

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

    也就是说,一个动作需要许多不同的模型有点奇怪。很有可能你最好做点别的事情。

    如果你说出你想要达到的目标,你的问题可能会得到更好的答案

    【讨论】:

    • 我不认为你可以有多个同名的动作(不管参数)。
    • 参数必须是不同的类型。 csharpindepth.com/Articles/General/Overloading.aspx
    • 虽然刚刚重新阅读了您的评论(可能是我睡觉的时间)@zimdanen - 是的......虽然您绝对可以以这种方式重载方法并且操作应该只是我从未真正做过的方法,所以不知道 MVC 或模型绑定是否会出错
    • 你去... stackoverflow.com/a/436935/222163 MVC 确实会出错,但您可以为每个动作添加一个属性来区分它们。也就是说,我确实认为做其他事情会更好:)
    【解决方案2】:

    默认的 Asp.NET ModelBinder 不能以这种方式绑定泛型对象。您应该查看这里以了解 DefaultModelBinder 将如何在服务器中重新构建模型:Understanding ASP.NET MVC Model Binding。

    鉴于您的表单有很多模型,您应该将它们封装到 ViewModel 中来执行此类操作。

    ViewModel 应该如下所示:

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

    还有控制器:

    [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.       
    }
    

    【讨论】:

      【解决方案3】:

      最近我遇到了同样的问题并解决如下:

      第 1 步: 从 javascript 传递 2 参数:

      首先,将模型名称作为字符串传递,以识别即将到来的模型

      其次,使用 JSON.stringify(data) 从 javascript 传递数据。您的数据可能来自Model1, Model2 , Model3 等。

      第 2 步:在您的控制器中:

      [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;
          }
      }
      

      您需要一种方法,如下所示:

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

      JsonConvert 需要命名空间“Newtonsoft.Json”。

      您还需要如下声明 jsonSettings

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

      此解决方案是一种解决方法。还有一种解决方案。您还可以检查: How can I make a Controller Action take a dynamic parameter?

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-28
        • 1970-01-01
        • 2011-08-05
        • 1970-01-01
        • 2019-06-12
        • 2013-07-24
        • 1970-01-01
        相关资源
        最近更新 更多