如何在knockout视图模型中绑定服务器端异常?

时间:2013-04-29 11:51:48

标签: knockout.js

我正在向服务器发出ajax调用请求一些数据。例如:http / get(SomeDataService)。 在控制器中,我有如下数据对象:

API控制器:

public DataCollection getSomeData()
{
try{
// get the data in object and checking its null or not. 
//If not null, will bind the data in ko viewModel.if null throw below exception.
}
catch(Exception e)
{
e. message(" No Data Found")
}
}

现在我想在KO viewModel和视图中绑定“找不到数据”消息。

请建议我怎么做?我是KO,ASP.net的新手

我再次重新发布我真正需要的东西。 1.进行web api Ajax调用

function GetData() {

            var data = http.get(apiUrl)
            .success(function (data) {
                if (data != null )
                {
                    // some stuff for success data

                    vm.getDataSuccess;
                }
                else {
                    vm.errorMessage();// server side exception message.

            })
  1. WebApi控制器:

    public DataCollection GetSomeData() {     var data = GetData();     if(data == null){         抛出新的异常(“数据为空”);

    }

  2. 我创建了如下的viewmodel:

    var vm = {             激活:激活,         getDataSuccess:ko.observableArray(),             的errorMessage:ko.observable(),             标题:'TopNews'         };

  3. 在其中一个div中的视图页面上进行绑定

    - < -div class =“error”data-bind =“text:errorMessage”/>

    我不确定上述方法是否正确。但我需要这样。

4 个答案:

答案 0 :(得分:1)

在服务器端代码中,您应该将异常包装到HttpResponseException中:

try
{
    // ... your stuff here
}
catch (Exception exception)
{
    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
    {
        ReasonPhrase = exception.Message
    });
}

您通常可以在jquery的.ajaxError处理程序中捕获此消息。

甚至更高级,创建自定义KO绑定:

ko.bindingHandlers.flash = {
    prepareInfo: function (valueAccessor) {
        var info = {},
            options = ko.utils.unwrapObservable(valueAccessor());

        if (options && options.value) {
            info.value = options.value;
        } else {
            info.value = valueAccessor();
        }

        return info;
    },
    init: function (element, valueAccessor) {
        var info = ko.bindingHandlers.flash.prepareInfo(valueAccessor);

        $(element)
            .ajaxError(function (event, xhr, ajaxSettings, errorThrown) {
                info.value(errorThrown);
             }).ajaxSend(function () {
                info.value(null);
             });

        $(element).hide();
    },
    update: function (element, valueAccessor) {
        var info = ko.bindingHandlers.flash.prepareInfo(valueAccessor);
        if (info.value()) {
            $(element).stop().hide().text(info.value()).fadeIn(function () {
                clearTimeout($(element).data("timeout"));
                $(element).data("timeout", setTimeout(function () {
                    $(element).fadeOut('fast');
                    info.value(null);
                }, 3000));
            });
        }
    }
};

然后只需在HTML中的某处添加一个DIV,并将数据绑定添加到此绑定中。

答案 1 :(得分:0)

你必须将它添加到你返回视图的模型中,即。你的viewmodel。

如果你使用ajax,那么你抛出的异常将返回给ajax函数 拨打:

$.ajax({
            type: "POST",
            url: "/chart/setfilter",
            data: JSON.stringify(filters),
            dataType: "json",
            contentType: "application/json; charset=utf-8"
        }).done(function (res, status, xhr) {
            //here res will contain the exception

        });

答案 2 :(得分:0)

您应该使用成功和错误参数(doc)。

尝试类似this的内容。

$.ajax({
    type: "GET",
    url: "error.com", // your url
    error: function (jqXHR, textStatus, errorThrown) {
        vm.response('Error ' + errorThrown)
    },
    success: function (respo) {
        vm.response("Success" + response)
    }
})

答案 3 :(得分:0)

根据我的经验,无缝处理此问题的最佳方法是设置您的web api,以便它不负责处理意外错误。这使得web api代码非常简洁,如下所示:

public DataCollection GetSomeData()
{
    var data = GetData();
    return data;
}

如果您因任何原因想要抛出自定义异常 - 如果数据为空,您可能会显示一条特定的消息 - 您可以正常抛出异常:

public DataCollection GetSomeData()
{
    var data = GetData();
    if( data == null ){
        throw new Exception("Data is null");
        //or... throw new MyCustomException("Data is null");  
    }
}

现在,到目前为止,这种方法是不可接受的,因为它可能会将敏感的服务器信息暴露给客户端。为了清楚地处理这个问题,请创建一个处理异常的自定义操作过滤器。像这样:

/// <summary>
/// Represents an attribute that will automatically process any unhandled exceptions
/// that occur during during the execution of a web api action
/// </summary>
public class HandleExceptionAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        //log the error (make sure LogError doesn't throw any exceptions)
        LogError(actionExecutedContext);

        //set up a default message that is safe to send to the client 
        // (doesn't expose any sensitive exception information)
        var message = "An error has occured please try your request again later";

        //if the exception is, or inherits from MyCustomException, then 
        //  go ahead and forward the message on the client
        if (actionExecutedContext.Exception is MyCustomException)
        {
            message = actionExecutedContext.Exception.Message;
        }

        actionExecutedContext.Response = 
            actionExecutedContext.Request.CreateResponse(HttpStatusCode.InternalServerError, message);
    }
}

请务必全局应用此操作过滤器,以便它适用于所有Web api方法,而无需任何开发人员干预。这样您就可以确信没有未处理的异常会将原始异常消息抛回客户端。


现在您正确地从服务器返回错误,您可以通过多种方式向用户显示消息。最干净的事情是立即显示消息,而不是尝试将其添加到视图模型中。您可以使用toast.js或其他一些通知机制(甚至是window.alert()向用户显示一条消息,直到您走得更远。)

这是关于Stack Overflow的另一个问题,可能有助于做出这个决定:knockout js best practices ajax error handling