c# - 逐步更新 ASP.NET MVC 中的模型

标签 c# asp.net-mvc

我有一个很长的数据库网络调用,我想分块填充我的模型。我们正在谈论 asp.net MVC。 我有一个模糊的想法,每次有新的 block 可用时,我应该触发 model.Bind() 但我不知道如何在之间进行管道

a)以 block 的形式提供数据的服务 - 它是使用事件模式实现的 - 每次有新 block 可用时都会触发一个事件,但是哪个事件?它应该包含对模型的引用?

b)将绑定(bind)到模型的数据(我想它不应该是一个bind(),而是对某个集合的添加)

c) 如果步骤 a 和 b 中一切正常,那么更改将传播到 View ,而无需进一步执行操作?

最佳答案

您可以使用long polling使用隐藏的 iframe 和来自服务器的分块传输编码,它将吐出 <script>当数据可用时进行标记。在此脚本标记中,您可以调用自定义回调 JavaScript 函数,该函数将负责格式化结果。


更新:

根据评论部分的要求,这里是使用隐藏 iframe 的长轮询技术的示例实现。

假设您有一些模型:

public class MyViewModel
{
    public string Foo { get; set; }
}

并且您有一个服务以 block 的形式返回此模型,并使用事件通知调用者 block 可用:

public class MyService
{
    public void GetModels(Action<MyViewModel, object> onModelAvailable, object state, Action onComplete)
    {
        Task.Factory.StartNew(x =>
        {
            try
            {
                for (int i = 0; i < 10; i++)
                {
                    onModelAvailable(new MyViewModel
                    {
                        Foo = "foo " + i
                    }, x);
                    Thread.Sleep(1000);
                }
            }
            finally
            {
                onComplete();
            }
        }, state);
    }
}

现在,我们可以拥有以下 Controller :

public class HomeController : AsyncController
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult LongPoll()
    {
        var service = new MyService();
        return new MyActionResult(service);
    }
}

以及以下 View :

<script type="text/javascript">
    // we define a callback function which will be invoked
    // when a chunk is available from the server
    var callback = function (model) {
        // the model variable passed here will represent the chunk
        $($('<div/>', {
            html: model.Foo
        })).appendTo('#result');
    };
</script>

<iframe style="display:none;" src="@Url.Action("longpoll")"></iframe>
<div id="result"></div>

现在当然的最后一部分是自定义操作结果的实现,它将执行分块传输:

public class MyActionResult : ActionResult
{
    private readonly MyService _service;
    public MyActionResult(MyService service)
    {
        _service = service;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;
        response.BufferOutput = true;
        response.ContentType = "text/html";
        var wait = new ManualResetEvent(false);
        _service.GetModels((model, state) =>
        {
            var httpResponse = (HttpResponseBase)state;
            httpResponse.BufferOutput = true;
            httpResponse.ContentType = "text/html";
            var serializer = new JavaScriptSerializer();
            var script = string.Format(
                "<script type=\"text/javascript\">window.parent.callback({0});</script>",
                serializer.Serialize(model)
            );
            httpResponse.Write(script);
            httpResponse.Flush();
        },
        response,
        () =>
        {
            wait.Set();
        });
        wait.WaitOne();
    }
}

关于c# - 逐步更新 ASP.NET MVC 中的模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8896817/

相关文章:

c# - 如何使用抽象基类继承内部类?

asp.net-mvc - 我应该使用自定义模型绑定(bind)器将 View 模型绑定(bind)到实体吗?

.net - 使用自定义 VirtualPathProvider 加载继承自定义 WebViewPage 的嵌入式 View

c# - DataContractSerializer 是否仅适用于 http ://schemas. datacontract.org/2004/07/

c# - 如何指定打开excel文件的字符串路径?

c# - Microsoft Bot Framework - Facebook 集成 - Net Framework

javascript - @grid MVC 将日期转换为本地时区

ASP.Net MVC与ASP.Net表单

asp.net-mvc - 如何在 mvc4 的 cshtml View 页面中的 html.textboxfor 中设置数字范围验证?

c# - 如何使用 OpenSSL.net 创建证书