我正在尝试将javascript对象列表传递给具有对象类型参数的类,如下所示:
[HttpPost, Route("Save")]
public async Task<JsonResult> Save (int id, List<BaseDynamicSaveModel> models)
{
var widgets = await DataContext.Widgets
.AsNoTracking()
.Where(e => e.IsActive)
.ToListAsync();
var Messages = new List<object>();
if (models != null)
{
foreach (var model in models)
{
if (model.Model != null)
{
var widget = widgets.FirstOrDefault(e => e.Name.Equals(model.WidgetName, StringComparison.InvariantCultureIgnoreCase));
var dynamicViewModel = (IDynamicViewModel)Activator.CreateInstance(Type.GetType("Registration.Models.Dynamic." + model.WidgetName + "ViewModel"));
dynamicViewModel.ListOrder = widget.ListOrder.HasValue ? widget.ListOrder.Value : 0;
dynamicViewModel.ViewName = widget.Name;
dynamicViewModel.Title = widget.Title;
await dynamicViewModel.Save(API, model);
Messages.Add(new { Message = dynamicViewModel.Message, Success = dynamicViewModel.Success });
}
}
}
return Json(Messages);
}
BaseDynamicSaveModel如下所示:
public class BaseDynamicSaveModel : IDynamicSaveModel
{
public string WidgetName { get; set; }
public IEnumerable<DynamicModelProperty> Model { get; set; }
}
DynamicModelProperty看起来像这样:
public class DynamicModelProperty
{
public string Key { get; set; }
public object Value { get; set; }
}
问题是,在我调试时,Value在传递非原始类型时始终显示为{object},而我似乎无法访问任何数据。
我确实在这里尝试使用词典,但它必须是Dictionary&lt; string,object&gt;和object总是为null所以我只是为键/值对创建了自己的类。
每个模块都有一个ViewModel,它继承自BaseViewModel类,如下所示:
public class BaseDynamicViewModel : IDynamicViewModel
{
public string ViewName { get; set; }
public string Message { get; set; }
public bool Success { get; set; }
public string Title { get; set; }
public int ListOrder { get; set; }
public string ViewIcon { get; set; }
public virtual Task Load(API.APIProvider API, int id)
{
throw new NotImplementedException();
}
public virtual Task Save(API.APIProvider API, BaseDynamicSaveModel model)
{
throw new NotImplementedException();
}
protected object CopyProperties(object destination, BaseDynamicSaveModel source)
{
var destinationModel = destination;
var destinationProperties = destinationModel.GetType();
foreach (var destinationProperty in destinationProperties.GetProperties())
{
if (destinationProperty.CanRead)
{
var value = source.Model.Where(e => e.Key.ToLower() == destinationProperty.Name.ToLower()).Select(e => e.Value).FirstOrDefault();
if (value != null)
{
//Need to check if property is nullable and get underlying type
var targetType = destinationProperty.PropertyType.IsNullable() ? Nullable.GetUnderlyingType(destinationProperty.PropertyType) : destinationProperty.PropertyType;
var convertedValue = Convert.ChangeType(value, targetType);
destinationProperty.SetValue(destinationModel, convertedValue, null);
}
}
}
return destinationModel;
}
}
特别是有问题的模块的保存方法(这个方法中的其余代码并不重要,我真的不能很好地表现出来):
public override async Task Save(API.APIProvider API, BaseDynamicSaveModel model)
{
//The module is not really named Module3, it has been renamed for obvious reasons
var saveModel = new Module3SaveModel();
saveModel = (Module3SaveModel)CopyProperties(saveModel, model);
}
在控制器中,如果您注意到 await dynamicViewModel.Save(API,model); 是我调用每个模块的保存方法的地方,以便澄清。< / p>
我有2个模块可以保存得很好,因为我只传递一个具有基本类型且没有嵌套对象的模型。对于第3个模块,我传递了一个对象列表,这就是它失败的地方。当对象不是原始类型时,调试器中只显示{object}而没有数据,我无法使用CopyProperties方法设置SaveModel,因为它似乎没有任何数据。
问题:如何从AJAX调用到泛型类获取对象列表,以便稍后使用反射进行解包或至少我尝试这样做?
我不知所措。我非常希望将List作为控制器中的参数,但它需要是通用的,因为其他模块将使用它。这似乎是一个简单的问题,但谷歌没有太多帮助(或者我的谷歌技能可能缺乏)。
感谢您的帮助:)
答案 0 :(得分:0)
对于我为解决问题所做的事情感兴趣的任何人,我只是创建了一个单独的控制器:
[HttpPost, Route("Save")]
public async Task<JsonResult> Save(int id, List<List<DynamicModelProperty>> models, string name)
{
}
其中列出了作为数组的模块。在javascript中,我只确定传递给save的模型是否是一个数组并将其传递给该控制器。