问:
How to log Http Request body in Spring MVC?
Just think it will be a useful feature for dev stage. Is it something I can configure or requires a bit coding? Thank you stackers!</p>

答:
Take a look at the AbstractRequestLoggingFilter family of filters.

Aslo it may be convenient to use client-side tools for debugging, such as Firebug or Fiddler.


来源: stackexchange

问:
How to vertically center a span/svg inside a div
Fiddle: https://jsfiddle.net/6yfv3u5m/

HTML:

```<code><div id="dvMore">
    <div id="dvMore2">
        <span id="spMore">View More</span>
        <svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="#000000" d="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"></path></svg>
    </div>
</div>
</code>```

I don't have a height, just dynamic content.

Edit: Tried to set dvMore2 to vertically-align: center. Also tried to add a placeholder span and set the vertical-align to center but none of them worked.

答:
Use the vertical-align property like below. You need to set it on the children, not the parent itself:

#dvMore2 * {
  vertical-align: middle;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div id="dvMore">
  <div id="dvMore2">
    <span id="spMore">View More</span>
    <svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="#000000" d="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"></path></svg>
  </div>
</div></code>```

ContentLicense: CC BY-SA 3.0

Body:
Fiddle: https://jsfiddle.net/6yfv3u5m/

HTML:

        View More
        <svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="#000000" d="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"></path></svg>

I don't have a height, just dynamic content.

Edit: Tried to set dvMore2 to vertically-align: center. Also tried to add a placeholder span and set the vertical-align to center but none of them worked.

Body:
Use the vertical-align property like below. You need to set it on the children, not the parent itself:

#dvMore2 * {
  vertical-align: middle;
}

<div id="dvMore">
  <div id="dvMore2">
    <span id="spMore">View More</span>
    <svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="#000000" d="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"></path></svg>
  </div>
</div>


问:
Split users in teams
I have a list with a random number of users, and a class Team.
Each team can hold maximum 9 users.
So, I want to split them in teams but I'm stuck.
I coded the thing if the users are < 9 but,
if the users are > 9  means that I have to create a new team and then set the other users inside the new team while looping the users.
I'm stuck because the constructor of the class Team must be with 2 users.

Main

```<code>private static List<Team> _teams = new ArrayList<>();

public static void main (String[] args)
{
    final List<User> allUsers = Arrays.asList(
                new User("Lily",1),
                new User("Kecia",2),
                new User("Tanika",3),
                new User("Julieta",4),
                new User("Alla",5),
                new User("Pennie",6),
                new User("Anna",7),
                new User("Mohammad",8),
                new User("John",9)
            );
    Collections.shuffle(allUsers);
    makeTeams(allUsers);
}
public static void makeTeams(List<User> users)
{
    if (users.size() > 9)
    {
        //here
    }
    else
    {
        User first = users.get(0);
        User sec = users.get(1);

        Team team = new Team(first,sec);

        first.setTeam(team);
        sec.setTeam(team);

        for (User user : users)
        {
            if (team.getUsers().contains(user))
                continue;

            team.add(user);
            user.setTeam(team);
        }
        _teams.add(team);
    }

    _teams.forEach(System.out::println);
}
</code>```

User

```<code>public class User {

private String _name;
private int _objId;
private Team _team;
public User(String name,int objId)
{
    _name = name;
    _objId = objId;
}

public String getName()
{
    return _name;
}
public int getObjId()
{
    return _objId;
}

public void setTeam(Team team)
{
    _team = team;
}
</code>```

}

Team

```<code>public class Team {

private final List<User> _users = new ArrayList<>();

public Team(User first, User second) {
    _users.add(first);
    _users.add(second);
}

public void add(User mem) {
    _users.add(mem);
}

@Override
public String toString()
{
    StringBuilder sb = new StringBuilder();

    sb.append("======== Team =========\n");
    _users.forEach(user -> sb.append(user.getName() + "\n"));
    sb.append("=======================\n");

    return sb.toString();
}

public List<User> getUsers ()
{
    return _users;
}
</code>```

}

in the specific example the users are 9 and the output is

```<code>======== Team =========
Mohammad
John
Julieta
Kecia
Anna
Tanika
Alla
Lily
Pennie
=======================
</code>```

答:
I would like to suggest you to do some refactor on your "business logic" a little bit.

I think you do not need to have Team class and it makes your life a little bit easier.

Your User class looks fine but I suggest you to overwrite the toString method which will help you to display the result:

```<code>public class User {

    private String name;
    private Integer id;

    // constructor
    public User(final String name, final Integer id) {
        this.name = name;
        this.id = id;
    }

    @Override
    public String toString() {
        return name + ":" + id;
    }

    // getter and setter methods
}
</code>```

And this is the main application which split users between teams. The most important methods here is the calculateTeams which split users between teams:

```<code>public class AllocateTeams {
    private static final int MEMBERS_IN_TEAM = 9;

    public static void main(String[] args) {
        List<User> users = getUsers();
        //int numberOfTeams = getNumberOfTeams(users);
        List<List<User>> teams = calculateTeams(users, MEMBERS_IN_TEAM);

        System.out.println(String.format("Number of the individual players: %d", users.size()));
        System.out.println(String.format("Maximum players in a team: %d", MEMBERS_IN_TEAM));
        System.out.println(String.format("Number of the teams: %d", teams.size()));
        printTeams(teams);
    }

    private static void printTeams(final List<List<User>> teams) {
        int teamIndex = 0;
        for (List<User> team : teams) {
            teamIndex++;
            System.out.println(String.format("---------- team %d ----------", teamIndex));
            System.out.println(team);
        }
    }

    private static List<List<User>> calculateTeams(final List<User> users, final int memberInTeam) {
        List<List<User>> teams = new ArrayList<>();
        int teamNumber = getNumberOfTeams(users, memberInTeam);

        for (int teamIndex = 0; teamIndex < teamNumber; teamIndex++) {
            List<User> team = new ArrayList<>();

            for (int userIndexPerTeam = 0; userIndexPerTeam < memberInTeam; userIndexPerTeam++) {
                int userIndex = userIndexPerTeam + (teamIndex * memberInTeam);

                if (userIndex < users.size()) {
                    team.add(users.get(userIndex));
                }
            }

            teams.add(team);
        }

        return teams;
    }

    private static int getNumberOfTeams(final List<User> users, final int memberInTeam) {
        return (users.size() + memberInTeam - 1) / memberInTeam;
    }

    private static List<User> getUsers() {
        int id = 0;
        List<User> users = new ArrayList<>();
        users.add(new User("Peter", id++));
        users.add(new User("Alfonso", id++));
        users.add(new User("Arthur", id++));
        users.add(new User("Ashley", id++));
        users.add(new User("Arnold", id++));
        users.add(new User("Andy", id++));
        users.add(new User("Augustus", id++));
        users.add(new User("Angelo", id++));
        users.add(new User("Alan", id++));
        users.add(new User("Albert", id++));
        users.add(new User("Nick", id++));
        users.add(new User("Nicolas", id++));
        users.add(new User("Norris", id++));
        users.add(new User("Fiona", id++));
        users.add(new User("Fidela", id++));
        users.add(new User("Fanny", id++));
        users.add(new User("Francesca", id++));
        users.add(new User("Paula", id++));
        users.add(new User("Eliza", id++));
        users.add(new User("Elizbeth", id++));
        users.add(new User("Ernestina", id++));
        users.add(new User("Sharda", id++));
        users.add(new User("Shara", id++));

        Collections.shuffle(users);
        return users;
    }
}
</code>```

This is the outcome:

```<code>Number of the individual players: 23
Maximum players in a team: 9
Number of the teams: 3
---------- team 1 ----------
[Albert:9, Norris:12, Francesca:16, Paula:17, Ernestina:20, Alan:8, Fidela:14, Nicolas:11, Fanny:15]
---------- team 2 ----------
[Andy:5, Fiona:13, Peter:0, Shara:22, Arnold:4, Elizbeth:19, Eliza:18, Sharda:21, Augustus:6]
---------- team 3 ----------
[Arthur:2, Nick:10, Ashley:3, Angelo:7, Alfonso:1]
</code>```

I hope that the code is clear any you can understand it.

Title: Split users in teams

Body:
I have a list with a random number of users, and a class Team.
Each team can hold maximum 9 users.
So, I want to split them in teams but I'm stuck.
I coded the thing if the users are < 9 but,
if the users are > 9  means that I have to create a new team and then set the other users inside the new team while looping the users.
I'm stuck because the constructor of the class Team must be with 2 users.

Main

private static List<Team> _teams = new ArrayList<>();

public static void main (String[] args)
{
    final List<User> allUsers = Arrays.asList(
                new User("Lily",1),
                new User("Kecia",2),
                new User("Tanika",3),
                new User("Julieta",4),
                new User("Alla",5),
                new User("Pennie",6),
                new User("Anna",7),
                new User("Mohammad",8),
                new User("John",9)
            );
    Collections.shuffle(allUsers);
    makeTeams(allUsers);
}
public static void makeTeams(List<User> users)
{
    if (users.size() > 9)
    {
        //here
    }
    else
    {
        User first = users.get(0);
        User sec = users.get(1);

        Team team = new Team(first,sec);

        first.setTeam(team);
        sec.setTeam(team);

        for (User user : users)
        {
            if (team.getUsers().contains(user))
                continue;

            team.add(user);
            user.setTeam(team);
        }
        _teams.add(team);
    }

    _teams.forEach(System.out::println);
}

User

public class User {

private String _name;
private int _objId;
private Team _team;
public User(String name,int objId)
{
    _name = name;
    _objId = objId;
}

public String getName()
{
    return _name;
}
public int getObjId()
{
    return _objId;
}

public void setTeam(Team team)
{
    _team = team;
}

}

Team

public class Team {

private final List<User> _users = new ArrayList<>();

public Team(User first, User second) {
    _users.add(first);
    _users.add(second);
}

public void add(User mem) {
    _users.add(mem);
}

@Override
public String toString()
{
    StringBuilder sb = new StringBuilder();

    sb.append("======== Team =========\n");
    _users.forEach(user -> sb.append(user.getName() + "\n"));
    sb.append("=======================\n");

    return sb.toString();
}

public List<User> getUsers ()
{
    return _users;
}

}

in the specific example the users are 9 and the output is

======== Team =========
Mohammad
John
Julieta
Kecia
Anna
Tanika
Alla
Lily
Pennie
=======================

Body:
I would like to suggest you to do some refactor on your "business logic" a little bit.

I think you do not need to have Team class and it makes your life a little bit easier.

Your User class looks fine but I suggest you to overwrite the toString method which will help you to display the result:

public class User {

    private String name;
    private Integer id;

    // constructor
    public User(final String name, final Integer id) {
        this.name = name;
        this.id = id;
    }

    @Override
    public String toString() {
        return name + ":" + id;
    }

    // getter and setter methods
}

And this is the main application which split users between teams. The most important methods here is the calculateTeams which split users between teams:

public class AllocateTeams {
    private static final int MEMBERS_IN_TEAM = 9;

    public static void main(String[] args) {
        List<User> users = getUsers();
        //int numberOfTeams = getNumberOfTeams(users);
        List<List<User>> teams = calculateTeams(users, MEMBERS_IN_TEAM);

        System.out.println(String.format("Number of the individual players: %d", users.size()));
        System.out.println(String.format("Maximum players in a team: %d", MEMBERS_IN_TEAM));
        System.out.println(String.format("Number of the teams: %d", teams.size()));
        printTeams(teams);
    }

    private static void printTeams(final List<List<User>> teams) {
        int teamIndex = 0;
        for (List<User> team : teams) {
            teamIndex++;
            System.out.println(String.format("---------- team %d ----------", teamIndex));
            System.out.println(team);
        }
    }

    private static List<List<User>> calculateTeams(final List<User> users, final int memberInTeam) {
        List<List<User>> teams = new ArrayList<>();
        int teamNumber = getNumberOfTeams(users, memberInTeam);

        for (int teamIndex = 0; teamIndex < teamNumber; teamIndex++) {
            List<User> team = new ArrayList<>();

            for (int userIndexPerTeam = 0; userIndexPerTeam < memberInTeam; userIndexPerTeam++) {
                int userIndex = userIndexPerTeam + (teamIndex * memberInTeam);

                if (userIndex < users.size()) {
                    team.add(users.get(userIndex));
                }
            }

            teams.add(team);
        }

        return teams;
    }

    private static int getNumberOfTeams(final List<User> users, final int memberInTeam) {
        return (users.size() + memberInTeam - 1) / memberInTeam;
    }

    private static List<User> getUsers() {
        int id = 0;
        List<User> users = new ArrayList<>();
        users.add(new User("Peter", id++));
        users.add(new User("Alfonso", id++));
        users.add(new User("Arthur", id++));
        users.add(new User("Ashley", id++));
        users.add(new User("Arnold", id++));
        users.add(new User("Andy", id++));
        users.add(new User("Augustus", id++));
        users.add(new User("Angelo", id++));
        users.add(new User("Alan", id++));
        users.add(new User("Albert", id++));
        users.add(new User("Nick", id++));
        users.add(new User("Nicolas", id++));
        users.add(new User("Norris", id++));
        users.add(new User("Fiona", id++));
        users.add(new User("Fidela", id++));
        users.add(new User("Fanny", id++));
        users.add(new User("Francesca", id++));
        users.add(new User("Paula", id++));
        users.add(new User("Eliza", id++));
        users.add(new User("Elizbeth", id++));
        users.add(new User("Ernestina", id++));
        users.add(new User("Sharda", id++));
        users.add(new User("Shara", id++));

        Collections.shuffle(users);
        return users;
    }
}

This is the outcome:

Number of the individual players: 23
Maximum players in a team: 9
Number of the teams: 3
---------- team 1 ----------
[Albert:9, Norris:12, Francesca:16, Paula:17, Ernestina:20, Alan:8, Fidela:14, Nicolas:11, Fanny:15]
---------- team 2 ----------
[Andy:5, Fiona:13, Peter:0, Shara:22, Arnold:4, Elizbeth:19, Eliza:18, Sharda:21, Augustus:6]
---------- team 3 ----------
[Arthur:2, Nick:10, Ashley:3, Angelo:7, Alfonso:1]

I hope that the code is clear any you can understand it.


问:
Angular UI grid : export hidden columns when user selects Export Visible data
Hi I am using Angular UI grid. I have 3 columns. One of the column is hidden. When user clicks on Export Visible data as CSV or Export Visible data as Pdf the hidden column also needs to be exported. How can I achieve this?

Here is a link to the plunkr
http://plnkr.co/edit/Vwq7azXtx0GV7idvrSvq?p=preview

HTML:
Here is my code

```<code><!doctype html>
<html ng-app="app">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-touch.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
    <script src="http://ui-grid.info/release/ui-grid.js"></script>
    <link rel="stylesheet" href="http://ui-grid.info/release/ui-grid.css" type="text/css">
    <link rel="stylesheet" href="main.css" type="text/css">
  </head>
  <body>

<div ng-controller="MainCtrl">
  <div ui-grid="gridOptions" ui-grid-selection ui-grid-exporter class="grid"></div>
</div>
</code>```

JS

```<code><script src="app.js"></script>
  </body>
</html>
var app = angular.module('app', ['ngAnimate', 'ngTouch', 'ui.grid', 'ui.grid.selection', 'ui.grid.exporter']);

app.controller('MainCtrl', ['$scope', '$http', function ($scope, $http) {
  $scope.gridOptions = {
    columnDefs: [
      { field: 'name' },
      { field: 'gender', visible: false},
      { field: 'company' }
    ],
    enableGridMenu: true,
    enableSelectAll: true,
    exporterCsvFilename: 'myFile.csv',
    exporterPdfDefaultStyle: {fontSize: 9},
    exporterPdfOrientation: 'portrait',
    exporterPdfPageSize: 'LETTER',
    exporterPdfMaxGridWidth: 500,
    onRegisterApi: function(gridApi){
      $scope.gridApi = gridApi;
    }
  };

  $http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/100.json')
  .success(function(data) {
    $scope.gridOptions.data = data;
  });

}]);
</code>```

Here column gender is hidden. But when I click on Export Visible data as csv/pdf I want this hidden column to be exported too.

答:
I have the same requirement and was able to accomplish this with the following.

```<code>$scope.gridOptions = {
    exporterMenuCsv: true,
    exporterMenuPdf: true,
    exporterMenuVisibleData: false, // suppress default menu options

    columnDefs: [
        // define columns
    ],

    onRegisterApi: function (gridApi) {
        const grid = gridApi.grid;

        // add our own export visible data menu option
        // we want to export all columns, not just visible ones
        // add a small delay because the addToGridMenu function
        // may not be defined yet when this code is executed
        $timeout( function() {
            grid.api.core.addToGridMenu(grid, [
                {
                    title: i18nService.getSafeText('gridMenu.exporterVisibleAsCsv'),
                    action: function ($event) {
                        grid.api.exporter.csvExport(uiGridExporterConstants.VISIBLE, uiGridExporterConstants.ALL);
                    },
                    shown: function () {
                        return grid.options.exporterMenuCsv;
                    },
                    order: grid.options.exporterMenuItemOrder + 1
                },
                {
                    title: i18nService.getSafeText('gridMenu.exporterVisibleAsPdf'),
                    action: function ($event) {
                        grid.api.exporter.pdfExport(uiGridExporterConstants.VISIBLE, uiGridExporterConstants.ALL);
                    },
                    shown: function () {
                        return grid.options.exporterMenuPdf;
                    },
                    order: grid.options.exporterMenuItemOrder + 4
                }
            ]);
        }, 200 );
    }
}
</code>```

The code hides the default "Export visible data..." menu options added by the ui-grid-exporter module and adds new ones. The action function calls the export method specifying uiGridExporterConstants.ALL instead of uiGridExporterConstants.VISIBLE for the column type.

Body:
Hi I am using Angular UI grid. I have 3 columns. One of the column is hidden. When user clicks on Export Visible data as CSV or Export Visible data as Pdf the hidden column also needs to be exported. How can I achieve this?

Here is a link to the plunkr
http://plnkr.co/edit/Vwq7azXtx0GV7idvrSvq?p=preview

HTML:
Here is my code

<!doctype html>

    <link rel="stylesheet" href="http://ui-grid.info/release/ui-grid.css" type="text/css">
    <link rel="stylesheet" href="main.css" type="text/css">

JS

var app = angular.module('app', ['ngAnimate', 'ngTouch', 'ui.grid', 'ui.grid.selection', 'ui.grid.exporter']);

app.controller('MainCtrl', ['$scope', '$http', function ($scope, $http) {
  $scope.gridOptions = {
    columnDefs: [
      { field: 'name' },
      { field: 'gender', visible: false},
      { field: 'company' }
    ],
    enableGridMenu: true,
    enableSelectAll: true,
    exporterCsvFilename: 'myFile.csv',
    exporterPdfDefaultStyle: {fontSize: 9},
    exporterPdfOrientation: 'portrait',
    exporterPdfPageSize: 'LETTER',
    exporterPdfMaxGridWidth: 500,
    onRegisterApi: function(gridApi){
      $scope.gridApi = gridApi;
    }
  };

  $http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/100.json')
  .success(function(data) {
    $scope.gridOptions.data = data;
  });

}]);

Here column gender is hidden. But when I click on Export Visible data as csv/pdf I want this hidden column to be exported too.

Body:
I have the same requirement and was able to accomplish this with the following.

$scope.gridOptions = {
    exporterMenuCsv: true,
    exporterMenuPdf: true,
    exporterMenuVisibleData: false, // suppress default menu options

    columnDefs: [
        // define columns
    ],

    onRegisterApi: function (gridApi) {
        const grid = gridApi.grid;

        // add our own export visible data menu option
        // we want to export all columns, not just visible ones
        // add a small delay because the addToGridMenu function
        // may not be defined yet when this code is executed
        $timeout( function() {
            grid.api.core.addToGridMenu(grid, [
                {
                    title: i18nService.getSafeText('gridMenu.exporterVisibleAsCsv'),
                    action: function ($event) {
                        grid.api.exporter.csvExport(uiGridExporterConstants.VISIBLE, uiGridExporterConstants.ALL);
                    },
                    shown: function () {
                        return grid.options.exporterMenuCsv;
                    },
                    order: grid.options.exporterMenuItemOrder + 1
                },
                {
                    title: i18nService.getSafeText('gridMenu.exporterVisibleAsPdf'),
                    action: function ($event) {
                        grid.api.exporter.pdfExport(uiGridExporterConstants.VISIBLE, uiGridExporterConstants.ALL);
                    },
                    shown: function () {
                        return grid.options.exporterMenuPdf;
                    },
                    order: grid.options.exporterMenuItemOrder + 4
                }
            ]);
        }, 200 );
    }
}

The code hides the default "Export visible data..." menu options added by the ui-grid-exporter module and adds new ones. The action function calls the export method specifying uiGridExporterConstants.ALL instead of uiGridExporterConstants.VISIBLE for the column type.


问:
Difference between System.import() and import()?

In webpack 1 docs is statement that in webpack 2 will use System.import() for dynamic require:

Luckily, there is a JavaScript API “loader” specification being
  written to handle the dynamic use case: System.load (or
  System.import). This API will be the native equivalent to the above
  require variations.

And during that time all around the web was examples of using this System.import().

Before releasing webpack 2, authors decide to change System.import() to import():

add import() as Code Splitting construct. It should be used instead of
  System.import when possible. System.import will be deprecated in
  webpack 2 release (removed in webpack 3) as it's behavior is incorrect
  according to the spec.

This import() is based on tc39/proposal-dynamic-import specification, and you can read more why they made this change here.

Can someone explain difference between System.import() and import()?

Despite different name, usage looks the same:

import(modulePath)
  .then(module => module.default())
  .catch(/* ... */);

System.import(modulePath)
  .then(module => module.default())
  .catch(/* ... */);
```

But in weback 2 doc is: "System.import() behavior is incorrect according to the spec" - so it suggest that there is difference between System.import() and import().

答:
Here's what you're looking for:  tc39 Proposal for Import

An actual function

Drafts of the Loader ideas collection have at various times had actual functions (not just function-like syntactic forms) named System.import() or System.loader.import() or similar, which accomplish the same use cases.

The biggest problem here, as previously noted by the spec's editors, is how to interpret the specifier argument to these functions. Since these are just functions, which are the same across the entire Realm and do not vary per script or module, the function must interpret its argument the same no matter from where it is called. (Unless something truly weird like stack inspection is implemented.) So likely this runs into similar problems as the document base URL issue for the importModule function above, where relative module specifiers become a bug farm and mismatch any nearby import declarations.

Body:
In webpack 1 docs is statement that in webpack 2 will use System.import() for dynamic require:

Luckily, there is a JavaScript API “loader” specification being
  written to handle the dynamic use case: System.load (or
  System.import). This API will be the native equivalent to the above
  require variations.

And during that time all around the web was examples of using this System.import().

Before releasing webpack 2, authors decide to change System.import() to import():

add import() as Code Splitting construct. It should be used instead of
  System.import when possible. System.import will be deprecated in
  webpack 2 release (removed in webpack 3) as it's behavior is incorrect
  according to the spec.

This import() is based on tc39/proposal-dynamic-import specification, and you can read more why they made this change here.

Can someone explain difference between System.import() and import()?

Despite different name, usage looks the same:

import(modulePath)
  .then(module => module.default())
  .catch(/* ... */);

System.import(modulePath)
  .then(module => module.default())
  .catch(/* ... */);

But in weback 2 doc is: "System.import() behavior is incorrect according to the spec" - so it suggest that there is difference between System.import() and import().


问:
Sort AWS Instances by Tag:Name in PowerShell after Get-EC2Instance Cmdlet
I'm trying to sort the AWS Instances I pull with the Get-EC2Instance cmdlet but the issue I'm facing is that the property is a Tag and I'm not sure how to format it properly. I only know about assigning simple properties like "Sort-Object -Property Name".

I used the following to get the AWS Instances filtered by the Name tag.

```<code>$ids = Get-EC2Instance -Filter @( @{name='tag:Name'; values="*EXAMPLE*"}) | Select-Object -ExpandProperty instances | #insert sort here
</code>```

Trying to pipeline sort in the last part. I tried properties like tag, tag:Name, tag:Key=Name but all failed. When I used Get-EC2Image, I had no issues with Sort Name but can't figure it out for Get-EC2Instance.

There is a AWS CLI version and answer at Sort EC2 Instances by Tag Name but I wasn't able to apply it to PowerShell.

EDIT: Rewrote question and added more details since it got downvoted.

答:
You can pipe the output to Sort-Object cmdlet. I dont have access to a AWS instance to test this. But try variation of this command

```<code>$ids = Get-EC2Instance -Filter @( @{name='tag:Name'; values="*EXAMPLE*"}) | Select-Object -ExpandProperty instances | Sort-Object $_.Tag.Value
</code>```

There are two ways. You can get the object using the $_

OR
You can reference the property directly by using a method chain like:

```<code>(Get-EC2Instance).instances.tag.value
</code>```

Body:
I'm trying to sort the AWS Instances I pull with the Get-EC2Instance cmdlet but the issue I'm facing is that the property is a Tag and I'm not sure how to format it properly. I only know about assigning simple properties like "Sort-Object -Property Name".

I used the following to get the AWS Instances filtered by the Name tag.

$ids = Get-EC2Instance -Filter @( @{name='tag:Name'; values="*EXAMPLE*"}) | Select-Object -ExpandProperty instances | #insert sort here

Trying to pipeline sort in the last part. I tried properties like tag, tag:Name, tag:Key=Name but all failed. When I used Get-EC2Image, I had no issues with Sort Name but can't figure it out for Get-EC2Instance.

There is a AWS CLI version and answer at Sort EC2 Instances by Tag Name but I wasn't able to apply it to PowerShell.

EDIT: Rewrote question and added more details since it got downvoted.

Body:
You can pipe the output to Sort-Object cmdlet. I dont have access to a AWS instance to test this. But try variation of this command

$ids = Get-EC2Instance -Filter @( @{name='tag:Name'; values="*EXAMPLE*"}) | Select-Object -ExpandProperty instances | Sort-Object $_.Tag.Value

There are two ways. You can get the object using the $_

OR
You can reference the property directly by using a method chain like:

(Get-EC2Instance).instances.tag.value


问:
Passing null value by ajax to controller
I am trying to modify my save routine to pass a null value to id_cellcarrier on to my controller in codeigniter.  The following is what I have tried and it does not work.  There are a lot of pieces of this code that I am not posting here for brevity sake.  I hope enough is here that you can get the idea of where I am going.  Do I have to do something on the controller side to understand null?

Javascript:

```<code>     /**
     * Event: Save Add/Edit Customer Operation "Click"
     */
    $('#save-customer').click(function() {
        var customer = {
            if ($('#cell-carrier').val()== ''){
                JSON.stringify({id_cellcarrier: null}),
            }else{
                id_cellcarrier: $('#cell-carrier').val(),
            }
            wp_id: $('#wp-id').val(),
            notifications: $('#client-notifications').val(),
            first_name: $('#first-name').val(),
            last_name: $('#last-name').val(),
            email: $('#email').val(),
            phone_number: $('#phone-number').val(),
            address: $('#address').val(),
            city: $('#city').val(),
            zip_code: $('#zip-code').val(),
            notes: $('#notes').val()
        };

        if ($('#customer-id').val() != '') {
            customer.id = $('#customer-id').val();
        }

        if (!instance.validate(customer)) return;

        instance.save(customer);
    });

/**
 * Save a customer record to the database (via ajax post).
 *
 * @param {Object} customer Contains the customer data.
 */
CustomersHelper.prototype.save = function(customer) {
    var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_customer';
    var postData = {
        csrfToken: GlobalVariables.csrfToken,
        customer: JSON.stringify(customer)
    };

    $.post(postUrl, postData, function(response) {
        if (!GeneralFunctions.handleAjaxExceptions(response)) {
            return;
        }

        Backend.displayNotification(EALang['customer_saved']);
        this.resetForm();
        $('#filter-customers .key').val('');
        this.filter('', response.id, true);
    }.bind(this), 'json').fail(GeneralFunctions.ajaxFailureHandler);
};
</code>```

Controller:

```<code>/**
 * [AJAX] Save (insert or update) a customer record.
 *
 * @param array $_POST['customer'] JSON encoded array that contains the customer's data.
 */
public function ajax_save_customer() {
    try {
        $this->load->model('customers_model');
        $customer = json_decode($_POST['customer'], true);

        $REQUIRED_PRIV = (!isset($customer['id']))
                ? $this->privileges[PRIV_CUSTOMERS]['add']
                : $this->privileges[PRIV_CUSTOMERS]['edit'];
        if ($REQUIRED_PRIV == FALSE) {
            throw new Exception('You do not have the required privileges for this task.');
        }

        $customer_id = $this->customers_model->add($customer);
        echo json_encode(array(
            'status' => AJAX_SUCCESS,
            'id' => $customer_id
        ));
    } catch(Exception $exc) {
        echo json_encode(array(
            'exceptions' => array(exceptionToJavaScript($exc))
        ));
    }
}
</code>```

From the Model

```<code>public function add($customer) {
    // Validate the customer data before doing anything.
    $this->validate($customer);

    // :: CHECK IF CUSTOMER ALREADY EXIST (FROM EMAIL).
    if ($this->exists($customer) && !isset($customer['id'])) {
        // Find the customer id from the database.
        $customer['id'] = $this->find_record_id($customer);
    }

    // :: INSERT OR UPDATE CUSTOMER RECORD
    if (!isset($customer['id'])) {
        $customer['id'] = $this->_insert($customer);
    } else {
        $this->_update($customer);
    }

    return $customer['id'];
}

protected function _update($customer) {
    // Do not update empty string values.
    foreach ($customer as $key => $value) {
        if ($value === '')
            unset($customer[$key]);
    }

    $this->db->where('id', $customer['id']);
    if (!$this->db->update('ea_users', $customer)) {
        throw new Exception('Could not update customer to the database.');
    }

    return intval($customer['id']);
}
</code>```

答:
At first glance it seems this portion of your code must be a typo:

```<code>        if ($('#cell-carrier').val()== ''){
            JSON.stringify({id_cellcarrier: null}),
        }else{
            id_cellcarrier: $('#cell-carrier').val(),
        }
</code>```

,but if it is not a typo, it should be this:

```<code>id_cellcarrier: $('#cell-carrier').val() === ''? null: $('#cell-carrier').val(),
</code>```

Body:
I am trying to modify my save routine to pass a null value to id_cellcarrier on to my controller in codeigniter.  The following is what I have tried and it does not work.  There are a lot of pieces of this code that I am not posting here for brevity sake.  I hope enough is here that you can get the idea of where I am going.  Do I have to do something on the controller side to understand null?

Javascript:

     /**
     * Event: Save Add/Edit Customer Operation "Click"
     */
    $('#save-customer').click(function() {
        var customer = {
            if ($('#cell-carrier').val()== ''){
                JSON.stringify({id_cellcarrier: null}),
            }else{
                id_cellcarrier: $('#cell-carrier').val(),
            }
            wp_id: $('#wp-id').val(),
            notifications: $('#client-notifications').val(),
            first_name: $('#first-name').val(),
            last_name: $('#last-name').val(),
            email: $('#email').val(),
            phone_number: $('#phone-number').val(),
            address: $('#address').val(),
            city: $('#city').val(),
            zip_code: $('#zip-code').val(),
            notes: $('#notes').val()
        };

        if ($('#customer-id').val() != '') {
            customer.id = $('#customer-id').val();
        }

        if (!instance.validate(customer)) return;

        instance.save(customer);
    });

/**
 * Save a customer record to the database (via ajax post).
 *
 * @param {Object} customer Contains the customer data.
 */
CustomersHelper.prototype.save = function(customer) {
    var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_customer';
    var postData = {
        csrfToken: GlobalVariables.csrfToken,
        customer: JSON.stringify(customer)
    };

    $.post(postUrl, postData, function(response) {
        if (!GeneralFunctions.handleAjaxExceptions(response)) {
            return;
        }

        Backend.displayNotification(EALang['customer_saved']);
        this.resetForm();
        $('#filter-customers .key').val('');
        this.filter('', response.id, true);
    }.bind(this), 'json').fail(GeneralFunctions.ajaxFailureHandler);
};

Controller:

/**
 * [AJAX] Save (insert or update) a customer record.
 *
 * @param array $_POST['customer'] JSON encoded array that contains the customer's data.
 */
public function ajax_save_customer() {
    try {
        $this->load->model('customers_model');
        $customer = json_decode($_POST['customer'], true);

        $REQUIRED_PRIV = (!isset($customer['id']))
                ? $this->privileges[PRIV_CUSTOMERS]['add']
                : $this->privileges[PRIV_CUSTOMERS]['edit'];
        if ($REQUIRED_PRIV == FALSE) {
            throw new Exception('You do not have the required privileges for this task.');
        }

        $customer_id = $this->customers_model->add($customer);
        echo json_encode(array(
            'status' => AJAX_SUCCESS,
            'id' => $customer_id
        ));
    } catch(Exception $exc) {
        echo json_encode(array(
            'exceptions' => array(exceptionToJavaScript($exc))
        ));
    }
}

From the Model

public function add($customer) {
    // Validate the customer data before doing anything.
    $this->validate($customer);

    // :: CHECK IF CUSTOMER ALREADY EXIST (FROM EMAIL).
    if ($this->exists($customer) && !isset($customer['id'])) {
        // Find the customer id from the database.
        $customer['id'] = $this->find_record_id($customer);
    }

    // :: INSERT OR UPDATE CUSTOMER RECORD
    if (!isset($customer['id'])) {
        $customer['id'] = $this->_insert($customer);
    } else {
        $this->_update($customer);
    }

    return $customer['id'];
}

protected function _update($customer) {
    // Do not update empty string values.
    foreach ($customer as $key => $value) {
        if ($value === '')
            unset($customer[$key]);
    }

    $this->db->where('id', $customer['id']);
    if (!$this->db->update('ea_users', $customer)) {
        throw new Exception('Could not update customer to the database.');
    }

    return intval($customer['id']);
}

Body:
At first glance it seems this portion of your code must be a typo:

        if ($('#cell-carrier').val()== ''){
            JSON.stringify({id_cellcarrier: null}),
        }else{
            id_cellcarrier: $('#cell-carrier').val(),
        }

,but if it is not a typo, it should be this:

id_cellcarrier: $('#cell-carrier').val() === ''? null: $('#cell-carrier').val(),


问:
How to validate the entire form on field blur instead of just the blurred field
I have a form that uses jQuery validation, using unobtrusive validation to declare rules. Currently I'm using the default submit behaviour where there is no validation on blur until the form is submitted (validating every field in the form), after which subsequent blurs validate just the blurred field.

I'd like to change this behaviour so that after a submit, blurring a single field revalidates the entire form, so that the error summary remains on screen until every issue has been addressed. The behaviour before submit should remain the same.

I've tried the following onfocusout methods based on other SO answers, with no luck:

```<code>onfocusout: function(element, event) {
    $(element).valid();
}
</code>```

and

```<code>onfocusout: function(element, event) {
    this.element(element);
}
</code>```

答:
Both this.element(element) and $(element).valid() are for triggering validation on a single element.  In your case, since you're trying to apply this inside of the options of the .validate() or .setDefaults() methods, you cannot use .valid() as it could potentially trigger an infinite recursion.

That leaves .element().  However, as per the docs, you can only use this on a single field, not the entire form.

How to validate the entire form on field blur instead of just the blurred field

  I'd like to change this behaviour ... blurring a single field revalidates the entire form

The solution would be to write an external blur event handler attached to all relevant input elements and trigger the .valid() method attached to your form.  Edit the selectors in this generic example for whatever is applicable to your particular form.

```<code>$('#myform input[type="text"]').on('blur', function() {
    $('#myform').valid();  // <- trigger validation on entire form
});
</code>```

$('#myform input[type="text"]') selects all text inputs within #myform

$('#myform') selects theformbased onid="myform"`

Body:
I have a form that uses jQuery validation, using unobtrusive validation to declare rules. Currently I'm using the default submit behaviour where there is no validation on blur until the form is submitted (validating every field in the form), after which subsequent blurs validate just the blurred field.

I'd like to change this behaviour so that after a submit, blurring a single field revalidates the entire form, so that the error summary remains on screen until every issue has been addressed. The behaviour before submit should remain the same.

I've tried the following onfocusout methods based on other SO answers, with no luck:

onfocusout: function(element, event) {
    $(element).valid();
}

and

onfocusout: function(element, event) {
    this.element(element);
}

Body:
Both this.element(element) and $(element).valid() are for triggering validation on a single element.  In your case, since you're trying to apply this inside of the options of the .validate() or .setDefaults() methods, you cannot use .valid() as it could potentially trigger an infinite recursion.

That leaves .element().  However, as per the docs, you can only use this on a single field, not the entire form.

How to validate the entire form on field blur instead of just the blurred field

  I'd like to change this behaviour ... blurring a single field revalidates the entire form

The solution would be to write an external blur event handler attached to all relevant input elements and trigger the .valid() method attached to your form.  Edit the selectors in this generic example for whatever is applicable to your particular form.

$('#myform input[type="text"]').on('blur', function() {
    $('#myform').valid();  // <- trigger validation on entire form
});

$('#myform input[type="text"]') selects all text inputs within #myform

$('#myform') selects theformbased onid="myform"`


问:
regex for email validation Not Working with Subdomains?
I'm using the following for email validation:

```<code>var filter = /^([\w]+)(.[\w]+)*@([\w]+)(.[\w]{2,3}){1,2}$/; // For Email Validation

if (filter.test(emailInputVal))) {console.log('good')}
</code>```

For some reason the above does not work with emails that have a subdomain Any ideas why?

```<code>xxxx@xxx.xxx.com
</code>```

Thanks

答:
I am not sure if the above code will work any format, because there is an extra ) in the if condition, removing it works for the sub domain too:</p>

```<code>if (filter.test(emailInputVal)) {console.log('good')}
</code>```

ContentLicense: CC BY-SA 2.5

Body:
I'm using the following for email validation:

var filter = /^([\w]+)(.[\w]+)*@([\w]+)(.[\w]{2,3}){1,2}$/; // For Email Validation

if (filter.test(emailInputVal))) {console.log('good')}

For some reason the above does not work with emails that have a subdomain Any ideas why?

xxxx@xxx.xxx.com

Thanks

Body:
I am not sure if the above code will work any format, because there is an extra ) in the if condition, removing it works for the sub domain too:

if (filter.test(emailInputVal)) {console.log('good')}


问:
Close userform with escape button
I have 2 questions.

When I pressed esc button then close Userform1

When I input open in TextBox1 then Userform2 should show. Also clear TextBox1 in Userform1 automatically.

I have tried the below code:

```<code>Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If textbox1.value = "open" then
        userform2.show
        textbox1.value =""
    End If
End Sub
</code>```

答:
if you have a button the closes the form, just set the (Cancel) property to True and that will fire the cancel button on (Esc)..
Cheers.

Title: Close userform with escape button

Body:
I have 2 questions.

When I pressed esc button then close Userform1

When I input open in TextBox1 then Userform2 should show. Also clear TextBox1 in Userform1 automatically.

I have tried the below code:

Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If textbox1.value = "open" then
        userform2.show
        textbox1.value =""
    End If
End Sub


问:
Modify PHP script to read from CSV file
I have script which was reading two variable from CSV and those variable was at column 0 and column 5 and it was fine:

```<code>$file = fopen($qtyfile,"r");
output("reading file $qtyfile");

$i=0;
$imported = 0;
$failed = 0;
while(! feof($file))
{
  $i++;

  $line = (fgetcsv($file));

  if($i==1) continue;

  $cols = explode(';',$line[0]);

  $pcode = $cols[0];
  $stock = $cols[5];
</code>```

The CSV file has been orginzed in different way, and the variable now at column 16 & 19 i tried to modify the code to the following but it's not working :

```<code>$file = fopen($qtyfile,"r");
output("reading file $qtyfile");

$i=0;
$imported = 0;
$failed = 0;
while(! feof($file))
{
  $i++;

  $line = (fgetcsv($file));

  if($i==1) continue;

  $cols = explode(';',$line[0]);

  $pcode = $cols[16];
  $stock = $cols[19];
</code>```

can you please help to make the script ready from new column.

any help will be appreciated.

Link to full script and the csv:

答:
Here's an awesome little function which will parse any csv file into an associative array with column titles from row 1 as array keys.

```<code>function csvArray($file) {
    $csv = array_map('str_getcsv', file($file));
    array_walk($csv, function(&$a) use ($csv) {
      $a = array_combine($csv[0], $a);
    });
    array_shift($csv);
return $csv;
}
</code>```

Usage:

```<code>$output = csvArray($file);
foreach ($output as $o) {
echo $o['pcode'];
// whatever
}
</code>```

I have to deal with quite a lot of csv files and I use this all the time. Once the data is in an array it's much easier to deal with, and it doesn't matter if columns get moved around as long as the name stays the same it won't break your code.

Title: Modify PHP script to read from CSV file

Body:
I have script which was reading two variable from CSV and those variable was at column 0 and column 5 and it was fine:

$file = fopen($qtyfile,"r");
output("reading file $qtyfile");

$i=0;
$imported = 0;
$failed = 0;
while(! feof($file))
{
  $i++;

  $line = (fgetcsv($file));

  if($i==1) continue;

  $cols = explode(';',$line[0]);

  $pcode = $cols[0];
  $stock = $cols[5];

The CSV file has been orginzed in different way, and the variable now at column 16 & 19 i tried to modify the code to the following but it's not working :

$file = fopen($qtyfile,"r");
output("reading file $qtyfile");

$i=0;
$imported = 0;
$failed = 0;
while(! feof($file))
{
  $i++;

  $line = (fgetcsv($file));

  if($i==1) continue;

  $cols = explode(';',$line[0]);

  $pcode = $cols[16];
  $stock = $cols[19];

can you please help to make the script ready from new column.

any help will be appreciated.

Link to full script and the csv:

Body:
Here's an awesome little function which will parse any csv file into an associative array with column titles from row 1 as array keys.

function csvArray($file) {
    $csv = array_map('str_getcsv', file($file));
    array_walk($csv, function(&$a) use ($csv) {
      $a = array_combine($csv[0], $a);
    });
    array_shift($csv);
return $csv;
}

Usage:

$output = csvArray($file);
foreach ($output as $o) {
echo $o['pcode'];
// whatever
}

I have to deal with quite a lot of csv files and I use this all the time. Once the data is in an array it's much easier to deal with, and it doesn't matter if columns get moved around as long as the name stays the same it won't break your code.


问:
stored procedure can't figure out how to insert results into existing table
I have seen many posts on this but unfortunately I have not been able to use them to my benefit.  Like many other I would like to take the results of a stored procedure and as part of the procedure, every time it is run have the results go into an already existing table.  I cannot figure out how to do this and also how to match the columns up.

For example, the existing table has 4 columns.  2 of those columns are string and the stored procedure needs to hard code those values (a fixed name and definition for each procedure).  I have 4 stored procedures and each one needs to have the 'name' and 'description' defined in it.  This accounts for 2 of the 4 columns in the existing 'output' table.  The remaining two columns, one needs to show the datetime the procedure was run, and the other whether the check passed or failed.

my procedure works fine, up to outputting results.

the existing output table, lets call it 'dbo.procedure_results'.  it has 4 columns (checkname, description, asofdate, and pass)

there are 4 procedures, let's call them dbo.p1, dbo. p2....

each procedure when run currently outputs a file date and a total allocated storage integer (in TB).  I need to define 'checkname' and 'description' for each procedure.  'asofdate' can be the datetime the procuedure was run  Pass is an if statement, if the difference between returned values 1 and 3 are X, then Y, else z.

My current procedure:

```<code>ALTER PROCEDURE [dbo].[SP_DQ_SAN_Hosts_200TB_TotalCapacity]

AS
BEGIN

SELECT top 3 (CONVERT(date, day)) as Ref_Date, sum(TotalAllocated_TB)

  FROM [STORAGE_DW].[dbo].[SMART_Host_Dash]
  where TotalAllocated_TB >50
  GROUP BY cast(Day as date)
  order by CONVERT(date, day) desc

  insert into dbo.dq_check_summary
  exec dbo.sp_dq_san_hosts_200tb_totalcapacity

  END
</code>```

procedure currently outputs:

```<code>Ref_Date     Allocated_TB
2017-05-29   898.868404388428
2017-04-24   1056.01000595093
2017-03-27   779.119682312012
</code>```

答:
Your goal is suspicious - much like the idea that the condition "TotalAllocated_TB > 50" corresponds to the name you gave to your procedure. But you simply change the select statement to include the literals you want. E.g.,

```<code>select top 3 'what you want for checkname' as 'check name',
'what you want for description' as 'description',
cast([day] as date) as refdate,
...
order by refdate;
</code>```

Note that you can use an alias in the order by clause. Don't need to repeat the expression. Notice that you are summing and you filter the selected rows. Are you certain this logic is correct? The filter occurs logically before the summing? Be careful you understand that and that your sample data is sufficient to validate your logic. And do not write an insert statement that does not specify the columns to be inserted. Ever!

```<code>insert into dbo.dq_check_summary (col1, col2, col3, col4)
execute dbo.blah;
</code>```

Since your procedure is relatively trivial, you might consider using table-valued functions rather than a procedure. That would require a different approach but might be easier (in the long run) to use generally. In fact, you could create a view to do this - which might be a better choice for someone without much tsql experience. A view can generate the resultset you desire - you then decide if you want to insert the results into table when you query the view.

Body:
I have seen many posts on this but unfortunately I have not been able to use them to my benefit.  Like many other I would like to take the results of a stored procedure and as part of the procedure, every time it is run have the results go into an already existing table.  I cannot figure out how to do this and also how to match the columns up.

For example, the existing table has 4 columns.  2 of those columns are string and the stored procedure needs to hard code those values (a fixed name and definition for each procedure).  I have 4 stored procedures and each one needs to have the 'name' and 'description' defined in it.  This accounts for 2 of the 4 columns in the existing 'output' table.  The remaining two columns, one needs to show the datetime the procedure was run, and the other whether the check passed or failed.

my procedure works fine, up to outputting results.

the existing output table, lets call it 'dbo.procedure_results'.  it has 4 columns (checkname, description, asofdate, and pass)

there are 4 procedures, let's call them dbo.p1, dbo. p2....

each procedure when run currently outputs a file date and a total allocated storage integer (in TB).  I need to define 'checkname' and 'description' for each procedure.  'asofdate' can be the datetime the procuedure was run  Pass is an if statement, if the difference between returned values 1 and 3 are X, then Y, else z.

My current procedure:

ALTER PROCEDURE [dbo].[SP_DQ_SAN_Hosts_200TB_TotalCapacity]

AS
BEGIN

SELECT top 3 (CONVERT(date, day)) as Ref_Date, sum(TotalAllocated_TB)

  FROM [STORAGE_DW].[dbo].[SMART_Host_Dash]
  where TotalAllocated_TB >50
  GROUP BY cast(Day as date)
  order by CONVERT(date, day) desc

  insert into dbo.dq_check_summary
  exec dbo.sp_dq_san_hosts_200tb_totalcapacity

  END

procedure currently outputs:

Ref_Date     Allocated_TB
2017-05-29   898.868404388428
2017-04-24   1056.01000595093
2017-03-27   779.119682312012

Body:
Your goal is suspicious - much like the idea that the condition "TotalAllocated_TB > 50" corresponds to the name you gave to your procedure. But you simply change the select statement to include the literals you want. E.g.,

select top 3 'what you want for checkname' as 'check name',
'what you want for description' as 'description',
cast([day] as date) as refdate,
...
order by refdate;

Note that you can use an alias in the order by clause. Don't need to repeat the expression. Notice that you are summing and you filter the selected rows. Are you certain this logic is correct? The filter occurs logically before the summing? Be careful you understand that and that your sample data is sufficient to validate your logic. And do not write an insert statement that does not specify the columns to be inserted. Ever!

insert into dbo.dq_check_summary (col1, col2, col3, col4)
execute dbo.blah;

Since your procedure is relatively trivial, you might consider using table-valued functions rather than a procedure. That would require a different approach but might be easier (in the long run) to use generally. In fact, you could create a view to do this - which might be a better choice for someone without much tsql experience. A view can generate the resultset you desire - you then decide if you want to insert the results into table when you query the view.


问:
Apply custom promo rule using observer in Magento 2
I have created new table in Magento 2, for storing custom promorules, now I have created observer for event controller_action_predispatch_checkout_cart_couponPost and inside that observer I want to check if user has entered any custom rule then apply discount according to that rule.

Below is my code:

```<code><?php
namespace Webkul\Grid\Observer;

use Magento\Framework\Event\ObserverInterface;

class coupenAppliedAfter implements ObserverInterface
{
    /**
     * @var ObjectManagerInterface
     */
    protected $_objectManager;

    /**
     * @param \Magento\Framework\ObjectManagerInterface $objectManager
     */
    public function __construct(
        \Magento\Framework\ObjectManagerInterface $objectManager
    ) {
        $this->_objectManager = $objectManager;
    }

    /**
     * customer register event handler
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        // get enetered coupen code
        $controller = $observer->getControllerAction();
        $couponCode = $controller->getRequest()->getParam('coupon_code');

        $objectManager =   \Magento\Framework\App\ObjectManager::getInstance();
        $connection = $objectManager->get('Magento\Framework\App\ResourceConnection')->getConnection('\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION');
        // get list of coupon codes from that custom table
        $all_custom_codes = $connection->fetchAll("SELECT * FROM custom_promotion_rules");

        foreach($all_custom_codes as $code) {
            $db_coupen_code = $code['code'];
            // matching if user has entered any custom code
            if($couponCode == $db_coupen_code) {
                // if yes trying to apply custom discount
                $DiscountAmount = $code['discount_amount'];
                $result = $observer->getEvent()->getResult();
                $result->setAmount($DiscountAmount);
                $result->setBaseAmount($DiscountAmount);
            }
        }

    }
}
</code>```

but above code is not working and giving error Fatal error: Uncaught Error: Call to a member function setAmount() on null

Please suggest solution for this.

答:
$result is null. Are you trying to run this function manually? If you are, that could be your problem since $observer would be empty or null.

I would also move the initialization of $result above the foreach statement.

Body:
I have created new table in Magento 2, for storing custom promorules, now I have created observer for event controller_action_predispatch_checkout_cart_couponPost and inside that observer I want to check if user has entered any custom rule then apply discount according to that rule.

Below is my code:

<?php
namespace Webkul\Grid\Observer;

use Magento\Framework\Event\ObserverInterface;

class coupenAppliedAfter implements ObserverInterface
{
    /**
     * @var ObjectManagerInterface
     */
    protected $_objectManager;

    /**
     * @param \Magento\Framework\ObjectManagerInterface $objectManager
     */
    public function __construct(
        \Magento\Framework\ObjectManagerInterface $objectManager
    ) {
        $this->_objectManager = $objectManager;
    }

    /**
     * customer register event handler
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        // get enetered coupen code
        $controller = $observer->getControllerAction();
        $couponCode = $controller->getRequest()->getParam('coupon_code');

        $objectManager =   \Magento\Framework\App\ObjectManager::getInstance();
        $connection = $objectManager->get('Magento\Framework\App\ResourceConnection')->getConnection('\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION');
        // get list of coupon codes from that custom table
        $all_custom_codes = $connection->fetchAll("SELECT * FROM custom_promotion_rules");

        foreach($all_custom_codes as $code) {
            $db_coupen_code = $code['code'];
            // matching if user has entered any custom code
            if($couponCode == $db_coupen_code) {
                // if yes trying to apply custom discount
                $DiscountAmount = $code['discount_amount'];
                $result = $observer->getEvent()->getResult();
                $result->setAmount($DiscountAmount);
                $result->setBaseAmount($DiscountAmount);
            }
        }

    }
}

but above code is not working and giving error Fatal error: Uncaught Error: Call to a member function setAmount() on null

Please suggest solution for this.


问:
Predict Warning on newdata
I have reviewed the following similar questions and answers but believe my situation is different enough to warrant another question.

Getting Warning: " 'newdata' had 1 row but variables found have 32 rows" on predict.lm in R

R Warning: newdata' had 15 rows but variables found have 22 rows

Warning message 'newdata' had 1 row but variables found have 16 rows in R

warning when calculating predicted values

Trouble using predict with linear model in R

Predict.lm in R fails to recognize newdata

The last question listed has a great answer from Joran that gets to the heart of the naming convention between what was modeled and what is being scored.

The model I am fitting is a polynomial which generates some naming problems.

```<code>mdl <- lm(val ~ poly(grp,2), data = mRetCurv)
model.frame(mdl)
</code>```

Generates the following output:

```<code>     val       poly(grp, 2).1  poly(grp, 2).2
1   39.54227   -0.290170670    0.374017601
2   48.68225   -0.272368788    0.308602552
</code>```

Note the name of my predictor variables.  If I call

```<code>predict.lm(mdl, newdata = apl$grp)
</code>```

I get the standard warning as the variable grp != poly(grp, 2).1 or poly(grp, 2).2 as far as predict.lm is concerned.  I tried making a duplicate column of grp and renaming the two to match the model.frame but R doesn't like "poly(grp, 2).1" as a column name.  Nor is this a data efficient solution replicating a column when I apply it to many rows.

Any help is appreciated.

Thank you

答:
apl$grp is a vector, but predict requires the newdata argument to be a data frame.* This data frame must contain columns with the same names as the predictor variables used to fit the model (though it can contain other columns as well). So, the following code should work:

```<code>predict(mdl, newdata = apl)
</code>```

You can use predict rather than predict.lm. mdl is an object of class lm, which causes predict to "dispatch" the predict.lm method automatically.

* Strictly speaking, since this is an lm model, the predict "method" that gets dispatched is predict.lm and that method requires that newdata be a data frame. predict.glm also requires a data frame. However, there are some predict methods that can take other types of arguments. For example:

The randomForest package has a predict method for randomForest models that can take a data frame or matrix as the newdata argument.

The glmnet package has a predict method for glmnet models that requires a matrix, although the argument is called newx rather than newdata in that case.

Title: Predict Warning on newdata

Body:
I have reviewed the following similar questions and answers but believe my situation is different enough to warrant another question.

Getting Warning: " 'newdata' had 1 row but variables found have 32 rows" on predict.lm in R

R Warning: newdata' had 15 rows but variables found have 22 rows

Warning message 'newdata' had 1 row but variables found have 16 rows in R

warning when calculating predicted values

Trouble using predict with linear model in R

Predict.lm in R fails to recognize newdata

The last question listed has a great answer from Joran that gets to the heart of the naming convention between what was modeled and what is being scored.

The model I am fitting is a polynomial which generates some naming problems.

mdl <- lm(val ~ poly(grp,2), data = mRetCurv)
model.frame(mdl)

Generates the following output:

     val       poly(grp, 2).1  poly(grp, 2).2
1   39.54227   -0.290170670    0.374017601
2   48.68225   -0.272368788    0.308602552

Note the name of my predictor variables.  If I call

predict.lm(mdl, newdata = apl$grp)

I get the standard warning as the variable grp != poly(grp, 2).1 or poly(grp, 2).2 as far as predict.lm is concerned.  I tried making a duplicate column of grp and renaming the two to match the model.frame but R doesn't like "poly(grp, 2).1" as a column name.  Nor is this a data efficient solution replicating a column when I apply it to many rows.

Any help is appreciated.

Thank you

Body:
apl$grp is a vector, but predict requires the newdata argument to be a data frame.* This data frame must contain columns with the same names as the predictor variables used to fit the model (though it can contain other columns as well). So, the following code should work:

predict(mdl, newdata = apl)

You can use predict rather than predict.lm. mdl is an object of class lm, which causes predict to "dispatch" the predict.lm method automatically.

* Strictly speaking, since this is an lm model, the predict "method" that gets dispatched is predict.lm and that method requires that newdata be a data frame. predict.glm also requires a data frame. However, there are some predict methods that can take other types of arguments. For example:

The randomForest package has a predict method for randomForest models that can take a data frame or matrix as the newdata argument.

The glmnet package has a predict method for glmnet models that requires a matrix, although the argument is called newx rather than newdata in that case.


问:
Finding duplicates between columns using pandas
I have a dataset in pandas that consists of nba game statistics.

The data looks something like this:

```<code>Date|Team 1|Team 2|Team1 Stats|...|Team2 Stats|...
</code>```

Because of the way I scraped the data I have now two instances of each game, where the stats for each team are simply mirrored.

(All entries are equal just Team1 stats are in Team2 columns, and vice versa)

How do I find and remove the duplicate entries using pandas.

答:
To remove duplicates, you can keep only cases where Team1 is before Team2 lexicographically.

```<code>dfFiltered=df[df["Team1"]<df["Team2"]]
</code>```

Assuming that a team never plays itself, this will work

Body:
I have a dataset in pandas that consists of nba game statistics.

The data looks something like this:

Date|Team 1|Team 2|Team1 Stats|...|Team2 Stats|...

Because of the way I scraped the data I have now two instances of each game, where the stats for each team are simply mirrored.

(All entries are equal just Team1 stats are in Team2 columns, and vice versa)

How do I find and remove the duplicate entries using pandas.

Body:
To remove duplicates, you can keep only cases where Team1 is before Team2 lexicographically.

dfFiltered=df[df["Team1"]<df["Team2"]]

Assuming that a team never plays itself, this will work


问:
Remove item from list is while
Could someone help me understand why this code is returning the original items on the list instead of the items after user input name has been removed. </p>

```<code> lists = ['leo','bob','bob','Joe','Sam','Tracy','bob']
 counts = 0
 removeName = input(print("what name would you like to remove \n"))

 while counts != len(lists) and removeName not in lists :
     lists.remove(removeName)
     counts = counts + 1
print ("ok we removed all the", removeName, "from the list" )
print(lists)
</code>```

答:
When you use the input() function you do not need to do print. Python will find the input from anything you put in that parameter, so first remove that print so it becomes:

```<code>removeName = input("what name would you like to remove \n")
</code>```

Instead of:

```<code>removeName = input(print("what name would you like to remove \n"))
</code>```

Next, you need to remember if an item in a list is removed, it is one item shorter. This means that if you remove an item, you don't want to change "counts". The final code should be:

```<code>lists = ['leo','bob','bob','Joe','Sam','Tracy','bob']
counts = 0
removeName = input("what name would you like to remove \n")
while counts != len(lists):
    if lists[counts] != removeName:
        counts = counts + 1
    else:
        lists.remove(removeName)
print ("ok we removed all the", removeName, "from the list" )
print(lists)
</code>```

Title: Remove item from list is while

Body:
Could someone help me understand why this code is returning the original items on the list instead of the items after user input name has been removed.

 lists = ['leo','bob','bob','Joe','Sam','Tracy','bob']
 counts = 0
 removeName = input(print("what name would you like to remove \n"))

 while counts != len(lists) and removeName not in lists :
     lists.remove(removeName)
     counts = counts + 1
print ("ok we removed all the", removeName, "from the list" )
print(lists)

Body:
When you use the input() function you do not need to do print. Python will find the input from anything you put in that parameter, so first remove that print so it becomes:

removeName = input("what name would you like to remove \n")

Instead of:

removeName = input(print("what name would you like to remove \n"))

Next, you need to remember if an item in a list is removed, it is one item shorter. This means that if you remove an item, you don't want to change "counts". The final code should be:

lists = ['leo','bob','bob','Joe','Sam','Tracy','bob']
counts = 0
removeName = input("what name would you like to remove \n")
while counts != len(lists):
    if lists[counts] != removeName:
        counts = counts + 1
    else:
        lists.remove(removeName)
print ("ok we removed all the", removeName, "from the list" )
print(lists)


问:
Hide Empty Subreport in SSRS2008 R2
I have added a subreport to my report. The aim is simply to hide the subreport  if there is no data in it.

NoRows property was mentioned on this thread on Microsoft forums, but I guess it is for SSRS 2005 as the thread as quite old.

Isn't  there any obvious way to hide subreport if there is no data in it? I could hide the tablix in the subreport itself, but I also need to hide the row where subreport placed. To do this I need an indication whether the subreport has data or not in the main report.

Could you give a clue to sort this out?

答:
The more easy solution is:

Sanjay Kumar Rajarao responded on 16 Oct 2013 12:15 AM Access sub report properties - visibility - show based on expression. Enter this
  code:

=IIF(RowNumber(Nothing)>0,False,True)

https://community.dynamics.com/gp/f/32/t/114129

Title: Hide Empty Subreport in SSRS2008 R2


问:
Preserve leading zeros when saving numeric values in database
When executing dynamic MySQL prepared statements to INSERT or UPDATE, leading zeros (such as 0 in 0213123) disappear. How can I prevent this?

```<code>public function update($tablo, array $column, array $form)
{
    global $db;
    $sutun = implode(' = ?, ', array_keys($column)) . ' = ?';
    $where = implode(' = ?, ', array_keys($form)) . ' = ?';
    $stmt = $this->db->prepare("UPDATE $tablo SET $sutun  WHERE $where") or die($this->db->error);
    $form = array_merge($column, $form);
    call_user_func_array(array($stmt,'bind_param'), $this->params($form));
    return $stmt->execute() or die($this->db->error);
}

public function params($params, $types = '', $input = array())
{
    foreach ($params as $key => $val) {
        ${$key} = $val;
        $input[] =& ${$key};

        if (is_numeric($val) AND fmod($val, 1) === 0.00) {
            $types .= 'i';
        } elseif (is_float($val)) {
            $types .= 'd';
        } elseif (is_string($val) OR fmod($val, 1) !== 0.00) {
            $types .= 's';
        } else {
            $types .= 'b';
        }
    }
    array_unshift($input, $types);
    return $input;
}
</code>```

答:
Don't use is_numeric() to decide whether to use i as the type. It will be true for a string like "0213123". That will cause it to be parsed as a number, instead of keeping it as a string. Use is_int().

```<code>    if (is_int($val)) {
        $types .= 'i';
    } elseif (is_float($val)) {
        $types .= 'd';
    } elseif (is_string($val)) {
        $types .= 's';
    } else {
        $types .= 'b';
    }
</code>```

However, this means you won't be able to use numeric strings for integer or float columns. The caller needs to provide the appropriate types.

But that shouldn't be much of a problem. MySQL will automatically convert types when storing into the database, so the types specified in the prepare() call don't have to match the database types exactly.

ContentLicense: CC BY-SA 4.0

Body:
When executing dynamic MySQL prepared statements to INSERT or UPDATE, leading zeros (such as 0 in 0213123) disappear. How can I prevent this?

public function update($tablo, array $column, array $form)
{
    global $db;
    $sutun = implode(' = ?, ', array_keys($column)) . ' = ?';
    $where = implode(' = ?, ', array_keys($form)) . ' = ?';
    $stmt = $this->db->prepare("UPDATE $tablo SET $sutun  WHERE $where") or die($this->db->error);
    $form = array_merge($column, $form);
    call_user_func_array(array($stmt,'bind_param'), $this->params($form));
    return $stmt->execute() or die($this->db->error);
}

public function params($params, $types = '', $input = array())
{
    foreach ($params as $key => $val) {
        ${$key} = $val;
        $input[] =& ${$key};

        if (is_numeric($val) AND fmod($val, 1) === 0.00) {
            $types .= 'i';
        } elseif (is_float($val)) {
            $types .= 'd';
        } elseif (is_string($val) OR fmod($val, 1) !== 0.00) {
            $types .= 's';
        } else {
            $types .= 'b';
        }
    }
    array_unshift($input, $types);
    return $input;
}

Body:
Don't use is_numeric() to decide whether to use i as the type. It will be true for a string like "0213123". That will cause it to be parsed as a number, instead of keeping it as a string. Use is_int().

    if (is_int($val)) {
        $types .= 'i';
    } elseif (is_float($val)) {
        $types .= 'd';
    } elseif (is_string($val)) {
        $types .= 's';
    } else {
        $types .= 'b';
    }

However, this means you won't be able to use numeric strings for integer or float columns. The caller needs to provide the appropriate types.

But that shouldn't be much of a problem. MySQL will automatically convert types when storing into the database, so the types specified in the prepare() call don't have to match the database types exactly.


问:
C++ Is there something like RVO for passing temporary objects to functions?
With RVO it is possible to create an object from a returned object without move or copy. Is it possible to do something similar when passing an object to a function?

```<code>class SomeClass {
    int a;

public:
    SomeClass(int _a)                   {a = _a;        std::cout << "created\n";}
    SomeClass(const SomeClass& source)  {a = source.a;  std::cout << "copied\n";}
    SomeClass(SomeClass&& source)       {a = source.a;  std::cout << "moved\n";}
};

void create(SomeClass&& source) {
    SomeClass some_object( std::move( source));
    //p_some_object = new SomeClass( std::move( source));
    //new( p_some_object) SomeClass( std::move( source));
}

// ...

create(SomeClass(15));
</code>```

In this example the result is "created, moved". (GCC 5.4 / C++11 / -O3) It is the same with new or placement-new. There is no branch or anything so why can't it be created without move?

答:
RVO don't happen with reference nor it happen when creating another object from a function parameter.

If you change your reference parameter to a value parameter, RVO will be applied to it, but not the local object:

```<code>void create(SomeClass source) {
    SomeClass otherObject = std::move(source); // No RVO, object constructed from parameter
}

// ...

create(SomeClass{15}); // RVO applied to source parameter
</code>```

However, you can achieve it using lambda as function parameters:

```<code>template<typename C>
void create(C source) {
    SomeClass some_object{source()};
}

// ...

create([]{ return SomeClass{15}; });
</code>```

You can check the live output

Body:
With RVO it is possible to create an object from a returned object without move or copy. Is it possible to do something similar when passing an object to a function?

class SomeClass {
    int a;

public:
    SomeClass(int _a)                   {a = _a;        std::cout << "created\n";}
    SomeClass(const SomeClass& source)  {a = source.a;  std::cout << "copied\n";}
    SomeClass(SomeClass&& source)       {a = source.a;  std::cout << "moved\n";}
};

void create(SomeClass&& source) {
    SomeClass some_object( std::move( source));
    //p_some_object = new SomeClass( std::move( source));
    //new( p_some_object) SomeClass( std::move( source));
}

// ...

create(SomeClass(15));

In this example the result is "created, moved". (GCC 5.4 / C++11 / -O3) It is the same with new or placement-new. There is no branch or anything so why can't it be created without move?

Body:
RVO don't happen with reference nor it happen when creating another object from a function parameter.

If you change your reference parameter to a value parameter, RVO will be applied to it, but not the local object:

void create(SomeClass source) {
    SomeClass otherObject = std::move(source); // No RVO, object constructed from parameter
}

// ...

create(SomeClass{15}); // RVO applied to source parameter

However, you can achieve it using lambda as function parameters:

template<typename C>
void create(C source) {
    SomeClass some_object{source()};
}

// ...

create([]{ return SomeClass{15}; });

You can check the live output


问:
How many integers can be represented with floating point in IEEE-754 with single precision?
Can someone please help me understand how to calculate how many integers (a whole number, not a fractional number) can be represented with floating point in IEEE-754 with single precision?</p>

答:
I am lazy, so I coded up a brute-force search as follows (this assumes float maps to the IEEE-754 binary32 floating-point type):

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>

int main (void)
{
    volatile union {
        float f;
        uint32_t i;
    } num;
    uint32_t count = 0;
    num.i = 0;
    do {
        if ((num.f == floorf (num.f)) && !isinf (num.f)) count++;
        num.i++;
    } while (num.i);
    printf ("count = %u\n", count);
    return EXIT_SUCCESS;
}
```

<p>On a reasonably fast PC, after less than a minute, the program spits out:</p>

```count = 1778384896
```

If you want to treat -0 as redundant with +0, subtract one. It is advisable to compile this code with the maximum IEEE-754 compliance offered by one's C compiler. I used the Intel compiler version 13 on Windows and specified /fp:strict.

Body:
I am lazy, so I coded up a brute-force search as follows (this assumes float maps to the IEEE-754 binary32 floating-point type):

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>

int main (void)
{
    volatile union {
        float f;
        uint32_t i;
    } num;
    uint32_t count = 0;
    num.i = 0;
    do {
        if ((num.f == floorf (num.f)) && !isinf (num.f)) count++;
        num.i++;
    } while (num.i);
    printf ("count = %u\n", count);
    return EXIT_SUCCESS;
}

On a reasonably fast PC, after less than a minute, the program spits out:

count = 1778384896

If you want to treat -0 as redundant with +0, subtract one. It is advisable to compile this code with the maximum IEEE-754 compliance offered by one's C compiler. I used the Intel compiler version 13 on Windows and specified /fp:strict.


问:
iDP connecting to SP SAML / SSO
I have been assigned a task where I (the iDP) need to connect to a service provider.

So far I have the code:

```<code>public ActionResult SSO(string SAMLRequest)
{
    var model = new ApiSsoModel();

    try
    {
        if (SAMLRequest == null)
            throw new ArgumentNullException("The parameter \"SAMLRequest\" is null.");

        byte[] decoded2 = Convert.FromBase64String(SAMLRequest);
        string decoded3 = string.Empty;

        using (MemoryStream stream2 = new MemoryStream(decoded2))
        {
            using (MemoryStream stream3 = new MemoryStream())
            {
                using (StreamReader reader3 = new StreamReader(stream3))
                {
                    stream2.Position = 0L;
                    new DeflateStream(stream2, CompressionMode.Decompress).CopyTo(stream3);
                    stream3.Position = 0L;
                    decoded3 = reader3.ReadToEnd();
                    reader3.Close();
                }

                stream3.Close();
            }

            stream2.Close();
        }

        string assertion = System.IO.File.ReadAllText(Server.MapPath("~/assertion.xml"));

        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";

        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

        XmlDocument assertionDoc = new XmlDocument();
        assertionDoc.LoadXml(assertion);

        XmlDocument response = new XmlDocument();
        response.LoadXml(decoded3);

        SignedXml signedXml = new SignedXml(assertionDoc);

        Reference reference = new Reference();

        signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
        signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;

        reference.Uri = "#_79723ebe12aed3704c4d8de6ea16cf90c0d7451da0";

        reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
        reference.AddTransform(new XmlDsigExcC14NTransform());
        reference.DigestMethod = SignedXml.XmlDsigSHA1Url;
        reference.DigestValue = Encoding.ASCII.GetBytes("3jdMJaumbeC3UJ16d8VQJWjKQKU=");

        signedXml.AddReference(reference);

        signedXml.SigningKey = rsaKey;

        HMACSHA256 key = new HMACSHA256();

        signedXml.ComputeSignature(key);

        XmlElement xmlDigitalSignature = signedXml.GetXml();

        assertionDoc.GetElementsByTagName("ds:SignatureValue")[0].InnerText = xmlDigitalSignature.InnerText;

        model.Base64EncodedAssertion = Convert.ToBase64String(Encoding.ASCII.GetBytes(assertionDoc.InnerXml));

        model.Message += "Success";
    }
    catch (Exception ex)
    {
        model.Message = ex.Message;
    }

    return View(model);

}
</code>```

I am loading up an assertion file which was provided in an SSO 2.0 documentation file

```<code><?xml version="1.0" encoding="UTF-8"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="9f84acebb80533147969eac6a0aead9603c807b5b" Version="2.0" IssueInstant="2015-07-08T09:44:20Z" Destination="https://testdata.redpoints.co.uk/saml/consume" InResponseTo="_e4098d80-0783-0133-f409-7cd1c3f7b75b">
  <saml:Issuer>https://openidp.feide.no</saml:Issuer>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <ds:Reference URI="#_b9f84acebb80533147969eac6a0aead9603c807b5b">
        <ds:Transforms>
          <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
          <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <ds:DigestValue>3jdMJaumbeC3UJ16d8VQJWjKQKU=</ds:DigestValue>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>dewQ7U/QjQtaeUHHk/wgzyCLXi0B6mnmMNCUJgj+taxa/c+HsrKVx97iMbMaoFWRd9Ps9SjNr5P40yC2I5j3Dx9pheBAgKX6RRAl0C7CJM36XZAqWwA1CBlDCqx1H3vTeSeotuOovzKVhnpQj9AL38GmFYqHnNS1e5pCfugI72o=</ds:SignatureValue>
    <ds:KeyInfo>
      <ds:X509Data>
        <ds:X509Certificate>MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==</ds:X509Certificate>
      </ds:X509Data>
    </ds:KeyInfo>
  </ds:Signature>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
  </samlp:Status>
  <saml:Assertion xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="_79723ebe12aed3704c4d8de6ea16cf90c0d7451da0" Version="2.0" IssueInstant="2015-07-08T09:44:20Z">
    <saml:Issuer>https://openidp.feide.no</saml:Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
        <ds:Reference URI="#_79723ebe12aed3704c4d8de6ea16cf90c0d7451da0">
          <ds:Transforms>
            <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          </ds:Transforms>
          <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <ds:DigestValue>sDFB4zP6PHBacygh64DRtaeowZ8=</ds:DigestValue>
        </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>GY1M5iO5yht1JLOAOmFBUdZPtxKZeek5jG77w7Ct6A+H1qbUAbX7u8PmniGdOXkllxPWqB+L4Gtd39WbCEoWiQ9QvY/pVz2xe6xzI9gVsnJBP0alalyCZglnxNpQ2x+692OcpVXnbau4LJoFv2+0zktXPhQEI3CfAyixOpASu1w=</ds:SignatureValue>
      <ds:KeyInfo>
        <ds:X509Data>
          <ds:X509Certificate>MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </ds:Signature>
    <saml:Subject>
      <saml:NameID SPNameQualifier="https://testdata.redpoints.co.uk/saml/metadata" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_36355e0a362adec0f5753911aff3b14f9b21d9c2b8</saml:NameID>
      <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <saml:SubjectConfirmationData NotOnOrAfter="2017-11-08T09:49:20Z" Recipient="https://testdata.redpoints.co.uk/saml/consume" InResponseTo="_e4098d80-0783-0133-f409-7cd1c3f7b75b" />
      </saml:SubjectConfirmation>
    </saml:Subject>
    <saml:Conditions NotBefore="2015-07-08T09:43:50Z" NotOnOrAfter="2017-11-08T09:49:20Z">
      <saml:AudienceRestriction>
        <saml:Audience>https://testdata.redpoints.co.uk/saml/metadata</saml:Audience>
      </saml:AudienceRestriction>
    </saml:Conditions>
    <saml:AuthnStatement AuthnInstant="2015-07-08T09:15:58Z" SessionNotOnOrAfter="2017-11-08T17:44:20Z" SessionIndex="_066bce0e07565d6a61ae7e94fe95d8bcdd79a3cfd0">
      <saml:AuthnContext>
        <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
      </saml:AuthnContext>
    </saml:AuthnStatement>
    <saml:AttributeStatement>
      <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
        <saml:AttributeValue xsi:type="xs:string">102112</saml:AttributeValue>
      </saml:Attribute>
    </saml:AttributeStatement>
  </saml:Assertion>
</samlp:Response>
</code>```

I have tried many different methods to make this work, downloading multiple .net libraries which are meant to help with setting up SSO for the iDP but not had no luck.

答:
There are a number of SAML stacks around - SAML : SAML connectivity / toolkit .

I would definitely suggest that you don't roll your own. You'll fix this only to come across the next problem.

The problem with most of the stacks is that they are client side. You want server side.

Agree with componentspace suggestion - it can do both sides.

Or this one - currently in beta.

Or have a look at the OpenSAML source - it's Java but the principles are the same.

Title: iDP connecting to SP SAML / SSO

Body:
I have been assigned a task where I (the iDP) need to connect to a service provider.

So far I have the code:

public ActionResult SSO(string SAMLRequest)
{
    var model = new ApiSsoModel();

    try
    {
        if (SAMLRequest == null)
            throw new ArgumentNullException("The parameter \"SAMLRequest\" is null.");

        byte[] decoded2 = Convert.FromBase64String(SAMLRequest);
        string decoded3 = string.Empty;

        using (MemoryStream stream2 = new MemoryStream(decoded2))
        {
            using (MemoryStream stream3 = new MemoryStream())
            {
                using (StreamReader reader3 = new StreamReader(stream3))
                {
                    stream2.Position = 0L;
                    new DeflateStream(stream2, CompressionMode.Decompress).CopyTo(stream3);
                    stream3.Position = 0L;
                    decoded3 = reader3.ReadToEnd();
                    reader3.Close();
                }

                stream3.Close();
            }

            stream2.Close();
        }

        string assertion = System.IO.File.ReadAllText(Server.MapPath("~/assertion.xml"));

        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";

        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

        XmlDocument assertionDoc = new XmlDocument();
        assertionDoc.LoadXml(assertion);

        XmlDocument response = new XmlDocument();
        response.LoadXml(decoded3);

        SignedXml signedXml = new SignedXml(assertionDoc);

        Reference reference = new Reference();

        signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
        signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;

        reference.Uri = "#_79723ebe12aed3704c4d8de6ea16cf90c0d7451da0";

        reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
        reference.AddTransform(new XmlDsigExcC14NTransform());
        reference.DigestMethod = SignedXml.XmlDsigSHA1Url;
        reference.DigestValue = Encoding.ASCII.GetBytes("3jdMJaumbeC3UJ16d8VQJWjKQKU=");

        signedXml.AddReference(reference);

        signedXml.SigningKey = rsaKey;

        HMACSHA256 key = new HMACSHA256();

        signedXml.ComputeSignature(key);

        XmlElement xmlDigitalSignature = signedXml.GetXml();

        assertionDoc.GetElementsByTagName("ds:SignatureValue")[0].InnerText = xmlDigitalSignature.InnerText;

        model.Base64EncodedAssertion = Convert.ToBase64String(Encoding.ASCII.GetBytes(assertionDoc.InnerXml));

        model.Message += "Success";
    }
    catch (Exception ex)
    {
        model.Message = ex.Message;
    }

    return View(model);

}

I am loading up an assertion file which was provided in an SSO 2.0 documentation file

<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="9f84acebb80533147969eac6a0aead9603c807b5b" Version="2.0" IssueInstant="2015-07-08T09:44:20Z" Destination="https://testdata.redpoints.co.uk/saml/consume" InResponseTo="_e4098d80-0783-0133-f409-7cd1c3f7b75b">
  <saml:Issuer>https://openidp.feide.no</saml:Issuer>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <ds:Reference URI="#_b9f84acebb80533147969eac6a0aead9603c807b5b">
        <ds:Transforms>
          <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
          <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <ds:DigestValue>3jdMJaumbeC3UJ16d8VQJWjKQKU=</ds:DigestValue>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>dewQ7U/QjQtaeUHHk/wgzyCLXi0B6mnmMNCUJgj+taxa/c+HsrKVx97iMbMaoFWRd9Ps9SjNr5P40yC2I5j3Dx9pheBAgKX6RRAl0C7CJM36XZAqWwA1CBlDCqx1H3vTeSeotuOovzKVhnpQj9AL38GmFYqHnNS1e5pCfugI72o=</ds:SignatureValue>
    <ds:KeyInfo>
      <ds:X509Data>
        <ds:X509Certificate>MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==</ds:X509Certificate>
      </ds:X509Data>
    </ds:KeyInfo>
  </ds:Signature>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
  </samlp:Status>
  <saml:Assertion xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="_79723ebe12aed3704c4d8de6ea16cf90c0d7451da0" Version="2.0" IssueInstant="2015-07-08T09:44:20Z">
    <saml:Issuer>https://openidp.feide.no</saml:Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
        <ds:Reference URI="#_79723ebe12aed3704c4d8de6ea16cf90c0d7451da0">
          <ds:Transforms>
            <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          </ds:Transforms>
          <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <ds:DigestValue>sDFB4zP6PHBacygh64DRtaeowZ8=</ds:DigestValue>
        </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>GY1M5iO5yht1JLOAOmFBUdZPtxKZeek5jG77w7Ct6A+H1qbUAbX7u8PmniGdOXkllxPWqB+L4Gtd39WbCEoWiQ9QvY/pVz2xe6xzI9gVsnJBP0alalyCZglnxNpQ2x+692OcpVXnbau4LJoFv2+0zktXPhQEI3CfAyixOpASu1w=</ds:SignatureValue>
      <ds:KeyInfo>
        <ds:X509Data>
          <ds:X509Certificate>MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </ds:Signature>
    <saml:Subject>
      <saml:NameID SPNameQualifier="https://testdata.redpoints.co.uk/saml/metadata" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_36355e0a362adec0f5753911aff3b14f9b21d9c2b8</saml:NameID>
      <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <saml:SubjectConfirmationData NotOnOrAfter="2017-11-08T09:49:20Z" Recipient="https://testdata.redpoints.co.uk/saml/consume" InResponseTo="_e4098d80-0783-0133-f409-7cd1c3f7b75b" />
      </saml:SubjectConfirmation>
    </saml:Subject>
    <saml:Conditions NotBefore="2015-07-08T09:43:50Z" NotOnOrAfter="2017-11-08T09:49:20Z">
      <saml:AudienceRestriction>
        <saml:Audience>https://testdata.redpoints.co.uk/saml/metadata</saml:Audience>
      </saml:AudienceRestriction>
    </saml:Conditions>
    <saml:AuthnStatement AuthnInstant="2015-07-08T09:15:58Z" SessionNotOnOrAfter="2017-11-08T17:44:20Z" SessionIndex="_066bce0e07565d6a61ae7e94fe95d8bcdd79a3cfd0">
      <saml:AuthnContext>
        <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
      </saml:AuthnContext>
    </saml:AuthnStatement>
    <saml:AttributeStatement>
      <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
        <saml:AttributeValue xsi:type="xs:string">102112</saml:AttributeValue>
      </saml:Attribute>
    </saml:AttributeStatement>
  </saml:Assertion>
</samlp:Response>

I have tried many different methods to make this work, downloading multiple .net libraries which are meant to help with setting up SSO for the iDP but not had no luck.


问:
has no exported member 'Firebase'
I am trying to add Firebase in my ionic2 project from: https://ionicframework.com/docs/v2/native/firebase/

After installing, I got this error:

/myApp2/node_modules/ionic-native/dist/es5/index"' has no exported member 'Firebase'.

```<code>       L9:  import { Firebase } from 'ionic-native';
</code>```

Anyone has solution for this?

答: I think it's firebase versioning problem . If you use 4.5.0 version try to downgrade your version , I downgraded from firebase 4.5.0 to 4.3.0 . so resolved.</p>

Title: has no exported member 'Firebase'

Body:
I am trying to add Firebase in my ionic2 project from: https://ionicframework.com/docs/v2/native/firebase/

After installing, I got this error:

/myApp2/node_modules/ionic-native/dist/es5/index"' has no exported member 'Firebase'.

       L9:  import { Firebase } from 'ionic-native';

Anyone has solution for this?