ASP.net MVC Controller不会返回视图

时间:2022-11-24 11:22:23

Still kinda new to ASP.net and I have this strange problem. Its a very basic scenario but something is up and I can't figure it out. Deploy should return a view named Deploy that is typed to the model CompiledAppModel. However, when you click install in the view it never leaves the page despite calling the return View() method. Any ideas?

对ASP.net来说还是个新手,我有这个奇怪的问题。这是一个非常基本的场景,但有些东西已经出现,我无法弄明白。部署应返回名为Deploy的视图,该视图将键入到模型CompiledAppModel中。但是,当您在视图中单击“安装”时,尽管调用了返回的View()方法,它仍然不会离开页面。有任何想法吗?

Here is my controller:

这是我的控制器:

[HttpPost]
public ActionResult Deploy(string key_name, string custom_folder = "")
{
    string userId = Membership.GetUser().ProviderUserKey.ToString();
    UserDataModel user_info = _user_data_service.getUserDataByPrimaryIDNoDB(userId, HttpContext.Cache);
    log.Trace("Deploy was called. key_name:" + key_name + " UID: " + user_info.UID);

    // first we'll call the info to install remote application
    bool serviceInstall = _fms_app_service.DeployFmsApp(user_info, key_name, custom_folder);

    // then we'll call to generate client side info
    bool clientInstall = _fms_app_service.CompileClientApp(user_info, key_name);

    var model = _fms_app_service.getInstalledAppInfo(user_info, key_name);
    if (serviceInstall && clientInstall)
    {
        return RedirectToAction("Deploy", model);
    }

    return View("Error");
}

and my view:

和我的观点:

@model IEnumerable<Models.Applications.FmsAppModel>

@foreach (var item in Model) {
    <div class="col">
        <h2>@Html.DisplayFor(modelItem => item.friendly_name)</h2>
        <p>@Html.DisplayFor(modelItem => item.app_description)</p>
        <p><strong>Tags:</strong> @Html.DisplayFor(modelItem => item.app_type)</p>

        <a href="#" class="btn btn-primary install-app" data-key-name="@(item.key_name)">Install</a>

        @Html.ActionLink("Details", "Detailss", new {  id=item.app_id  })
    </div>
}
</div>

<script type="text/javascript">
   (function () {
        $('.install-app').on('click', function (e) {
            e.preventDefault();
            var data_key_name = $(this).data('key-name');
            //ajax install app
            $.ajax({
                type: "POST",
                url: '@Url.Action("Deploy")',
                data: {
                    key_name: data_key_name
                }
            });
        });
    })();
</script>

And the model.

和模型。

public class CompiledAppModel
{
    [Display(Name = "Admin URL")]
    public string adminURL { get; set; }

    [Display(Name = "Viewer URL")]
    public string viewerURL { get; set; }

    [Display(Name = "Embed URL")]
    public string embedURL { get; set; }
}

3 个解决方案

#1


4  

I assume that you really want to redirect after making the ajax call.

我假设你真的想在进行ajax调用后重定向。

As far as i know, you have to implement a custom ActionResult, something like:

据我所知,你必须实现一个自定义ActionResult,如:

public class AjaxAwareRedirectResult : RedirectResult
{       
    public AjaxAwareRedirectResult(String url)
        : base(url)
    {
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if ( context.RequestContext.HttpContext.Request.IsAjaxRequest() )
        {
            String destinationUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext);

            JavaScriptResult result = new JavaScriptResult()
            {
                Script = "window.location='" + destinationUrl + "';"
            };
            result.ExecuteResult(context);
        }
        else
        {
            base.ExecuteResult(context);
        }
    }
}

In your controller, just do:

在你的控制器中,只需:

    [HttpPost]
public ActionResult Deploy(string key_name, string custom_folder = "")
{
    string userId = Membership.GetUser().ProviderUserKey.ToString();
    UserDataModel user_info = _user_data_service.getUserDataByPrimaryIDNoDB(userId, HttpContext.Cache);
    log.Trace("Deploy was called. key_name:" + key_name + " UID: " + user_info.UID);
    // first we'll call the info to install remote application
    bool serviceInstall = _fms_app_service.DeployFmsApp(user_info, key_name, custom_folder);
    // then we'll call to generate client side info
    bool clientInstall = _fms_app_service.CompileClientApp(user_info, key_name);

    var model = _fms_app_service.getInstalledAppInfo(user_info, key_name);
    if (serviceInstall && clientInstall)
    {
        return RedirectToAction("Deploy", model);
    }
    return AjaxAwareRedirectResult("/foo");
}

But, as I said, this is just me assuming that you really want to redirect after the ajax call.

但是,正如我所说,这只是我假设你真的想在ajax调用之后重定向。

#2


1  

Looks to me like your using an Ajax call to do your post back to the server, in which case the result isn't going to get rendered to the page without a little extra work. You can define a success handler on the ajax call to take action when the ajax call returns. So something like

在我看来,就像你使用Ajax调用将你的帖子发回服务器一样,在这种情况下,结果不会在没有一点额外工作的情况下呈现给页面。您可以在ajax调用上定义成功处理程序,以便在ajax调用返回时执行操作。所以像

<script type="text/javascript"> (function () {
    $('.install-app').on('click', function (e) {
        e.preventDefault();
        var data_key_name = $(this).data('key-name');
        //ajax install app
        $.ajax({
            type: "POST",
            url: '@Url.Action("Deploy")',
            data: {
                key_name: data_key_name
            },
            success: function(data) { alert(data) }
        });
    });
})();

will give you an alert message with the HTML returned from the ajax call when the request completes.

当请求完成时,将为您提供一条警告消息,其中包含从ajax调用返回的HTML。

I'd also use Firebug or the developer tools in Chrome to view the HTML returned, if there is an exception occurring on the server you should be able to inspect this in more detail using these tools.

我还会使用Chrome中的Firebug或开发人员工具查看返回的HTML,如果服务器上发生异常,您应该可以使用这些工具更详细地检查它。

#3


1  

Doing an HTTP redirect after an ajax call might not make a whole lot of sense. You could do that simply with an html form and a regular POST.

在ajax调用之后执行HTTP重定向可能没有多大意义。您只需使用html表单和常规POST即可。

However, if you really need redirection and still want the POST through AJAX you could do it by returning Json instead of a redirect, as suggested in the following answers:

但是,如果您确实需要重定向并且仍然希望通过AJAX进行POST,则可以通过返回Json而不是重定向来执行此操作,如以下答案中所示:

In that case, you could return the target action url within a Json object, and use that info in your success handler as shown in Neil's answer.

在这种情况下,您可以在Json对象中返回目标操作URL,并在成功处理程序中使用该信息,如Neil的答案所示。

Also, remember that RedirectToAction is just a 302 redirect, therefore, it won't render a view directly so you wouldn't pass it a full-blown ViewModel, just the Action Url for the browser to issue the GET to.

此外,请记住,RedirectToAction只是一个302重定向,因此,它不会直接呈现视图,因此您不会将其传递给完整的ViewModel,只是为了向浏览器发出GET的Action Url。

That target GET action should be the one responsible for obtaining your Installed App Info and passing that as parameter to a view, following the POST-REDIRECT-GET pattern.

该目标GET操作应该是负责获取您的已安装应用程序信息并将其作为参数传递给视图的操作,遵循POST-REDIRECT-GET模式。

#1


4  

I assume that you really want to redirect after making the ajax call.

我假设你真的想在进行ajax调用后重定向。

As far as i know, you have to implement a custom ActionResult, something like:

据我所知,你必须实现一个自定义ActionResult,如:

public class AjaxAwareRedirectResult : RedirectResult
{       
    public AjaxAwareRedirectResult(String url)
        : base(url)
    {
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if ( context.RequestContext.HttpContext.Request.IsAjaxRequest() )
        {
            String destinationUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext);

            JavaScriptResult result = new JavaScriptResult()
            {
                Script = "window.location='" + destinationUrl + "';"
            };
            result.ExecuteResult(context);
        }
        else
        {
            base.ExecuteResult(context);
        }
    }
}

In your controller, just do:

在你的控制器中,只需:

    [HttpPost]
public ActionResult Deploy(string key_name, string custom_folder = "")
{
    string userId = Membership.GetUser().ProviderUserKey.ToString();
    UserDataModel user_info = _user_data_service.getUserDataByPrimaryIDNoDB(userId, HttpContext.Cache);
    log.Trace("Deploy was called. key_name:" + key_name + " UID: " + user_info.UID);
    // first we'll call the info to install remote application
    bool serviceInstall = _fms_app_service.DeployFmsApp(user_info, key_name, custom_folder);
    // then we'll call to generate client side info
    bool clientInstall = _fms_app_service.CompileClientApp(user_info, key_name);

    var model = _fms_app_service.getInstalledAppInfo(user_info, key_name);
    if (serviceInstall && clientInstall)
    {
        return RedirectToAction("Deploy", model);
    }
    return AjaxAwareRedirectResult("/foo");
}

But, as I said, this is just me assuming that you really want to redirect after the ajax call.

但是,正如我所说,这只是我假设你真的想在ajax调用之后重定向。

#2


1  

Looks to me like your using an Ajax call to do your post back to the server, in which case the result isn't going to get rendered to the page without a little extra work. You can define a success handler on the ajax call to take action when the ajax call returns. So something like

在我看来,就像你使用Ajax调用将你的帖子发回服务器一样,在这种情况下,结果不会在没有一点额外工作的情况下呈现给页面。您可以在ajax调用上定义成功处理程序,以便在ajax调用返回时执行操作。所以像

<script type="text/javascript"> (function () {
    $('.install-app').on('click', function (e) {
        e.preventDefault();
        var data_key_name = $(this).data('key-name');
        //ajax install app
        $.ajax({
            type: "POST",
            url: '@Url.Action("Deploy")',
            data: {
                key_name: data_key_name
            },
            success: function(data) { alert(data) }
        });
    });
})();

will give you an alert message with the HTML returned from the ajax call when the request completes.

当请求完成时,将为您提供一条警告消息,其中包含从ajax调用返回的HTML。

I'd also use Firebug or the developer tools in Chrome to view the HTML returned, if there is an exception occurring on the server you should be able to inspect this in more detail using these tools.

我还会使用Chrome中的Firebug或开发人员工具查看返回的HTML,如果服务器上发生异常,您应该可以使用这些工具更详细地检查它。

#3


1  

Doing an HTTP redirect after an ajax call might not make a whole lot of sense. You could do that simply with an html form and a regular POST.

在ajax调用之后执行HTTP重定向可能没有多大意义。您只需使用html表单和常规POST即可。

However, if you really need redirection and still want the POST through AJAX you could do it by returning Json instead of a redirect, as suggested in the following answers:

但是,如果您确实需要重定向并且仍然希望通过AJAX进行POST,则可以通过返回Json而不是重定向来执行此操作,如以下答案中所示:

In that case, you could return the target action url within a Json object, and use that info in your success handler as shown in Neil's answer.

在这种情况下,您可以在Json对象中返回目标操作URL,并在成功处理程序中使用该信息,如Neil的答案所示。

Also, remember that RedirectToAction is just a 302 redirect, therefore, it won't render a view directly so you wouldn't pass it a full-blown ViewModel, just the Action Url for the browser to issue the GET to.

此外,请记住,RedirectToAction只是一个302重定向,因此,它不会直接呈现视图,因此您不会将其传递给完整的ViewModel,只是为了向浏览器发出GET的Action Url。

That target GET action should be the one responsible for obtaining your Installed App Info and passing that as parameter to a view, following the POST-REDIRECT-GET pattern.

该目标GET操作应该是负责获取您的已安装应用程序信息并将其作为参数传递给视图的操作,遵循POST-REDIRECT-GET模式。