HTTPError异常在服务器上运行webapi与在本地运行时不显示消息

时间:2014-04-24 19:27:25

标签: c# iis-7.5 httpcontent

我有一个在IIS7.5服务器上运行的webapi。它有3个控制器,所有3个控制器都可用于从我的应用程序中的调用中访问webapi。

我有一个错误,我的控制器的基类将其功能公开,而不是保护。这导致服务器抛出内部服务器错误500(因为抛出了无效的异常“找到了与请求匹配的多个操作”)。我花了一段时间来深入研究这个,因为它从未触发过我的webapi的日志记录。从这个讨论here,我发现发生的错误发生在Application_Error函数捕获它以记录它之前。所以我将以下代码添加到我的webapi的global.asax中,现在我可以记录这样的错误。

但我现在的问题是,当我在运行我的webapi的本地计算机上导致内部服务器错误500时,我得到一个日志,我希望看到它的“ExceptionMessage”“多个动作是发现匹配请求“拼写为内部服务器错误的原因。但是当将这个确切的代码部署到服务器并从那里使用webapi时,我的日志只显示“消息”:“发生了错误”并且没有向我显示“ExceptionMessage”,即使我可以看到异常是使用PerfView抛出。我只需要能够获取我的服务器日志以显示与本地日志显示的信息相同的信息。

public class ResponseExceptionTrapper : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        return base
            .SendAsync(request, cancellationToken)
            .ContinueWith(response =>
            {
                var result = response.Result;
                if (!result.IsSuccessStatusCode)
                {
                    var exceptionResult = string.Format(
                         "Response exception: \r\n Path({0}) \r\n Status({1}) \r\n",
                         request.RequestUri,
                         result.StatusCode);

                    if (result.Content != null)
                    {
                        var exceptionReadTask =
                               result.Content.ReadAsStringAsync();

                        exceptionReadTask.Wait();
                        exceptionResult += "Message:" +
                                          exceptionReadTask.Result;

                    }

                    // Do something appropriate with exceptionResult
                    exceptionResult.Log();
                }

                return result;
            }, cancellationToken);
    }
}

服务器日志示例:

Timestamp: 4/24/2014 12:24:40 PM
Message: Timestamp: 4/24/2014 4:24:40 PM
Message: Response exception: 
Path(http://webserver/CreditReporting/Api/RetrieveQueuedPullCreditReport) 
Status(InternalServerError) 
Message:{"Message":"An error has occurred."}

本地日志示例:

Timestamp: 4/24/2014 12:03:16 PM
Message: Timestamp: 4/24/2014 4:03:16 PM
Message: Response exception: 
 Path(http://localhost:XXXXX/Api/RetrieveQueuedPullCreditReport) 
 Status(InternalServerError)
 Message:
  {"Message":"An error has occurred.",
  "ExceptionMessage":"Multiple actions were found that match the request:
    \r\nSystem.Threading.Tasks.Task`1[
 Our.WebServices.CreditReporting.Contracts.RetrieveQueuedPullCreditReportResponse] Post

2 个答案:

答案 0 :(得分:58)

我发现需要在webapi本身的GlobalConfiguration中打开这些:

1: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly;
2: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
3: config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;

服务器实际上确定要显示多少细节,默认为LocalOnly。

我们的日志记录方法不被认为是本地的,我想因为它实际上并没有构建在API本身中,而是因为它位于多个API之间的共享dll中。

我发现 this 文章非常有帮助。

答案 1 :(得分:4)

我用过这个:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class Etst extends Application {

    @Override

    public void start(Stage primaryStage) {
        GridPane grid = new GridPane();
        // Labels & inputs Settings
        Label number1 = new Label("Data 1 :");
        Label number2 = new Label("Data 2 :");
        Label number3 = new Label("Data 3 :");
        Label number4 = new Label("Data 4 :");
        Label number5 = new Label("Data 5 :");
        Label resultat1 = new Label("The Result");
        TextField txt1 = new TextField();
        TextField txt2 = new TextField();
        TextField txt3 = new TextField();
        TextField txt4 = new TextField();
        TextField txt5 = new TextField();
        grid.add(number1, 0, 0);
        grid.add(number2, 0, 1);
        grid.add(number3, 0, 2);
        grid.add(number4, 0, 3);
        grid.add(number5, 0, 4);
        grid.add(resultat1, 0, 6);
        grid.add(txt1, 1, 0);
        grid.add(txt2, 1, 1);
        grid.add(txt3, 1, 2);
        grid.add(txt4, 1, 3);
        grid.add(txt5, 1, 4);
        Button butt = new Button();
        butt.setText("Applique KPPV");
        grid.add(butt, 0, 5);
        // My Main Method
        ///////////////////////////////////


        // ADDED THESE 5 LINES. NOW IT SHOWS A WINDOW WITH THESE VALUES FILLED IN
        txt1.setText("0.0");
        txt2.setText("0.0");
        txt3.setText("0.0");
        txt4.setText("0.0");
        txt5.setText("0.0");

        double insertedInt = Double.parseDouble(txt1.getText());
        double insertedInt2 = Double.parseDouble(txt2.getText());
        double insertedInt3 = Double.parseDouble(txt3.getText());
        double insertedInt4 = Double.parseDouble(txt4.getText());
        double insertedInt5 = Double.parseDouble(txt5.getText());
        double[] query = { insertedInt, insertedInt2, insertedInt3, insertedInt4, insertedInt5 };

        int k = 10;// K : Welaya List Counts
        List<City> cityList = new ArrayList<City>();
        List<Result> resultList = new ArrayList<Result>();
        cityList.add(new City(instances[0], "IRIS0"));
        cityList.add(new City(instances[1], "IRIS1"));
        cityList.add(new City(instances[2], "IRIS2"));
        cityList.add(new City(instances[3], "IRIS3"));
        cityList.add(new City(instances[4], "IRIS4"));
        cityList.add(new City(instances[5], "IRIS5"));
        cityList.add(new City(instances[6], "IRIS6"));
        cityList.add(new City(instances[7], "IRIS7"));
        cityList.add(new City(instances[8], "IRIS8"));
        cityList.add(new City(instances[9], "IRIS9"));
        // find distances
        for (City city : cityList) {
            double dist = 0.0;
            for (int j = 0; j < city.cityAttributes.length; j++) {
                dist += Math.pow(city.cityAttributes[j] - query[j], 2);
            }
            double distance = Math.sqrt(dist);
            resultList.add(new Result(distance, city.cityName));

        }

        Collections.sort(resultList, new DistanceComparator());
        String[] ss = new String[k];
        for (int x = 0; x < k; x++) {
            ss[x] = resultList.get(x).cityName;
        }
        String majClass = findMajorityClass(ss);
        // System.out.println("The Nearest IRIS Class is : "+majClass);

        ///////////////////////////////////
        Scene scene = new Scene(grid, 300, 250);

        // Final Action
        butt.setOnAction(event -> {
            resultat1.setText(majClass);
        });
        primaryStage.setTitle("KNN With JDK");
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    /**
     * @param args
     *            the command line arguments
     */
    public static void main(String[] args) {
        launch(args);

    }

    // My Method
    // our Data Base
    static double[][] instances = { { 6.300000, 2.500000, 5.000000, 1.900000, 3.000000 },
            { 6.900000, 3.200000, 5.700000, 2.300000, 3.000000 }, { 5.100000, 3.800000, 1.900000, 0.400000, 1.000000 },
            { 6.600000, 2.900000, 4.600000, 1.300000, 2.000000 }, { 5.700000, 4.400000, 1.500000, 0.400000, 1.000000 },
            { 4.600000, 3.400000, 1.400000, 0.300000, 1.000000 }, { 4.300000, 3.000000, 1.100000, 0.100000, 1.000000 },
            { 6.900000, 3.100000, 5.100000, 2.300000, 3.000000 }, { 5.100000, 3.700000, 1.500000, 0.400000, 1.000000 },
            { 6.100000, 2.800000, 4.700000, 1.200000, 2.000000 },

    };

    private static String findMajorityClass(String[] array) {
        // add the String array to a HashSet to get unique String values
        Set<String> h = new HashSet<String>(Arrays.asList(array));
        // convert the HashSet back to array
        String[] uniqueValues = h.toArray(new String[0]);
        // counts for unique strings
        int[] counts = new int[uniqueValues.length];
        // loop thru unique strings and count how many times they appear in
        // origianl array
        for (int i = 0; i < uniqueValues.length; i++) {
            for (int j = 0; j < array.length; j++) {
                if (array[j].equals(uniqueValues[i])) {
                    counts[i]++;
                }
            }
        }

        for (int i = 0; i < uniqueValues.length; i++)
            System.out.println(uniqueValues[i]);
        for (int i = 0; i < counts.length; i++)
            System.out.println(counts[i]);

        int max = counts[0];
        for (int counter = 1; counter < counts.length; counter++) {
            if (counts[counter] > max) {
                max = counts[counter];
            }
        }
        System.out.println("max # of occurences: " + max);
        int freq = 0;
        for (int counter = 0; counter < counts.length; counter++) {
            if (counts[counter] == max) {
                freq++;
            }
        }
        int index = -1;
        if (freq == 1) {
            for (int counter = 0; counter < counts.length; counter++) {
                if (counts[counter] == max) {
                    index = counter;
                    break;
                }
            }
            // System.out.println("one majority class, index is: "+index);
            return uniqueValues[index];
        } else {// we have multiple modes
            int[] ix = new int[freq];// array of indices of modes
            System.out.println("multiple majority classes: " + freq + " classes");
            int ixi = 0;
            for (int counter = 0; counter < counts.length; counter++) {
                if (counts[counter] == max) {
                    ix[ixi] = counter;// save index of each max count value
                    ixi++; // increase index of ix array
                }
            }

            for (int counter = 0; counter < ix.length; counter++)
                System.out.println("class index: " + ix[counter]);

            // now choose one at random
            Random generator = new Random();
            // get random number 0 <= rIndex < size of ix
            int rIndex = generator.nextInt(ix.length);
            System.out.println("random index: " + rIndex);
            int nIndex = ix[rIndex];
            // return unique value at that index
            return uniqueValues[nIndex];
        }

    }

    private static double meanOfArray(double[] m) {
        double sum = 0.0;
        for (int j = 0; j < m.length; j++) {
            sum += m[j];
        }
        return sum / m.length;
    }

    // simple class to model instances (features + class)
    static class City {
        double[] cityAttributes;
        String cityName;

        public City(double[] cityAttributes, String cityName) {
            this.cityName = cityName;
            this.cityAttributes = cityAttributes;
        }
    }

    // simple class to model results (distance + class)
    static class Result {
        double distance;
        String cityName;

        public Result(double distance, String cityName) {
            this.cityName = cityName;
            this.distance = distance;
        }
    }

    // simple comparator class used to compare results via distances
    static class DistanceComparator implements Comparator<Result> {
        @Override
        public int compare(Result a, Result b) {
            return a.distance < b.distance ? -1 : a.distance == b.distance ? 0 : 1;
        }
    }

}

在Global of API中 它成功了。