如何从Controller向Service传递匿名类型?附代码示例
如何向Service传递匿名类型数组?
嘿,我来帮你搞定这个问题!你现在的场景是在Controller里调用Service的SendAsync方法,想要把匿名类型数组传过去对吧?其实有几个可行的方案,我给你拆解一下:
方案1:使用dynamic类型接收(快速但缺乏类型安全)
你可以直接修改Service里SendAsync方法的参数,把需要接收匿名数组的参数改成dynamic[]类型,这样Controller里的匿名数组就能直接传进去了。
比如修改Service的方法:
public Task SendAsync(string email, string subject, dynamic[] templateData) { // 在这里可以直接访问templateData里的属性,比如templateData[0].UrlText Execute(email, subject, templateData).Wait(); return Task.FromResult(0); }
然后在Controller里调用:
var englishArray = new[] { new { UrlText = callbackurl, HeaderText = "Header", WelcomeText = "Welcome" }, // 其他匿名对象... }; await _emailService.SendAsync(user.Email, "Confirm Email", englishArray);
⚠️ 注意:这个方案虽然实现快,但缺点是没有编译时类型检查——要是拼写错属性名(比如把UrlText写成UrlTexT),只有运行时才会报错,后期维护风险较高。
方案2:创建强类型DTO(推荐,类型安全易维护)
这是更规范的做法,专门定义一个对应模板数据的类(也就是DTO,数据传输对象),用这个类代替匿名类型,兼顾类型安全和可读性。
首先定义DTO类:
public class EmailTemplateItem { public string UrlText { get; set; } public string HeaderText { get; set; } public string WelcomeText { get; set; } // 加上你需要的其他属性 }
然后修改Service的方法参数:
public Task SendAsync(string email, string subject, EmailTemplateItem[] templateData) { // 这里可以安全地访问属性,编译时就能检查错误 Execute(email, subject, templateData).Wait(); return Task.FromResult(0); }
Controller里创建数组并调用:
var englishArray = new EmailTemplateItem[] { new EmailTemplateItem { UrlText = callbackurl, HeaderText = "Header", WelcomeText = "Welcome" }, // 其他实例... }; await _emailService.SendAsync(user.Email, "Confirm Email", englishArray);
这个方案的好处是类型安全,拼写错误或者属性不匹配在编译阶段就能发现,代码可读性和可维护性都更高,非常适合正式项目使用。
方案3:使用ExpandoObject(灵活性高但略繁琐)
如果不想定义DTO,又想比dynamic多一点可控性,可以用ExpandoObject。你可以在Controller里把匿名对象转换成ExpandoObject数组,然后Service里用ExpandoObject[]接收。
Controller里的代码:
var englishArray = new[] { new { UrlText = callbackurl, HeaderText = "Header", WelcomeText = "Welcome" } } .Select(anon => { var expando = new ExpandoObject() as IDictionary<string, object>; foreach (var prop in anon.GetType().GetProperties()) { expando.Add(prop.Name, prop.GetValue(anon)); } return expando as ExpandoObject; }) .ToArray(); await _emailService.SendAsync(user.Email, "Confirm Email", englishArray);
Service的方法:
public Task SendAsync(string email, string subject, ExpandoObject[] templateData) { // 访问属性需要转换成字典,比如var item = (IDictionary<string, object>)templateData[0]; // 然后通过item["UrlText"]获取值 Execute(email, subject, templateData).Wait(); return Task.FromResult(0); }
这个方案比dynamic多了一点类型可控性,但还是不如DTO直观,一般只在特殊灵活场景下使用。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

