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