我在ASP.NET MVC中有一个处理上传文件的控制器操作。但是,在使用MvcContrib的 TestControllerBuilder 时,似乎无法调用 Request.Files.Count

我知道我可以通过抽象 Request.Files 来解决这个问题。我的问题是:

  1. 在使用 TestControllerBuilder 时,是否确实没有直接的方法来调用 Request.Files.Count ?或者我做错了什么?
  2. 使用 TestControllerBuilder 使用Rhino Mocks时,有没有办法将对 Request.Files.Count 的调用存根?
  3. 您认为我应该向MvcContrib提交处理 Request.Files.Count 的请求或补丁吗?
  4. 示例代码:

    我想确保 Request.Files 集合中至少有一个文件,所以我的操作中有以下条件:

    public class MyController : Controller {
        public ActionResult Upload() {
            if (Request.Files == null || Request.Files.Count == 0)
                ViewData.ModelState.AddModelError("File", "Please upload a file");
            // do stuff
            return View();
        }
    }
    

    我正在使用MvcContrib的 TestControllerBuilder 为我的控制器测试创建测试双。但是,对 Request.Files.Count 的调用似乎总是抛出异常。例如,在调用 Request.Files.Count 时,在调用 controller.Upload()期间运行以下NUnit测试会抛出 NotImplementedException

    [Test]
    public void Upload_should_return_default_view_given_one_file() {
        MyController controller = new MyController();
        TestControllerBuilder controllerBuilder = new TestControllerBuilder();
        controllerBuilder.InitializeController(controller);
        controllerBuilder.Files["file"] = 
            MockRepository.GenerateStub<HttpPostedFileBase>();
    
        var result = controller.Upload() as ViewResult;
    
        Assert.That(result.ViewData.ModelState.IsValid, Is.True);
        result.AssertViewRendered().ForView(string.Empty);
    }
    

    我还尝试将对 Request.Files.Count 的调用存根无效(我正在使用Rhino Mocks)。以下都不起作用(即使我将 controller 和/或 controllerBuilder 更改为存根):

    controllerBuilder.Stub(cb => cb.HttpContext.Request.Files.Count).Return(1);
    controller.Stub(c => c.Request.Files.Count).Return(1);
    

    由于

有帮助吗?

解决方案

我在Github上向MvcContrib mantainers 提交了补丁,但变化非常大简单来说,问题是HttpFileCollectionBase没有实现Count()和this [int index]方法,所以它们必须被MvcContrib中的WriteableHttpFileCollection覆盖。

我在这里粘贴代码是为了完整性,必须添加到WriteableHttpFileCollection类:

public override HttpPostedFileBase this[int index]
{
    get { return files[AllKeys[index]]; }
}

public override int Count
{
    get { return files.Count; }
}

其他提示

我已经用这种方法来解决问题。

设置测试:             string fileName =&quot; Test 1.pdf&quot ;;             FileStream stream = File.OpenRead(&quot; log4net.config&quot;);             MockRepository mock = new MockRepository();

        builder.Files[fileName] = mock.CreateMock<HttpPostedFileBase>();
        using (mock.Record())
        {
            Expect.Call(builder.Files[fileName].FileName)
                  .Return(fileName);
            Expect.Call(builder.Files[fileName].ContentType)
                  .Return(contentType);
            Expect.Call(builder.Files[fileName].ContentLength)
                  .Return(Convert.ToInt32(stream.Length.ToString()));
            Expect.Call(builder.Files[fileName].InputStream)
                  .Return(stream);
        }

使用模拟:

        foreach(string key in Request.Files.AllKeys)
        {
            int lenght = Request.Files[key].ContentLength;
            if (lenght > 0)
            {
                Document document = new Document();
                string fileName = Request.Files[key].FileName;
                byte[] content= new byte[Convert.ToInt32(lenght)];
                Request.Files[key].InputStream.Read(content, 0, content.Length);
                document.SetContent(content);
                document.MimeType = Request.Files[key].ContentType;
                // do whatever you want...
            }
        }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top