Asp.net mvc 如何在ASP.NET MVC 4(预览)中实例化IController,以便IController.ValidateModel工作?
我需要手动实例化一些控制器,因此有以下代码:Asp.net mvc 如何在ASP.NET MVC 4(预览)中实例化IController,以便IController.ValidateModel工作?,asp.net-mvc,asp.net-mvc-4,Asp.net Mvc,Asp.net Mvc 4,我需要手动实例化一些控制器,因此有以下代码: var controller = Activator.CreateInstance(typeof(AccountController), repository) as AccountController; 在AccountController中,我有一个类似的方法: [AllowAnonymous] [HttpPost] public ApiJsonResult LogOn(LogOnAccountDto mod
var controller = Activator.CreateInstance(typeof(AccountController),
repository) as AccountController;
在AccountController中,我有一个类似的方法:
[AllowAnonymous]
[HttpPost]
public ApiJsonResult LogOn(LogOnAccountDto model)
{
ValidateModel(model);
if (ModelState.IsValid)
{
//...
}
}
我希望我的ModelState.IsValid能够工作,因此我调用ValidateModel并将其传递给模型
这失败了,显然是因为没有设置controlContext。
我得到这个错误:
值不能为null。参数名称:controllerContext说明:
在执行当前操作期间发生未处理的异常
网络请求。有关详细信息,请查看堆栈跟踪
错误及其在代码中的起源
异常详细信息:System.ArgumentNullException:值不能为null。
参数名称:controllerContext
那么,如何在代码中手动实例化IController,以便“一切”都能正常工作
提前谢谢
那么,我为什么需要这个呢?
我正在为一个“在线战略游戏”玩弄一些架构和游戏逻辑的想法
我有一个ASP.NETMVC4(预览)应用程序,这是我的网络版游戏。其想法是,该游戏也应该通过本机应用程序在Windows Phone、iPhone等设备上玩。
因此,我需要一些用于我的游戏的API(某种通过http/json进行通信的REST服务)。
由于此API将是游戏的公共接口,所有游戏逻辑当然都将位于此API中
因此,我想从游戏的“网络版”和“手机版”使用这个API。
我在ASP.NETMVC4(预览版)中实现了这个API。我的第一个想法是从我的“web版本”到API实际执行httpwebrequest,因此我使用的API与“移动版本”完全相同。
但后来我想,实际上最好只是手动实例化控制器,以避免通过“正确的方式”调用API而产生的所有json/web调用开销
这就是为什么我现在在这里,我想在代码中手动实例化我的控制器,因为我想在它们中使用精确的逻辑
有道理吗?
如果你有更好的想法,请告诉我-我这样做是为了学习it,而不是生产真正的产品-至少这不是现在的目标-现在我只是想学习一些新东西:)你不需要直接调用
ValidateModel
至少在我的任何代码中我都不需要直接调用它,而且我也没有看到任何可以调用它的示例
您可以使用System.ComponentModel.DataAnnotations中的属性来控制模型的验证方式
让我给你一个例子,复制粘贴一些工作代码
模型类:(基本上只是一个DTO,没什么特别的。)
公共类文章模型
{
公共物品模型()
{
CategoryIds=新列表();
}
公共int Id{get;set;}
[必需(ErrorMessage=“字段必填!”)]
公共字符串标题{get;set;}
[必需(ErrorMessage=“字段必填!”)]
公共字符串文本{get;set;}
公共字符串摘要{get;set;}
公共bool刷新日期{get;set;}
公共列表类别ID{get;set;}
}
控制器操作:(实例化ORM的对象并将其保存到数据库。)
[HttpPost]
[验证输入(错误)]
[SiteAuthorization(SiteAuthorization.SiteOwner)]
公共行动结果编辑文章(ArticleModel模型)
{
var article=Repository.Retrieve().SingleOrDefault(x=>x.Id==model.Id&&x.Site==ColorfulUtility.CurrentSite);
if(article==null)
返回重定向到操作(“文章列表”);
if(ModelState.IsValid)
{
if(型号刷新日期)
article.Date=DateTime.Now;
article.Title=model.Title.SimpleTextToSafeHtml();
article.Text=model.Text.RichTextToSafeHtml();
article.Summary=model.Summary.RichTextToSafeHtml();
foreach(ColorfulUtility.CurrentSite.ArticleCategories中的var类别)
{
if(!article.Categories.Contains(category)和&model.categoryId.Contains(category.Id))
{
第条.类别.添加(类别);
}
else if(article.Categories.Contains(category)和&!model.categoryId.Contains(category.Id))
{
第条.类别.删除(类别);
}
}
Repository.Flush();
返回重定向到操作(“文章列表”);
}
返回视图(“CreateArticle”,模型);
}
如果您需要手动实例化控制器,那么您的设计就应该出现严重错误。我重复一遍:非常错误。好的,我会更新问题并解释为什么我需要这个。请稍等。你所说的游戏的网络版是什么意思?这不是ASP.NETMVC应用程序本身吗?是的,“web版本”是ASP.NETMVC4应用程序本身。我希望将API作为实际MVC应用程序的一部分的原因之一是,我需要能够同时运行此游戏的多个独立版本。例如:s1.mygame.com-为此,API将位于s1.mygame.com/API感谢您的输入,但我实际上知道数据注释,通常这些都已经在我的模型上设置好了。ValidateModel正在根据这些DataAnnotation进行验证。但我越想它,就越想在这里更改我的设计,只需在它自己的项目中取出API,然后像所有其他客户端一样针对它执行webrequests。我只是想在这里走一条捷径,让它变得不那么复杂,但似乎情况正好相反,因为要自己实例化IController并不容易:)
public class ArticleModel
{
public ArticleModel()
{
CategoryIds = new List<int>();
}
public int Id { get; set; }
[Required(ErrorMessage = "Field mandatory!")]
public string Title { get; set; }
[Required(ErrorMessage = "Field mandatory!")]
public string Text { get; set; }
public string Summary { get; set; }
public bool RefreshDate { get; set; }
public List<int> CategoryIds { get; set; }
}
[HttpPost]
[ValidateInput(false)]
[SiteAuthorize(SiteAuthorization.SiteOwner)]
public ActionResult EditArticle(ArticleModel model)
{
var article = Repository.Retrieve<Article>().SingleOrDefault(x => x.Id == model.Id && x.Site == ColorfulUtility.CurrentSite);
if (article == null)
return RedirectToAction("ArticleList");
if (ModelState.IsValid)
{
if (model.RefreshDate)
article.Date = DateTime.Now;
article.Title = model.Title.SimpleTextToSafeHtml();
article.Text = model.Text.RichTextToSafeHtml();
article.Summary = model.Summary.RichTextToSafeHtml();
foreach (var category in ColorfulUtility.CurrentSite.ArticleCategories)
{
if (!article.Categories.Contains(category) && model.CategoryIds.Contains(category.Id))
{
article.Categories.Add(category);
}
else if (article.Categories.Contains(category) && !model.CategoryIds.Contains(category.Id))
{
article.Categories.Remove(category);
}
}
Repository.Flush();
return RedirectToAction("ArticleList");
}
return View("CreateArticle", model);
}