问:
d3-Draw grid line at a location based on the y coordinates?
I am kind a new to d3.js and want to draw a horizontal grid line based on y coordinate value fiddle , i've tried with if condition at y1 and y2 locations but the lines are overlapping at the top of graph.

Any help is much appreciated.

答:
Your if statement makes little sense to me:

```<code>if (y(d) === thresholdValues.minValue) {
    return y(d);
}
</code>```

This means that only when the value in the screen is exactly thresholdValues.minValue (which is 40 in your code) the line will be painted.

Solution: drop the if statement. Actually, I kept the if just to avoid the first gridline, over the x axis:

```<code>if (d != 0) {
    return y(d);
}
</code>```

Here is your code with that change:

var margin = {
  top: 30,
  right: 20,
  bottom: 30,
  left: 50
};

var thresholdValues = {
  minValue: 40,
  maxValue: 85
};
var width = 600 - margin.left - margin.right;
var height = 270 - margin.top - margin.bottom;

var parseDate = d3.time.format("%d-%b-%y").parse;

var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

var xAxis = d3.svg.axis().scale(x)
  .orient("bottom").ticks(5);

var yAxis = d3.svg.axis().scale(y)
  .orient("left").ticks(5);

var valueline = d3.svg.line()
  .x(function(d) {
    return x(d.date);
  })
  .y(function(d) {
    return y(d.close);
  });

var svg = d3.select("body")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Get the data
var data = [{
  date: "1-May-12",
  close: "58.13"
}, {
  date: "30-Apr-12",
  close: "53.98"
}, {
  date: "27-Apr-12",
  close: "67.00"
}, {
  date: "26-Apr-12",
  close: "89.70"
}, {
  date: "25-Apr-12",
  close: "99.00"
}];

data.forEach(function(d) {
  d.date = parseDate(d.date);
  d.close = +d.close;
});

// Scale the range of the data
x.domain(d3.extent(data, function(d) {
  return d.date;
}));
y.domain([0, 100]);

svg.append("path") // Add the valueline path.
  .attr("d", valueline(data));

svg.append("g") // Add the X Axis
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);

svg.append("g") // Add the Y Axis
  .attr("class", "y axis")
  .call(yAxis);

svg.selectAll("line.horizontalGrid").data(y.ticks(4)).enter()
  .append("line")
  .attr({
    "class": "horizontalGrid",
    "x1": margin.right,
    "x2": width - margin.right,
    "y1": function(d) {
      if (d != 0) {
        return y(d);
      }
    },
    "y2": function(d) {
      if (d != 0) {
        return y(d);
      }
    },
    "fill": "none",
    "shape-rendering": "crispEdges",
    "stroke": "grey",
    "stroke-width": "2px",
    "opacity": 0.4,
    "stroke-dasharray": 8
  });```
<pre class="snippet-code-css lang-css prettyprint-override"><code>body {
  font: 12px Arial;
}

path {
  stroke: steelblue;
  stroke-width: 2;
  fill: none;
}

.axis path,
.axis line {
  fill: none;
  stroke: grey;
  stroke-width: 1;
  shape-rendering: crispEdges;
}</code>```

```
</div>
</div>
</p>

<p>EDIT: If you want to draw only two lines, at the thresholds, you have to pass their values to <code>data</code>, not the scale ticks:</p>

```.data(Object.values(thresholdValues))
```

<p>Here is the demo:</p>

<p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
<div class="snippet-code snippet-currently-hidden">
<pre class="snippet-code-js lang-js prettyprint-override"><code>var margin = {
  top: 30,
  right: 20,
  bottom: 30,
  left: 50
};

var thresholdValues = {
  minValue: 40,
  maxValue: 85
};
var width = 600 - margin.left - margin.right;
var height = 270 - margin.top - margin.bottom;

var parseDate = d3.time.format("%d-%b-%y").parse;

var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

var xAxis = d3.svg.axis().scale(x)
  .orient("bottom").ticks(5);

var yAxis = d3.svg.axis().scale(y)
  .orient("left").ticks(5);

var valueline = d3.svg.line()
  .x(function(d) {
    return x(d.date);
  })
  .y(function(d) {
    return y(d.close);
  });

var svg = d3.select("body")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Get the data
var data = [{
  date: "1-May-12",
  close: "58.13"
}, {
  date: "30-Apr-12",
  close: "53.98"
}, {
  date: "27-Apr-12",
  close: "67.00"
}, {
  date: "26-Apr-12",
  close: "89.70"
}, {
  date: "25-Apr-12",
  close: "99.00"
}];

data.forEach(function(d) {
  d.date = parseDate(d.date);
  d.close = +d.close;
});

// Scale the range of the data
x.domain(d3.extent(data, function(d) {
  return d.date;
}));
y.domain([0, 100]);

svg.append("path") // Add the valueline path.
  .attr("d", valueline(data));

svg.append("g") // Add the X Axis
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);

svg.append("g") // Add the Y Axis
  .attr("class", "y axis")
  .call(yAxis);

svg.selectAll("line.horizontalGrid").data(Object.values(thresholdValues)).enter()
  .append("line")
  .attr({
    "class": "horizontalGrid",
    "x1": margin.right,
    "x2": width - margin.right,
    "y1": function(d) {
      if (d != 0) {
        return y(d);
      }
    },
    "y2": function(d) {
      if (d != 0) {
        return y(d);
      }
    },
    "fill": "none",
    "shape-rendering": "crispEdges",
    "stroke": "grey",
    "stroke-width": "2px",
    "opacity": 0.4,
    "stroke-dasharray": 8
  });</code>```

path {
  stroke: steelblue;
  stroke-width: 2;
  fill: none;
}

.axis path,
.axis line {
  fill: none;
  stroke: grey;
  stroke-width: 1;
  shape-rendering: crispEdges;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://d3js.org/d3.v3.js"></script></code>```

Body:
Your if statement makes little sense to me:

if (y(d) === thresholdValues.minValue) {
    return y(d);
}

This means that only when the value in the screen is exactly thresholdValues.minValue (which is 40 in your code) the line will be painted.

Solution: drop the if statement. Actually, I kept the if just to avoid the first gridline, over the x axis:

if (d != 0) {
    return y(d);
}

Here is your code with that change:

var margin = {
  top: 30,
  right: 20,
  bottom: 30,
  left: 50
};

var thresholdValues = {
  minValue: 40,
  maxValue: 85
};
var width = 600 - margin.left - margin.right;
var height = 270 - margin.top - margin.bottom;

var parseDate = d3.time.format("%d-%b-%y").parse;

var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

var xAxis = d3.svg.axis().scale(x)
  .orient("bottom").ticks(5);

var yAxis = d3.svg.axis().scale(y)
  .orient("left").ticks(5);

var valueline = d3.svg.line()
  .x(function(d) {
    return x(d.date);
  })
  .y(function(d) {
    return y(d.close);
  });

var svg = d3.select("body")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Get the data
var data = [{
  date: "1-May-12",
  close: "58.13"
}, {
  date: "30-Apr-12",
  close: "53.98"
}, {
  date: "27-Apr-12",
  close: "67.00"
}, {
  date: "26-Apr-12",
  close: "89.70"
}, {
  date: "25-Apr-12",
  close: "99.00"
}];

data.forEach(function(d) {
  d.date = parseDate(d.date);
  d.close = +d.close;
});

// Scale the range of the data
x.domain(d3.extent(data, function(d) {
  return d.date;
}));
y.domain([0, 100]);

svg.append("path") // Add the valueline path.
  .attr("d", valueline(data));

svg.append("g") // Add the X Axis
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);

svg.append("g") // Add the Y Axis
  .attr("class", "y axis")
  .call(yAxis);

svg.selectAll("line.horizontalGrid").data(y.ticks(4)).enter()
  .append("line")
  .attr({
    "class": "horizontalGrid",
    "x1": margin.right,
    "x2": width - margin.right,
    "y1": function(d) {
      if (d != 0) {
        return y(d);
      }
    },
    "y2": function(d) {
      if (d != 0) {
        return y(d);
      }
    },
    "fill": "none",
    "shape-rendering": "crispEdges",
    "stroke": "grey",
    "stroke-width": "2px",
    "opacity": 0.4,
    "stroke-dasharray": 8
  });

body {
  font: 12px Arial;
}

path {
  stroke: steelblue;
  stroke-width: 2;
  fill: none;
}

.axis path,
.axis line {
  fill: none;
  stroke: grey;
  stroke-width: 1;
  shape-rendering: crispEdges;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

EDIT: If you want to draw only two lines, at the thresholds, you have to pass their values to data, not the scale ticks:

.data(Object.values(thresholdValues))

Here is the demo:

var margin = {
  top: 30,
  right: 20,
  bottom: 30,
  left: 50
};

var thresholdValues = {
  minValue: 40,
  maxValue: 85
};
var width = 600 - margin.left - margin.right;
var height = 270 - margin.top - margin.bottom;

var parseDate = d3.time.format("%d-%b-%y").parse;

var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

var xAxis = d3.svg.axis().scale(x)
  .orient("bottom").ticks(5);

var yAxis = d3.svg.axis().scale(y)
  .orient("left").ticks(5);

var valueline = d3.svg.line()
  .x(function(d) {
    return x(d.date);
  })
  .y(function(d) {
    return y(d.close);
  });

var svg = d3.select("body")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Get the data
var data = [{
  date: "1-May-12",
  close: "58.13"
}, {
  date: "30-Apr-12",
  close: "53.98"
}, {
  date: "27-Apr-12",
  close: "67.00"
}, {
  date: "26-Apr-12",
  close: "89.70"
}, {
  date: "25-Apr-12",
  close: "99.00"
}];

data.forEach(function(d) {
  d.date = parseDate(d.date);
  d.close = +d.close;
});

// Scale the range of the data
x.domain(d3.extent(data, function(d) {
  return d.date;
}));
y.domain([0, 100]);

svg.append("path") // Add the valueline path.
  .attr("d", valueline(data));

svg.append("g") // Add the X Axis
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);

svg.append("g") // Add the Y Axis
  .attr("class", "y axis")
  .call(yAxis);

svg.selectAll("line.horizontalGrid").data(Object.values(thresholdValues)).enter()
  .append("line")
  .attr({
    "class": "horizontalGrid",
    "x1": margin.right,
    "x2": width - margin.right,
    "y1": function(d) {
      if (d != 0) {
        return y(d);
      }
    },
    "y2": function(d) {
      if (d != 0) {
        return y(d);
      }
    },
    "fill": "none",
    "shape-rendering": "crispEdges",
    "stroke": "grey",
    "stroke-width": "2px",
    "opacity": 0.4,
    "stroke-dasharray": 8
  });

path {
  stroke: steelblue;
  stroke-width: 2;
  fill: none;
}

.axis path,
.axis line {
  fill: none;
  stroke: grey;
  stroke-width: 1;
  shape-rendering: crispEdges;
}

<script src="https://d3js.org/d3.v3.js"></script>


来源: stackexchange

问:
Calculating values in dynamically created DOM
I have created an html table that is dynamically created in the DOM.  It has 4 columns and two of the columns will have tetboxes that a user can enter values into and then will be subtracted as a value in the last column.  'Delta' = 'State Before' - 'State After'.  I am able to get the value when it is entered but not sure how to get the value of the other field to do the computation.

HTML

```<code>    <table id="deptState" border="1">
    <tr>
        <th>Department</th>
        <th>State Before</th>
        <th>State After</th>
        <th>Delta</th>
    </tr>
</table>
</code>```

JAVASCRIPT

```<code>   var deptArray = ["Human Resources", "Accounting and Finance", "IT", "Marketing", "Purchasing Department"];
var state = ["stateBefore", "stateAfter", "Delta"];

for(var x=0; x<deptArray.length; x++) {
    var html = "<tr>";
        html +="<td>"+deptArray[x]+"</td>";
        for(var y=0; y<state.length; y++) {
            if (state[y] === "stateBefore")
            {
                html += "<td><input type='text' class='.nrm-text' id='"+deptArray[x]+state[0]+"'></td>";
            }else if (state[y] === "stateAfter") {
                html += "<td><input type='text' class='.nrm-text' id='"+deptArray[x]+state[1]+"'></td>";
            }else if (state[y] === "Delta") {
                html += "<td><input type='text' id='"+deptArray[x]+state[2]+"'></td>";
            }
        }
      html += "</tr>";
      $("#deptState").append(html);
  }

  var allTextBoxes = document.querySelector("#deptState");
  console.dir(allTextBoxes);
  allTextBoxes.addEventListener("change", function( e ){
    if (e.target.tagName === 'INPUT'){
              alert("Value: "+document.getElementById(e.target.id).value);
            console.log("Save data to SharePoint list");
    }
  })
</code>```

It's easier to show.  Here's the jsfiddle:

In one of the rows, enter 9 in 'State Before' and 5 in 'State After'.  'Delta' should then have 4

http://jsfiddle.net/isogunro/pq4uref9/

答:
I've made this a little more jqueried. I've used jQueries on to hande events for dynamically added elements.

Then we grab all the inputs from the row that has had a  change and perform our operation

var deptArray = ["Human Resources", "Accounting and Finance", "IT", "Marketing", "Purchasing Department"];
var state = ["stateBefore", "stateAfter", "Delta"];

for(var x=0; x<deptArray.length; x++) {
 var html = "
";
  html +=""+deptArray[x]+"	";
  for(var y=0; y<state.length; y++) {
   if (state[y] === "stateBefore")
   {
      //alert(state[0]);
    html += "<input type='text' class='.nrm-text' id='"+deptArray[x]+state[0]+"'>	";
   }else if (state[y] === "stateAfter") {
      //alert(state[1]);
    html += "<input type='text' class='.nrm-text' id='"+deptArray[x]+state[1]+"'>	";
   }else if (state[y] === "Delta") {
      //alert(state[2]);
    html += "<input type='text' id='"+deptArray[x]+state[2]+"'>	";
   }
  }
      html += "
";
      //document.getElementById("#deptState").appendChild(html);
      $("#deptState").append(html);
  }

  $("#deptState").on("change", "input[type='text']", function(){

      var inputs = $(this).closest("tr").find("input[type='text']");
      var fldBefore = inputs[0];
      var fldAfter = inputs[1];
      var fldDelta = inputs[2];

      if($(fldBefore).val().length > 0 && $(fldAfter).val().length > 0)
      {
       alert("Value: "+$(this).val());
        console.log("Save data to SharePoint list");
        $(fldDelta).val($(fldBefore).val() - $(fldAfter).val()) ;
      }

  });```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="deptState" border="1">
  <tr>
   <th>Department</th>
   <th>State Before</th>
   <th>State After</th>
   <th>Delta</th>
  </tr>
 </table></code>```

:

ContentLicense: CC BY-SA 3.0

Body:
I have created an html table that is dynamically created in the DOM.  It has 4 columns and two of the columns will have tetboxes that a user can enter values into and then will be subtracted as a value in the last column.  'Delta' = 'State Before' - 'State After'.  I am able to get the value when it is entered but not sure how to get the value of the other field to do the computation.

HTML

        Department
        State Before
        State After
        Delta

JAVASCRIPT

   var deptArray = ["Human Resources", "Accounting and Finance", "IT", "Marketing", "Purchasing Department"];
var state = ["stateBefore", "stateAfter", "Delta"];

for(var x=0; x<deptArray.length; x++) {
    var html = "
";
        html +=""+deptArray[x]+"	";
        for(var y=0; y<state.length; y++) {
            if (state[y] === "stateBefore")
            {
                html += "<input type='text' class='.nrm-text' id='"+deptArray[x]+state[0]+"'>	";
            }else if (state[y] === "stateAfter") {
                html += "<input type='text' class='.nrm-text' id='"+deptArray[x]+state[1]+"'>	";
            }else if (state[y] === "Delta") {
                html += "<input type='text' id='"+deptArray[x]+state[2]+"'>	";
            }
        }
      html += "
";
      $("#deptState").append(html);
  }

  var allTextBoxes = document.querySelector("#deptState");
  console.dir(allTextBoxes);
  allTextBoxes.addEventListener("change", function( e ){
    if (e.target.tagName === 'INPUT'){
              alert("Value: "+document.getElementById(e.target.id).value);
            console.log("Save data to SharePoint list");
    }
  })

It's easier to show.  Here's the jsfiddle:

In one of the rows, enter 9 in 'State Before' and 5 in 'State After'.  'Delta' should then have 4

http://jsfiddle.net/isogunro/pq4uref9/

Body:
I've made this a little more jqueried. I've used jQueries on to hande events for dynamically added elements.

Then we grab all the inputs from the row that has had a  change and perform our operation

var deptArray = ["Human Resources", "Accounting and Finance", "IT", "Marketing", "Purchasing Department"];
var state = ["stateBefore", "stateAfter", "Delta"];

for(var x=0; x<deptArray.length; x++) {
 var html = "<tr>";
  html +="<td>"+deptArray[x]+"</td>";
  for(var y=0; y<state.length; y++) {
   if (state[y] === "stateBefore")
   {
      //alert(state[0]);
    html += "<td><input type='text' class='.nrm-text' id='"+deptArray[x]+state[0]+"'></td>";
   }else if (state[y] === "stateAfter") {
      //alert(state[1]);
    html += "<td><input type='text' class='.nrm-text' id='"+deptArray[x]+state[1]+"'></td>";
   }else if (state[y] === "Delta") {
      //alert(state[2]);
    html += "<td><input type='text' id='"+deptArray[x]+state[2]+"'></td>";
   }
  }
      html += "</tr>";
      //document.getElementById("#deptState").appendChild(html);
      $("#deptState").append(html);
  }

  $("#deptState").on("change", "input[type='text']", function(){

      var inputs = $(this).closest("tr").find("input[type='text']");
      var fldBefore = inputs[0];
      var fldAfter = inputs[1];
      var fldDelta = inputs[2];

      if($(fldBefore).val().length > 0 && $(fldAfter).val().length > 0)
      {
       alert("Value: "+$(this).val());
        console.log("Save data to SharePoint list");
        $(fldDelta).val($(fldBefore).val() - $(fldAfter).val()) ;
      }

  });

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="deptState" border="1">
  <tr>
   <th>Department</th>
   <th>State Before</th>
   <th>State After</th>
   <th>Delta</th>
  </tr>
 </table>

:


问:
The ViewBag content isn't being visualized
I'm brand new to ASP.NET MVC web development.
And I'm trying to build a website that basically has access to a database which can be filled by user.

Alright, all good, that part works fine. What I'm struggling with, is that whenever the user insert data into the database, I wanna show a message saying that his insertion has been done succesfully, or something like that. I wanna show that down in the form panel.

This is the code that I got so far:

This is the method being called when the user clicks the submit button:

```<code>[HttpPost]
public ActionResult Create(PersonModels person)
{
    try
    {
        // TODO: Add insert logic here
        //Adding to database and holding the response in the viewbag.
        string strInsertion = ConnectionModels.insertPerson(person);
        ViewBag.InsertionResult = strInsertion;

        return RedirectToAction("Index");
    }
    catch
    {
        return View("Index");
    }
}
</code>```

And this is my Index action:

```<code>public ActionResult Index()
{
    return View();
}
</code>```

And finally, this is what I'm trying to d in my index.cshtml:

```<code><div>
     <label>
         @ViewBag.InsertionResult
     </label>
</div>
</code>```

I'm not gonna post it completely 'cause it'd be quite extensive. But that's beneath the div of the form panel.

I hope you can give me a hand.

Thanks in advance! :)

答:
You can not pass a ViewBag value while redirecting to another action. If you are in the same controller you can use TempData to pass values in a session otherwise you can pass the message as a parameter to RedirectionResult like below:

```<code>return RedirectToAction("Index", new {message="Your Message"});
</code>```

and then get it back like this:

```<code>public ActionResult Index(string message)
{
    ViewBag.ViewBag.InsertionResult = message;
    return View();
}
</code>```

This is a general way how to pass messages but I would recommend something like this:

Use a BaseController where all controllers inherits from this one:

Here you can make a custom logic how to handle global message like error messages, notification messages, info messages etc.

For that you need to create a model like below:

I am keeping it simple here:

```<code>public class GlobalMessage
{
   public string Message { get;set;}
   public AlertType AlertType {get;set;}
}
public enum AlertType
{
   Success, Info, Error, Danger//etc
}
</code>```

In BaseController you would have something like this:

```<code>public abstract class BaseController : Controller
{
    protected GlobalMessage GlobalMessage;
    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Result is ViewResult)
        {
            if (GlobalMessage!= null)
            {
                filterContext.Controller.ViewBag.GlobalMessage = GlobalMessage;
            }
            else
            {
                GlobalErrorViewModel globalErrorModelView = TempData["GlobalMessage"] as GlobalMessage;

                if (globalErrorModelView != null)
                {
                    filterContext.Controller.ViewBag.GlobalErrorViewModel = globalErrorModelView;
                }
            }
        }
        base.OnActionExecuted(filterContext);
    }

}
</code>```

In this moment you just have to register new GlobalMessage in Tempdata like below:

```<code>public PeopleController : BaseController
{
    [HttpPost]
    public ActionResult Create(PersonModels person)
    {
        try
        {
            // TODO: Add insert logic here
            //Adding to database and holding the response in the viewbag.
            string strInsertion = ConnectionModels.insertPerson(person);
            TempData["GlobalMessage"] = new GlobalMessage{ AlertType = AlertType.Info, Message = "You have successfully added a new person" }

            return RedirectToAction("Index");
        }
        catch
        {
            return View("Index");
        }
    }
}
</code>```

Then here is the final step how to show data in the view:

I personally use popup or modal window to do this: For example in bootstrapp you would write something like this:

```<code>GlobalMessage globalMessage = ViewBag.GlobalMessage as GlobalMessage;
   @if (globalMessage != null)
    {
        <!-- Modal -->
        <div class="modal fade" id="globalMessage" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content panel-@globalMessage .AlertType.ToString().ToLower() remove-border-radius">
                    <div class="modal-header panel-heading">
                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                    </div>
                    <div class="modal-body">
                        <p class="h-text-primary">@Html.Raw(globalMessage .Message)</p>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-@globalMessage .AlertType.ToString().ToLower() remove-border-radius" data-dismiss="modal">Close</button>
                    </div>
                </div><!-- /.modal-content -->
            </div><!-- /.modal-dialog -->
        </div><!-- /.modal -->
    }
</code>```

Trigger the modal if there is a message:

```<code>@if (globalMessage != null)
{
    <script type="text/javascript">
        $(document).ready(function () {
            $('#globalMessage').modal('show');
        });
    </script>
}
</code>```

This example was to show how you can make a system to show different messages. In short terms whatever you want!

Body:
I'm brand new to ASP.NET MVC web development.
And I'm trying to build a website that basically has access to a database which can be filled by user.

Alright, all good, that part works fine. What I'm struggling with, is that whenever the user insert data into the database, I wanna show a message saying that his insertion has been done succesfully, or something like that. I wanna show that down in the form panel.

This is the code that I got so far:

This is the method being called when the user clicks the submit button:

[HttpPost]
public ActionResult Create(PersonModels person)
{
    try
    {
        // TODO: Add insert logic here
        //Adding to database and holding the response in the viewbag.
        string strInsertion = ConnectionModels.insertPerson(person);
        ViewBag.InsertionResult = strInsertion;

        return RedirectToAction("Index");
    }
    catch
    {
        return View("Index");
    }
}

And this is my Index action:

public ActionResult Index()
{
    return View();
}

And finally, this is what I'm trying to d in my index.cshtml:

         @ViewBag.InsertionResult

I'm not gonna post it completely 'cause it'd be quite extensive. But that's beneath the div of the form panel.

I hope you can give me a hand.

Thanks in advance! :)

Body:
You can not pass a ViewBag value while redirecting to another action. If you are in the same controller you can use TempData to pass values in a session otherwise you can pass the message as a parameter to RedirectionResult like below:

return RedirectToAction("Index", new {message="Your Message"});

and then get it back like this:

public ActionResult Index(string message)
{
    ViewBag.ViewBag.InsertionResult = message;
    return View();
}

This is a general way how to pass messages but I would recommend something like this:

Use a BaseController where all controllers inherits from this one:

Here you can make a custom logic how to handle global message like error messages, notification messages, info messages etc.

For that you need to create a model like below:

I am keeping it simple here:

public class GlobalMessage
{
   public string Message { get;set;}
   public AlertType AlertType {get;set;}
}
public enum AlertType
{
   Success, Info, Error, Danger//etc
}

In BaseController you would have something like this:

public abstract class BaseController : Controller
{
    protected GlobalMessage GlobalMessage;
    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Result is ViewResult)
        {
            if (GlobalMessage!= null)
            {
                filterContext.Controller.ViewBag.GlobalMessage = GlobalMessage;
            }
            else
            {
                GlobalErrorViewModel globalErrorModelView = TempData["GlobalMessage"] as GlobalMessage;

                if (globalErrorModelView != null)
                {
                    filterContext.Controller.ViewBag.GlobalErrorViewModel = globalErrorModelView;
                }
            }
        }
        base.OnActionExecuted(filterContext);
    }

}

In this moment you just have to register new GlobalMessage in Tempdata like below:

public PeopleController : BaseController
{
    [HttpPost]
    public ActionResult Create(PersonModels person)
    {
        try
        {
            // TODO: Add insert logic here
            //Adding to database and holding the response in the viewbag.
            string strInsertion = ConnectionModels.insertPerson(person);
            TempData["GlobalMessage"] = new GlobalMessage{ AlertType = AlertType.Info, Message = "You have successfully added a new person" }

            return RedirectToAction("Index");
        }
        catch
        {
            return View("Index");
        }
    }
}

Then here is the final step how to show data in the view:

I personally use popup or modal window to do this: For example in bootstrapp you would write something like this:

GlobalMessage globalMessage = ViewBag.GlobalMessage as GlobalMessage;
   @if (globalMessage != null)
    {
        <!-- Modal -->
        <div class="modal fade" id="globalMessage" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content panel-@globalMessage .AlertType.ToString().ToLower() remove-border-radius">
                    <div class="modal-header panel-heading">
                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    </div>
                    <div class="modal-body">
                        <p class="h-text-primary">@Html.Raw(globalMessage .Message)</p>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-@globalMessage .AlertType.ToString().ToLower() remove-border-radius" data-dismiss="modal">Close</button>
                    </div>
                </div><!-- /.modal-content -->
            </div><!-- /.modal-dialog -->
        </div><!-- /.modal -->
    }

Trigger the modal if there is a message:

@if (globalMessage != null)
{
    <script type="text/javascript">
        $(document).ready(function () {
            $('#globalMessage').modal('show');
        });
    </script>
}

This example was to show how you can make a system to show different messages. In short terms whatever you want!


问:
Local Background image css won't override stylesheet css
I have a universal stylesheet which references a universal background image. I now want to make different background images for several of the pages on my website.

I have tried adding local style to the class tag, with !important to override the stylesheet. While this stops the original background image from displaying, it won't display the new image.

Current code is:

```<code><div class="main_wrapper" style="float: left; background:
     url("/images/live_body_bg.jpg") no-repeat fixed top right !important;
     width:100%;">
</code>```

Stylesheet code is as follows:

```<code>.main_wrapper {
    padding: 0px 0 30px 0;
    margin: 0px;
    float: left;
    width: 100%;
    background: url(images/body_bg.jpg) no-repeat fixed top right #000;
    background-size: cover;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    border-bottom: 3px #fec500 solid;
}
</code>```

Please advise...

答: Solved it. The file path was wrong. When I put the entire URL in single quotes, the background image displays correctly.</p>

Body:
I have a universal stylesheet which references a universal background image. I now want to make different background images for several of the pages on my website.

I have tried adding local style to the class tag, with !important to override the stylesheet. While this stops the original background image from displaying, it won't display the new image.

Current code is:

Stylesheet code is as follows:

.main_wrapper {
    padding: 0px 0 30px 0;
    margin: 0px;
    float: left;
    width: 100%;
    background: url(images/body_bg.jpg) no-repeat fixed top right #000;
    background-size: cover;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    border-bottom: 3px #fec500 solid;
}

Please advise...


问:
Interface builder agent crashes when accessing @IBInspectable UIImage
I'm implementing a custom view by subclassing UIView and using @IBInspectable for some of my variables. Two of them are UIImage. If I try to access one of them in the code, the interface builder crashes with the following message:

```<code>file:///PathToMyProject/MyProject/Pod/Classes/UI/View/MyView.xib: error: IB Designables: Failed to update auto layout status: The agent crashed
</code>```

and

```<code>file:///PathToMyProject/MyProject/Pod/Classes/UI/View/MyView.xib: error: IB Designables: Failed to render instance of MyView: The agent crashed
</code>```

Everything runs fine on simulator and device.
Here's how you can reproduce it, assumed image_one.png is in the assets:

```<code>import UIKit

@IBDesignable
class MyView: UIView {

    @IBInspectable
    var anImage: UIImage = UIImage(named: "image_one")!

}
</code>```

In fact the interface builder agent crashes at initializing this variable. If you write var anImage: UIImage! = UIImage(named: "image_one"), then the agent crashes when accessing this variable (as stated above).

Any ideas?

答:
You do not have to set you image in inspector in IB heres a solution purely in code.</p>

```<code>let bundle = Bundle(for: self.classForCoder)
image = UIImage(named: "your_image.png", in: bundle, compatibleWith: self.traitCollection)!
self.setImage(image, for: .normal)
</code>```

Body:
I'm implementing a custom view by subclassing UIView and using @IBInspectable for some of my variables. Two of them are UIImage. If I try to access one of them in the code, the interface builder crashes with the following message:

file:///PathToMyProject/MyProject/Pod/Classes/UI/View/MyView.xib: error: IB Designables: Failed to update auto layout status: The agent crashed

and

file:///PathToMyProject/MyProject/Pod/Classes/UI/View/MyView.xib: error: IB Designables: Failed to render instance of MyView: The agent crashed

Everything runs fine on simulator and device.
Here's how you can reproduce it, assumed image_one.png is in the assets:

import UIKit

@IBDesignable
class MyView: UIView {

    @IBInspectable
    var anImage: UIImage = UIImage(named: "image_one")!

}

In fact the interface builder agent crashes at initializing this variable. If you write var anImage: UIImage! = UIImage(named: "image_one"), then the agent crashes when accessing this variable (as stated above).

Any ideas?

Body:
You do not have to set you image in inspector in IB heres a solution purely in code.

let bundle = Bundle(for: self.classForCoder)
image = UIImage(named: "your_image.png", in: bundle, compatibleWith: self.traitCollection)!
self.setImage(image, for: .normal)


问:
Connecting to Azure B2C, with .NET Core from behind a NGINX Proxy
Almost have this working. Almost.

My set up is that I have an Azure B2C Tenant set up, and some modified example code that I've changed to reflect the Tenant information. This all works fine locally, with a localhost uri.

My remote set up is a Ubuntu 16.01 server, with a Nginx 1.10.0 webserver acting as a reverse proxy to a .NET Core 1.0.4 and all with a LetsEncrypt SSL cert.

The proxy serves .NET projects fine, however when I hit the sign in it takes me over to the B2C login with an incorrect redirect_url.

I'd expect the value to reflect what is in the settings file, "https.sub.host.suffix/signin-oidc" instead I'm getting "http.sub.host.suffix,sub.host.suffix/signin-oidc"

Any ideas or suggestions appreciated!

答:
If NGINX is offloading SSL/TLS and then calling the .NET Core app, check as most probably is doing it through open HTTP (port 80).

You either need to ensure HTTPS all-the-way, or signal an HTTPS scheme to get triggered if HTTP endpoint was called.

As the .NET Core App gets a request through an HTTP endpoint, every URI created by it will keep that same scheme. So, you'll need to force https:// at link building time.

Hope it helps!


问:
Escaped apostrophe causing issue in JavaScript
Okay ... I always thought that escaping apostrophe would allow you to use it in a JavaScript string and not break your quotes.

However, I have the following JavaScript call:

```<code><a class="btn btn-danger" onclick="deleteAgenda(2056, 'PJ's Happy 4th of July New Agenda', '7/20/2017 5:15:00 PM');">
</code>```

And I am getting an error:

```<code>Uncaught SyntaxError: missing ) after argument list
</code>```

It fails in both Chrome and IE.

If I make the same call without the escaped apostrophe, it works.

If I cannot use an escaped apostrophe in a JavaScript String, how am I supposed to escape it?

Thanks,

Philip

答:
That's because you are attempting to use HTML character entities from within JavaScript. All you need to do to escape an apostrophe in JavaScript is to preface the apostrophe with a backslash ('PJ\'s ... '):

function deleteAgenda(one, two) {
  console.log(two);
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code>Hi there</code>```

Hope this helps! :)

Body:
Okay ... I always thought that escaping apostrophe would allow you to use it in a JavaScript string and not break your quotes.

However, I have the following JavaScript call:

And I am getting an error:

Uncaught SyntaxError: missing ) after argument list

It fails in both Chrome and IE.

If I make the same call without the escaped apostrophe, it works.

If I cannot use an escaped apostrophe in a JavaScript String, how am I supposed to escape it?

Thanks,

Philip

Body:
That's because you are attempting to use HTML character entities from within JavaScript. All you need to do to escape an apostrophe in JavaScript is to preface the apostrophe with a backslash ('PJ\'s ... '):

function deleteAgenda(one, two) {
  console.log(two);
}

<a class="btn btn-danger" onclick="deleteAgenda(2056, 'PJ\'s Happy 4th of July New Agenda', '7/20/2017 5:15:00 PM');">Hi there</a>

Hope this helps! :)


问:
Choosing a simple web application framework
I'm evaluating web application frameworks for a hobby project I'm starting, and am beginning to go crazy trying to decide among the vast number of frameworks available to choose. The framework language isn't helping me filter out frameworks as I have varying levels of experience with Java, Python, Ruby and C#, and don't mind frameworks in any of these languages. </p>

<p>I'm looking for help in narrowing the choice down to a few that I can then investigate in more detail. </p>

答:
I am doing my personal project in http://www.asp.net/mvc/.  The first time I did it I just slapped out a working site by fussing around with the code.  Now I am re-writing it to try to "code better" and learn new design principles.

I also have used codeigniter at work, and while I like it, it is php and you didn't mention that as a choice of languages.

OwnerDisplayName: nagul

ContentLicense: CC BY-SA 2.5

Body:
I'm evaluating web application frameworks for a hobby project I'm starting, and am beginning to go crazy trying to decide among the vast number of frameworks available to choose. The framework language isn't helping me filter out frameworks as I have varying levels of experience with Java, Python, Ruby and C#, and don't mind frameworks in any of these languages.

I'm looking for help in narrowing the choice down to a few that I can then investigate in more detail.

LastEditorDisplayName: Marko Dumic

OwnerDisplayName: MrChrister


问:
Selenium Server on startup
I'm using Selenium RC in a Ubuntu system.
I want to automate the tests, and I need to start Selenium-server.jar on startup of the machine.

I created seleniumServer.conf in /ect/init/ with:

```<code>start on startup
start on runlevel 3

respawn

exec xvfb-run java -jar /home/condde/selenium-server-1.0.3/selenium-server.jar -port 4444
</code>```

When I reboot the machine, it works fine, the process is running.
But when I execute a test, the result is:

```<code>PHPUnit_Framework_Exception: Could not connect to the Selenium RC server.
</code>```

Any ideas?
Thanks!

答:
I would start the selenium server process with -log parameter to get info from the process first and all and see if it actually get any kind of connections, errors etc..

A few ideas to troubleshoot:

Do you get any response if you enter http://localhost:4444
It should render a 403 error by the Jetty engine.

If this does not work I would try with your actual IP:4444, that might indicate problem with localhost variable, proxy settings etc..

Could the firewall settings be blocking the the 4444 port? Maybe the Selenium Server process is not allowed to start the browser.

Title: Selenium Server on startup

Body:
I'm using Selenium RC in a Ubuntu system.
I want to automate the tests, and I need to start Selenium-server.jar on startup of the machine.

I created seleniumServer.conf in /ect/init/ with:

start on startup
start on runlevel 3

respawn

exec xvfb-run java -jar /home/condde/selenium-server-1.0.3/selenium-server.jar -port 4444

When I reboot the machine, it works fine, the process is running.
But when I execute a test, the result is:

PHPUnit_Framework_Exception: Could not connect to the Selenium RC server.

Any ideas?
Thanks!


问:
Browsers randomly not requesting resources
My website includes code to log JavaScript errors back to the web server (Apache) as they occur, using a combination of $exceptionHandler in AngularJS for exceptions within my Angular code and also via window.onerror for stuff happening outside of Angular.

A number of errors logged of late indicate that clients are seemingly randomly failing to request one resource or another. So far, I cannot find any correlation between the specific resource not being fetched, or the browser or client device exhibiting the issue.

As an example, one of the JavaScript resources on my pages is called 'utility.js'. This includes some global functions and other common stuff for the website. An iPhone user (on iOS 10.3.2) today loaded a page and fetched all of the resources for the page except utility.js (I reviewed the Apache access log for the session and could see all other resources identified in the page being requested - and in the correct order - but not utility.js, and there was nothing in the error log around the same timeframe). A second later, a JavaScript error was logged to our server from the phone on account of a global function defined in utility.js not being defined.

Another (more commonly occurring) example is that of AngularJS generating a $compile:tpload error when attempting to access a HTML template resource. I get several of these each day. The template in question varies between instances of the error, but in the cases I have reviewed, again there is no evidence in the Apache log of a request for the template resource. Other template resources for the same page were loaded successfully. Of note in this case, I sometimes see the same client log the error regarding the same resource several times over a few minutes, suggesting the user is reloading the page and getting the same issue, so there does seem to be something 'stuck' or blocking in the browser, but I just cannot imagine what.

I'm reasonably confident that these resources are not cached in users' browsers already as in the cases I have looked at, other resources on the page were requested that would not have been if the page had already been loaded.

I really don't know where to go with this issue at present. To my knowledge, there is no way for me to get any visibility into the browser's network traffic for my page.

Any suggestions on how to further diagnose this issue?

答:
Looks like this is the cause of (at least a significant portion of) the $compile:tpload errors, if not possibly also some others:

https://github.com/angular/angular.js/issues/14219

Essentially, it seems Chrome and Firefox incorrectly(?) generate error events for XHR requests that are aborted due to unloading the page (ie. reloading it or navigating away). In my case, clients must have requests in-flight for the angular templates which are getting aborted when they reload or navigate away... perhaps they are on a slow network connection and having issues loading the page and so attempt a reload.

I reproduced the error by inserting a PHP sleep() request into one of the templates to prevent Apache from responding immediately. If I load the page, then reload it or navigate away, the $compile:tpload error is logged accordingly. I also found that Apache only logs requests in the access log file once they are responded to, which goes at least some way to explaining the behaviour I observed there (though not fully!)

It does not explain the incidents of the error occurring for IE11 though - I could not reproduce it with that. Nor does it explain why the vast majority of incidents are on Android devices.

In summary, some progress, but I don't have all the answers yet. At least this might be semi-useful to somebody out there!


问:
Spring controller that will accept (XML/BASE64) and return XML with jackson support
I'm creating a spring based web application(Spring,jackson and hibernate) that will accept XML/BASE64 input as request message and after processing the response will be XML message. Application will have different controllers to accept BASE64/XML message.

Client ---(BASE64/XML)-->Server---->XML--->Client

I need to know how to implement two different controller and can read the XML from the client. Since it is a web application, which will get input message based on client request. Request XML messages contains optional tags which may/may not be present. I need to know is it good to create the application as a spring web service(Please guide me with proper sample links) or like a normal web application that will read data from the input stream.

My client programs which will open a url connection, open stream writes the data and will wait for the server to write response back to stream.

```<code>@Controller
@RequestMapping("/employee")
public class EmployeeController {

   //Function to take request and response as XML
    @RequestMapping(value = "/allEmployyes", method = RequestMethod.POST)
    public @ResponseBody EmployeesStatus readAllEmployeeDetails() {
    }

   //Function to take request as BASE64 and reply as XML
    @RequestMapping(value = "/empProfile", method = RequestMethod.POST)
    public @ResponseBody ProfileStatus updateEmployeeProfilePic() {
    }
 }
</code>```

Please help me to create a better solution for the requirement(Expecting practical solutions from experienced Spring professionals).

答:
Here is one possible solution using @RestController that meets your requirements.  Note: I'm using Project Lombok annotation processing to reduce boilerplate getters and setters, but you're by no means obligated to use it.

```<code>import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import java.io.IOException;
import java.util.Base64;
import java.util.stream.Collectors;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.MediaType.APPLICATION_XML_VALUE;
import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

@RestController
@RequestMapping("/employee")
@Validated
@Slf4j
public class EmployeeController {
    /**
     * Reads employee details and returns status.
     *
     * @param employeeDetails the employee details
     * @return a status object
     */
    @RequestMapping(value = "/allEmployees", method = POST, consumes = APPLICATION_XML_VALUE, produces = APPLICATION_XML_VALUE)
    public EmployeeStatus readAllEmployeeDetails(@Valid @RequestBody EmployeeDetails employeeDetails) {
        log.info("Got employee details: {}", employeeDetails);
        return new EmployeeStatus("Employee details updated");
    }

    /**
     * Reads a Base64 encoded picture and returns status.
     *
     * @param picture the Base64 encoded picture
     * @return a status object
     */
    @RequestMapping(value = "/empProfile", method = POST, consumes = TEXT_PLAIN_VALUE, produces = APPLICATION_XML_VALUE)
    public ProfileStatus updateEmployeeProfilePic(
            @Valid
            // Regular expression for validating Base64 encoded text.
            @Pattern(message = "Not Base64 encoded", regexp = "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$")
            @RequestBody String picture) {
        byte[] bytes = Base64.getDecoder().decode(picture);
        log.info("Received {} bytes", bytes.length);
        // Process bytes...
        return new ProfileStatus("Picture updated");
    }

    /**
     * Handles validation constraint violations by returning a 400 Bad Request, and outputs the violation messages.
     *
     * @param e        the {@link ConstraintViolationException}
     * @param response the {@link HttpServletResponse}
     * @throws IOException on unexpected I/O error
     */
    @ExceptionHandler
    public void handleConstraintViolation(ConstraintViolationException e, HttpServletResponse response) throws IOException {
        String message = e.getConstraintViolations().stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining(", "));
        response.sendError(BAD_REQUEST.value(), message);
    }

    @Data
    public static class EmployeeDetails {
        @NotEmpty
        private String firstName;
        @NotEmpty
        private String lastName;
    }

    @Data
    @AllArgsConstructor
    public static class EmployeeStatus {
        private String status;
    }

    @Data
    @AllArgsConstructor
    public static class ProfileStatus {
        private String status;
    }
}
</code>```

Here is the Maven POM I'm using for the controller.  The key is to include jackson-dataformat-xml as a dependency for XML serialization support:

```<code><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.anoop</groupId>
    <artifactId>stack-44893803-rest</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.8.8</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.16</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
</code>```

This allows you to POST XML, and to serialize/deserialize it using Jackson:

```<code>curl -X POST \
  http://localhost:8080/employee/allEmployees \
  -H 'content-type: application/xml' \
  -d '<employee>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
</employee>'
</code>```

Body:
I'm creating a spring based web application(Spring,jackson and hibernate) that will accept XML/BASE64 input as request message and after processing the response will be XML message. Application will have different controllers to accept BASE64/XML message.

Client ---(BASE64/XML)-->Server---->XML--->Client

I need to know how to implement two different controller and can read the XML from the client. Since it is a web application, which will get input message based on client request. Request XML messages contains optional tags which may/may not be present. I need to know is it good to create the application as a spring web service(Please guide me with proper sample links) or like a normal web application that will read data from the input stream.

My client programs which will open a url connection, open stream writes the data and will wait for the server to write response back to stream.

@Controller
@RequestMapping("/employee")
public class EmployeeController {

   //Function to take request and response as XML
    @RequestMapping(value = "/allEmployyes", method = RequestMethod.POST)
    public @ResponseBody EmployeesStatus readAllEmployeeDetails() {
    }

   //Function to take request as BASE64 and reply as XML
    @RequestMapping(value = "/empProfile", method = RequestMethod.POST)
    public @ResponseBody ProfileStatus updateEmployeeProfilePic() {
    }
 }

Please help me to create a better solution for the requirement(Expecting practical solutions from experienced Spring professionals).

Body:
Here is one possible solution using @RestController that meets your requirements.  Note: I'm using Project Lombok annotation processing to reduce boilerplate getters and setters, but you're by no means obligated to use it.

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import java.io.IOException;
import java.util.Base64;
import java.util.stream.Collectors;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.MediaType.APPLICATION_XML_VALUE;
import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

@RestController
@RequestMapping("/employee")
@Validated
@Slf4j
public class EmployeeController {
    /**
     * Reads employee details and returns status.
     *
     * @param employeeDetails the employee details
     * @return a status object
     */
    @RequestMapping(value = "/allEmployees", method = POST, consumes = APPLICATION_XML_VALUE, produces = APPLICATION_XML_VALUE)
    public EmployeeStatus readAllEmployeeDetails(@Valid @RequestBody EmployeeDetails employeeDetails) {
        log.info("Got employee details: {}", employeeDetails);
        return new EmployeeStatus("Employee details updated");
    }

    /**
     * Reads a Base64 encoded picture and returns status.
     *
     * @param picture the Base64 encoded picture
     * @return a status object
     */
    @RequestMapping(value = "/empProfile", method = POST, consumes = TEXT_PLAIN_VALUE, produces = APPLICATION_XML_VALUE)
    public ProfileStatus updateEmployeeProfilePic(
            @Valid
            // Regular expression for validating Base64 encoded text.
            @Pattern(message = "Not Base64 encoded", regexp = "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$")
            @RequestBody String picture) {
        byte[] bytes = Base64.getDecoder().decode(picture);
        log.info("Received {} bytes", bytes.length);
        // Process bytes...
        return new ProfileStatus("Picture updated");
    }

    /**
     * Handles validation constraint violations by returning a 400 Bad Request, and outputs the violation messages.
     *
     * @param e        the {@link ConstraintViolationException}
     * @param response the {@link HttpServletResponse}
     * @throws IOException on unexpected I/O error
     */
    @ExceptionHandler
    public void handleConstraintViolation(ConstraintViolationException e, HttpServletResponse response) throws IOException {
        String message = e.getConstraintViolations().stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining(", "));
        response.sendError(BAD_REQUEST.value(), message);
    }

    @Data
    public static class EmployeeDetails {
        @NotEmpty
        private String firstName;
        @NotEmpty
        private String lastName;
    }

    @Data
    @AllArgsConstructor
    public static class EmployeeStatus {
        private String status;
    }

    @Data
    @AllArgsConstructor
    public static class ProfileStatus {
        private String status;
    }
}

Here is the Maven POM I'm using for the controller.  The key is to include jackson-dataformat-xml as a dependency for XML serialization support:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.anoop</groupId>
    <artifactId>stack-44893803-rest</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.8.8</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.16</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

This allows you to POST XML, and to serialize/deserialize it using Jackson:

curl -X POST \
  http://localhost:8080/employee/allEmployees \
  -H 'content-type: application/xml' \
  -d '<employee>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
</employee>'


问:
Swift addSubview() on views created using init(repeating:count) doesn't work
Here is a ViewController that creates 4 subviews using init(repeating:count).

In viewDidLoad I add them as subviews and set their frames. When I run the application only the last view is added.

```<code>class ViewController: UIViewController {

    let subviews = [UIView].init(repeating: UIView(), count: 4)

    override func viewDidLoad() {
        super.viewDidLoad()
        for i in 0..<subviews.count {
            self.view.addSubview(subviews[i])
            self.subviews[i].backgroundColor = UIColor.red
            self.subviews[i].frame = CGRect(x: CGFloat(i) * 35, y: 30, width: 30, height: 30)
        }
    }

}
</code>```

Here's the same code except instead of using init(repeating:count) I use

a closure. This works fine-- all subviews are added.

```<code>class ViewController: UIViewController {

    let subviews: [UIView] = {
        var subviews = [UIView]()
        for i in 0..<4 {
            subviews.append(UIView())
        }
        return subviews
    }()

    override func viewDidLoad() {
      //same as above...
    }
}
</code>```

答:
You’ve put the same instance of UIView in your array four times. Your viewDidLoad just ends up moving that single view around. You need to create four separate instances of UIView.

```<code>let subviews = (0 ..< 4).map({ _ in UIView() })
</code>```

Body:
Here is a ViewController that creates 4 subviews using init(repeating:count).

In viewDidLoad I add them as subviews and set their frames. When I run the application only the last view is added.

class ViewController: UIViewController {

    let subviews = [UIView].init(repeating: UIView(), count: 4)

    override func viewDidLoad() {
        super.viewDidLoad()
        for i in 0..<subviews.count {
            self.view.addSubview(subviews[i])
            self.subviews[i].backgroundColor = UIColor.red
            self.subviews[i].frame = CGRect(x: CGFloat(i) * 35, y: 30, width: 30, height: 30)
        }
    }

}

Here's the same code except instead of using init(repeating:count) I use

a closure. This works fine-- all subviews are added.

class ViewController: UIViewController {

    let subviews: [UIView] = {
        var subviews = [UIView]()
        for i in 0..<4 {
            subviews.append(UIView())
        }
        return subviews
    }()

    override func viewDidLoad() {
      //same as above...
    }
}

Body:
You’ve put the same instance of UIView in your array four times. Your viewDidLoad just ends up moving that single view around. You need to create four separate instances of UIView.

let subviews = (0 ..< 4).map({ _ in UIView() })


问:
Gridview within a placeholder
i have currently create a user web control with a dataview in it
currently this is the gridview

```<code><div class="col-md-12">
        <asp:GridView id="dtgrid1" runat="server" AutoGenerateColumns="False"  AutoGenerateDeleteButton="True" AutoGenerateEditButton="True" AutoGenerateSelectButton="True" CellPadding="4" ForeColor="#333333" GridLines="Horizontal" AllowPaging="True" width="100%" ShowFooter="True" ShowHeaderWhenEmpty="True" EmptyDataText="No records Found">
            <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
            <Columns>
                <asp:BoundField DataField="ID" HeaderText="ID" ItemStyle-Width="30" />
                <asp:BoundField DataField="Descripcion" HeaderText="Descripcion" ItemStyle-Width="250" />
                <asp:BoundField DataField="Monto" HeaderText="Monto" ItemStyle-Width="150" />
                <asp:BoundField DataField="Fecha" HeaderText="Fecha" ItemStyle-Width="150" />
            </Columns>
            <EditRowStyle BackColor="#999999" />
            <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
            <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
            <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
            <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
            <SortedAscendingCellStyle BackColor="#E9E7E2" />
            <SortedAscendingHeaderStyle BackColor="#506C8C" />
            <SortedDescendingCellStyle BackColor="#FFFDF8" />
            <SortedDescendingHeaderStyle BackColor="#6F8DAE" />
        </asp:GridView>
    </div>
</code>```

that gridview is in a webuser control with other cotrols and divs, everythings show as it should but the gridviews
this is the code on the onload event

```<code>If Not Page.IsPostBack Then
            dim dgv1datatable as new DataTable
            With dgv1datatable
                .Columns.Add(New DataColumn("ID", GetType(Integer)))
                .Columns.Add(New DataColumn("Descripcion", GetType(String)))
                .Columns.Add(New DataColumn("Monto", GetType(Double)))
                .Columns.Add(New DataColumn("Fecha", GetType(Date)))
            End With
            Session("dgv1dt") = dgv1datatable
            dtgrid1.DataSource = DirectCast(Session("dgv1dt"), DataTable)
            dtgrid1.DataBind()
            dtgrid1.Visible = True
        End If
</code>```

but it's now showing the gridview but if i insted place the gridview where the placeholder should be the gridview shows any help please?

EDIT
im going to try and explain better the issue
this is where the gridview should've within a webusercontrol that is in a placeholder

so since it wasn't showing i decided to delete the placeholder and place the gridview in the same place and it did appear

答:
```<code><asp:SqlDataSource ID="SqlDataSource1" runat="server" CacheExpirationPolicy="Sliding"
    ConnectionString="<%$ ConnectionStrings:catalog %>"
        SelectCommand="SELECT * FROM YourDB"></asp:SqlDataSource>
</code>```

Title: Gridview within a placeholder

Body:
i have currently create a user web control with a dataview in it
currently this is the gridview

        <asp:GridView id="dtgrid1" runat="server" AutoGenerateColumns="False"  AutoGenerateDeleteButton="True" AutoGenerateEditButton="True" AutoGenerateSelectButton="True" CellPadding="4" ForeColor="#333333" GridLines="Horizontal" AllowPaging="True" width="100%" ShowFooter="True" ShowHeaderWhenEmpty="True" EmptyDataText="No records Found">
            <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
            <Columns>
                <asp:BoundField DataField="ID" HeaderText="ID" ItemStyle-Width="30" />
                <asp:BoundField DataField="Descripcion" HeaderText="Descripcion" ItemStyle-Width="250" />
                <asp:BoundField DataField="Monto" HeaderText="Monto" ItemStyle-Width="150" />
                <asp:BoundField DataField="Fecha" HeaderText="Fecha" ItemStyle-Width="150" />
            </Columns>
            <EditRowStyle BackColor="#999999" />
            <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
            <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
            <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
            <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
            <SortedAscendingCellStyle BackColor="#E9E7E2" />
            <SortedAscendingHeaderStyle BackColor="#506C8C" />
            <SortedDescendingCellStyle BackColor="#FFFDF8" />
            <SortedDescendingHeaderStyle BackColor="#6F8DAE" />
        </asp:GridView>

that gridview is in a webuser control with other cotrols and divs, everythings show as it should but the gridviews
this is the code on the onload event

If Not Page.IsPostBack Then
            dim dgv1datatable as new DataTable
            With dgv1datatable
                .Columns.Add(New DataColumn("ID", GetType(Integer)))
                .Columns.Add(New DataColumn("Descripcion", GetType(String)))
                .Columns.Add(New DataColumn("Monto", GetType(Double)))
                .Columns.Add(New DataColumn("Fecha", GetType(Date)))
            End With
            Session("dgv1dt") = dgv1datatable
            dtgrid1.DataSource = DirectCast(Session("dgv1dt"), DataTable)
            dtgrid1.DataBind()
            dtgrid1.Visible = True
        End If

but it's now showing the gridview but if i insted place the gridview where the placeholder should be the gridview shows any help please?

EDIT
im going to try and explain better the issue
this is where the gridview should've within a webusercontrol that is in a placeholder

so since it wasn't showing i decided to delete the placeholder and place the gridview in the same place and it did appear


问:
WiX: Update version number displayed in Add/Remove Programs
I use WyUpdate to automatically deliver program updates so my customers are always running the latest version. However one problem with this approach is that the MSI installer (created with WiX 3.5) is not invoked during updates and thus the version numbers in Add/Remove Programs are not incremented.

My question is if there is some safe way to programmatically bump the displayed version ?(WyUpdate has the ability to execute custom code and change registry values during updates).

答:
Technically, you can find a key in the system registry where the version is read from (typically, under SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall) and force your update software to modify this value each time with the correct version.

BUT I don't think it is a good idea. Modifying the registry keys you don't owe, and injecting your own logic into the Windows Installer might lead to unexpected consequences. I would personally never do this. Sooner or later, it will shoot...

BTW, if you don't rely on Windows Installer with updates, why it is that important to update the version in ARP? Have a well-known place in your application where users can look for the current version, for instance.


问:
GPS coordinates in background in cordova app
I'm currently doing a hybrid app using ionic/cordova.
The app needs functionality where it pings our backend with its location every 1 minute or so and the backend API will answer if anything interesting is nearby.
If the answer is yes the app will queue a local notification which hopefully will make the user open the app.
This functionality is needed when the app is in background mode and even when the phone is locked.
The app needs to be able to be deployed to both app store, google play and eventually windows phone.

I'm currently using a combination of these three plugins:

https://www.npmjs.com/package/cordova-plugin-geolocation  - for location
https://github.com/katzer/cordova-plugin-background-mode - for bg mode
https://github.com/katzer/cordova-plugin-local-notifications - for local notifications

This currently works on Android when the device is not locked (so it works in foreground and background mode) but when the device is locked it is unable to get the GPS coordinates.

My code currently looks like this:

```<code>        // Enable background worker
        (cordova as any).plugins.backgroundMode.enable();

   intervalPromise = $interval(intervalWork, 30000, 0, false);

    function intervalWork() {
        $log.log('Trying to fetch pos');

        var options = { maximumAge: 30000, timeout: 30000, enableHighAccuracy: false };

        navigator.geolocation.getCurrentPosition(success,
            err,
            options);
    }

    function success(pos) {
        $log.log("lat: " + pos.coords.latitude + " long: " + pos.coords.longitude);

        var Checkin = $resource(ApiDataEndpoint.url + 'checkin/:lat/:lng/', {});

        var res= Checkin.get({ lat: pos.coords.latitude, lng: pos.coords.longitude });

               if (res) {

                $cordovaLocalNotification.schedule({
                    id: 1,
                    title: 'test',
                    text: 'test',
                }).then(function(result) {
                    $log.log("ok");
                });
            };
         }
</code>```

So... my questions are:

1) How to get the solution to work when my device is locked (the getCurrentPosition is called even when device is locked but returns timeout)?

2) Is it possible to get this solution to work on iOS?

3) Will an app made this way be approved in google play and app store?

4) If the project is doomed what are my alternatives?

I really need help on this one!

答:
I encountered the exact same issue, using the same plugins that you used. It turns out that it's a device permissions issue.

The cordova-plugin-geolocation plugin does not have the permission to run in the background, and more importantly it doesn't have the permission to track GPS while in the background. While the cordova-plugin-background-mode plugin does allow you to execute code in the background, you won't be able to get GPS coordinates while in the background.

The solution is to add a plugin that supports getting the location data while the app in the background. There are several plugins that support this, including the mauron85/cordova-plugin-background-geolocation plugin (as suggested previously). An alternative is to use the cordova-custom-config plugin which allows you to specify your own custom permissions. Really you can add any plugin, as long as it supports background location services. No additional code is required.

You can verify that you have the correct permissions, by opening the app settings (in iOS) and confirming that the "Always" option is available.

Body:
I'm currently doing a hybrid app using ionic/cordova.
The app needs functionality where it pings our backend with its location every 1 minute or so and the backend API will answer if anything interesting is nearby.
If the answer is yes the app will queue a local notification which hopefully will make the user open the app.
This functionality is needed when the app is in background mode and even when the phone is locked.
The app needs to be able to be deployed to both app store, google play and eventually windows phone.

I'm currently using a combination of these three plugins:

https://www.npmjs.com/package/cordova-plugin-geolocation  - for location
https://github.com/katzer/cordova-plugin-background-mode - for bg mode
https://github.com/katzer/cordova-plugin-local-notifications - for local notifications

This currently works on Android when the device is not locked (so it works in foreground and background mode) but when the device is locked it is unable to get the GPS coordinates.

My code currently looks like this:

        // Enable background worker
        (cordova as any).plugins.backgroundMode.enable();

   intervalPromise = $interval(intervalWork, 30000, 0, false);

    function intervalWork() {
        $log.log('Trying to fetch pos');

        var options = { maximumAge: 30000, timeout: 30000, enableHighAccuracy: false };

        navigator.geolocation.getCurrentPosition(success,
            err,
            options);
    }

    function success(pos) {
        $log.log("lat: " + pos.coords.latitude + " long: " + pos.coords.longitude);

        var Checkin = $resource(ApiDataEndpoint.url + 'checkin/:lat/:lng/', {});

        var res= Checkin.get({ lat: pos.coords.latitude, lng: pos.coords.longitude });

               if (res) {

                $cordovaLocalNotification.schedule({
                    id: 1,
                    title: 'test',
                    text: 'test',
                }).then(function(result) {
                    $log.log("ok");
                });
            };
         }

So... my questions are:

1) How to get the solution to work when my device is locked (the getCurrentPosition is called even when device is locked but returns timeout)?

2) Is it possible to get this solution to work on iOS?

3) Will an app made this way be approved in google play and app store?

4) If the project is doomed what are my alternatives?

I really need help on this one!


问:
Mapbox style layers are hidden sometimes despite layer zoom settings equal to [0, 22]
Using mapbox gl js.

I have set all my custom mapbox style layers zoom settings to be max range [0, 22] in mapbox studio. But layers are not visible after reaching 6-8 zoom levels on zoom-out.

It seems that mapbox understand automatically somehow that there is no reasot to show polygons anymore because they are too small and hides them.

What is exact case and where could i read about this? (didn't find anything in docs)

答:
The style settings consist of two important components:

the sources

the style layers

If you tell your style layers they should display on all zoom levels but the sources are missing data for some of these zoom levels, then the corresponding style layer won't work.

Reasons why some layers do not display data for some zoom levels:

the view zoom level is smaller than the source zoom level range (if set)

the source does not contain data for the given zoom level

ContentLicense: CC BY-SA 4.0


问:
Arduino Mega slows down after 4 hours
I'm making a small project that makes some POST request to an webserver and do some tasks based on server response. Server always respond with JSON or an array

Clasic response from server looks like :

```<code>POST /app_dev.php/api/?XDEBUG_SESSION_START=vagrant HTTP/1.1
Host: XXXXXX.vagrant:8080
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: 37fddefd-e120

id=594cdf2c962d740c2b1dac22&identifier=594cdf2c962d740c2b1dac22
</code>```

The problem is that after 4 hours of running flawless my arduino mega is running very very slow. First time, it takes only 10-20ms to retrive a command and execute task (power on a led). Now, after 4 hours, it takes around 5 seconds to power the same led. I saw that ethernet leds are blinking slowly. I guess is because I've used some const char* to store server response.
My question is, at the end of the loop function, variables like const char* are deleted ?
What does my arduino to run so slowly after few hours ? Thanks

Code that runs in loop function :

```<code>    void loop () {

  dataReceived = 0;
  apiResponseReceived = 1;
  apiCommandsResponseReceived = 1;
  sendConfirmationCommand = 0;
  checkForConfirmationResponse = 0;;
  payloadData dataPacket,dataBuffer;
  tmElements_t tm;

  RTC.read(tm);

  Serial.print("some things ");
  Serial.println(queueEncrypted.count());
  Serial.print("some things");
  Serial.println(queueDecrypted.count());
  printf_P(PSTR("Free ram: %d"),freeRam());

  if(apiCommandsResponseReceived == 1) {
    Serial.print("flag message");
    byte check = stash.create();
    stash.print("identifier=");
    stash.print("8234nsda987123");
    stash.save();
    int stash_size = stash.size();
    Stash::prepare(PSTR("POST http://$F/$F HTTP/1.0" "\r\n"
      "Host: $F" "\r\n"
      "Connection: close" "\r\n"
      "Content-Type: application/x-www-form-urlencoded" "\r\n"
      "Content-Length: $D" "\r\n"
      "\r\n"
      "$H"),
    website,readCommands,website, stash_size, check);
    // send the packet - this also releases all stash buffers once done

    sessionDoi = ether.tcpSend();

    int freeCount = stash.freeCount();

    if (freeCount <= 3) {
       Stash::initMap(56);
     }

    apiCommandsResponseReceived = 0;
  }

  long timeCommand = millis();

  while(millis()- timeCommand < 5000) {

    word len = ether.packetReceive(); // go receive new packets
    word pos = ether.packetLoop(len); // respond to incoming pings
    const char* reply2 = ether.tcpReply(sessionDoi);
    StaticJsonBuffer<200> jsonBuffer;
    Serial.print("flag message");

    if (reply2 != 0) {
      Serial.println(F(" >>>REPLY recieved...."));
      Serial.println(reply2);
      reply2 = removeHTTPHeader(reply2);
      Serial.println("------HEADER REMOVED-----");
      Serial.println(reply2);
      JsonObject& root = jsonBuffer.parseObject(reply2);
      if (root.success()) {
        const char* id = root["id"];
        strcpy(global_ID_command,id);
        const char* command = root["command"];
        const char* value = root["value"];
        Serial.print("id: ");
        Serial.println(id);
        Serial.print("id glabal: ");
        Serial.println(global_ID_command);
        Serial.print("comanda: ");
        Serial.println(command);
        Serial.print("flag message");
        Serial.print(value);
        int comanda = atoi(value);

        if(comanda == 1){
          Serial.print("e 1");
          digitalWrite(error_ETH,HIGH);
        }

        if(comanda == 0 ){
          Serial.print("e 0");
          digitalWrite(error_ETH,LOW);
        }
        sendConfirmationCommand = 1;
      }
      else {
        Serial.println("flag message");
      }

      if (strstr(reply2,success)) {
        Serial.println("flag message");
      }
      apiCommandsResponseReceived = 1;
      jsonBuffer.clear();
      break;
    }
  }

  pingSite(ether.hisip, 1, 500);

  if(sendConfirmationCommand == 1) {
    Serial.print("flag message");
    byte response = stash.create();
    stash.print("response%5Bcommand%5D=");
    stash.print(global_ID_command);
    stash.print("&response%5Bcurrent_state%5D=");
    stash.print("ON");
    stash.print("&response%5Bsuccess%5D=");
    stash.print("true");
    stash.save();
    int stash_size = stash.size();
    Stash::prepare(PSTR("POST http://$F/$F HTTP/1.0" "\r\n"
      "Host: $F" "\r\n"
      "Connection: close" "\r\n"
      "Content-Type: application/x-www-form-urlencoded" "\r\n"
      "Content-Length: $D" "\r\n"
      "\r\n"
      "$H"),
    website,executeCommands,website, stash_size, response);
    // send the packet - this also releases all stash buffers once done

    sessionTrei = ether.tcpSend();

    int freeCount = stash.freeCount();

    if (freeCount <= 3) {
       Stash::initMap(56);
     }

    sendConfirmationCommand = 0;
    checkForConfirmationResponse = 1;
  }

 if(checkForConfirmationResponse == 1){

   long timeExecute = millis();

   while(millis()- timeExecute < 5000) {

     word len = ether.packetReceive(); // go receive new packets
     word pos = ether.packetLoop(len); // respond to incoming pings
     const char* reply3 = ether.tcpReply(sessionTrei);

     Serial.print("flag message");

     if (reply3 != 0) {
       Serial.println(F(" >>>REPLY recieved...."));
       Serial.println(reply3);
       reply3 = removeHTTPHeader(reply3);
       Serial.println("------HEADER REMOVED-----");
       Serial.println(reply3);
       if (strstr(reply3,success)) {
         Serial.println("flag message");
       }
       checkForConfirmationResponse = 0;
       break;
     }
   }
 }
</code>```

Function to remove headers from tcp response

```<code>    char *removeHTTPHeader(char *buffer) {
    char *t = strstr(buffer, "\r\n\r\n");
    t = t + 4;
    return t;
}
</code>```

答:
This smells like the classic dynamic memory thrashing problem.  You don't say what ethernet library(ies) you are using, so I won't venture to guess whether they are using malloc et al.

I can say that the JSON library does not use dynamic memory, so I doubt the slow-down has anything to do with parsing the response.

Without the complete code set, I would suggest freeing up as much RAM as you can, to alleviate the "search" for memory by malloc.  The single biggest culprit is your use of double-quoted string constants.  Wrap all string literals you print with the F macro:

```<code>Serial.print( F("comanda: ") );
</code>```

You did that for some, but not all.  Also, the JSON library appears to support using FLASH strings, so change all your references to:

```<code>const char* command = root[ F("command") ];
</code>```

This does not save any memory in the JSON object itself, but it does save the RAM for that identifier.

This may do nothing but extend the time you can run.

After that, you may want to look at what functions in the ethernet/Stash code do, to determine if you can limit your use of calls that fragment the heap.  If there's nothing obvious, you may want to use the Watch Dog Timer to force a reset after some predetermined time.

Yay dynamic memory in embedded systems.  -_-

Title: Arduino Mega slows down after 4 hours

Body:
I'm making a small project that makes some POST request to an webserver and do some tasks based on server response. Server always respond with JSON or an array

Clasic response from server looks like :

POST /app_dev.php/api/?XDEBUG_SESSION_START=vagrant HTTP/1.1
Host: XXXXXX.vagrant:8080
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: 37fddefd-e120

id=594cdf2c962d740c2b1dac22&identifier=594cdf2c962d740c2b1dac22

The problem is that after 4 hours of running flawless my arduino mega is running very very slow. First time, it takes only 10-20ms to retrive a command and execute task (power on a led). Now, after 4 hours, it takes around 5 seconds to power the same led. I saw that ethernet leds are blinking slowly. I guess is because I've used some const char* to store server response.
My question is, at the end of the loop function, variables like const char* are deleted ?
What does my arduino to run so slowly after few hours ? Thanks

Code that runs in loop function :

    void loop () {

  dataReceived = 0;
  apiResponseReceived = 1;
  apiCommandsResponseReceived = 1;
  sendConfirmationCommand = 0;
  checkForConfirmationResponse = 0;;
  payloadData dataPacket,dataBuffer;
  tmElements_t tm;

  RTC.read(tm);

  Serial.print("some things ");
  Serial.println(queueEncrypted.count());
  Serial.print("some things");
  Serial.println(queueDecrypted.count());
  printf_P(PSTR("Free ram: %d"),freeRam());

  if(apiCommandsResponseReceived == 1) {
    Serial.print("flag message");
    byte check = stash.create();
    stash.print("identifier=");
    stash.print("8234nsda987123");
    stash.save();
    int stash_size = stash.size();
    Stash::prepare(PSTR("POST http://$F/$F HTTP/1.0" "\r\n"
      "Host: $F" "\r\n"
      "Connection: close" "\r\n"
      "Content-Type: application/x-www-form-urlencoded" "\r\n"
      "Content-Length: $D" "\r\n"
      "\r\n"
      "$H"),
    website,readCommands,website, stash_size, check);
    // send the packet - this also releases all stash buffers once done

    sessionDoi = ether.tcpSend();

    int freeCount = stash.freeCount();

    if (freeCount <= 3) {
       Stash::initMap(56);
     }

    apiCommandsResponseReceived = 0;
  }

  long timeCommand = millis();

  while(millis()- timeCommand < 5000) {

    word len = ether.packetReceive(); // go receive new packets
    word pos = ether.packetLoop(len); // respond to incoming pings
    const char* reply2 = ether.tcpReply(sessionDoi);
    StaticJsonBuffer<200> jsonBuffer;
    Serial.print("flag message");

    if (reply2 != 0) {
      Serial.println(F(" >>>REPLY recieved...."));
      Serial.println(reply2);
      reply2 = removeHTTPHeader(reply2);
      Serial.println("------HEADER REMOVED-----");
      Serial.println(reply2);
      JsonObject& root = jsonBuffer.parseObject(reply2);
      if (root.success()) {
        const char* id = root["id"];
        strcpy(global_ID_command,id);
        const char* command = root["command"];
        const char* value = root["value"];
        Serial.print("id: ");
        Serial.println(id);
        Serial.print("id glabal: ");
        Serial.println(global_ID_command);
        Serial.print("comanda: ");
        Serial.println(command);
        Serial.print("flag message");
        Serial.print(value);
        int comanda = atoi(value);

        if(comanda == 1){
          Serial.print("e 1");
          digitalWrite(error_ETH,HIGH);
        }

        if(comanda == 0 ){
          Serial.print("e 0");
          digitalWrite(error_ETH,LOW);
        }
        sendConfirmationCommand = 1;
      }
      else {
        Serial.println("flag message");
      }

      if (strstr(reply2,success)) {
        Serial.println("flag message");
      }
      apiCommandsResponseReceived = 1;
      jsonBuffer.clear();
      break;
    }
  }

  pingSite(ether.hisip, 1, 500);

  if(sendConfirmationCommand == 1) {
    Serial.print("flag message");
    byte response = stash.create();
    stash.print("response%5Bcommand%5D=");
    stash.print(global_ID_command);
    stash.print("&response%5Bcurrent_state%5D=");
    stash.print("ON");
    stash.print("&response%5Bsuccess%5D=");
    stash.print("true");
    stash.save();
    int stash_size = stash.size();
    Stash::prepare(PSTR("POST http://$F/$F HTTP/1.0" "\r\n"
      "Host: $F" "\r\n"
      "Connection: close" "\r\n"
      "Content-Type: application/x-www-form-urlencoded" "\r\n"
      "Content-Length: $D" "\r\n"
      "\r\n"
      "$H"),
    website,executeCommands,website, stash_size, response);
    // send the packet - this also releases all stash buffers once done

    sessionTrei = ether.tcpSend();

    int freeCount = stash.freeCount();

    if (freeCount <= 3) {
       Stash::initMap(56);
     }

    sendConfirmationCommand = 0;
    checkForConfirmationResponse = 1;
  }

 if(checkForConfirmationResponse == 1){

   long timeExecute = millis();

   while(millis()- timeExecute < 5000) {

     word len = ether.packetReceive(); // go receive new packets
     word pos = ether.packetLoop(len); // respond to incoming pings
     const char* reply3 = ether.tcpReply(sessionTrei);

     Serial.print("flag message");

     if (reply3 != 0) {
       Serial.println(F(" >>>REPLY recieved...."));
       Serial.println(reply3);
       reply3 = removeHTTPHeader(reply3);
       Serial.println("------HEADER REMOVED-----");
       Serial.println(reply3);
       if (strstr(reply3,success)) {
         Serial.println("flag message");
       }
       checkForConfirmationResponse = 0;
       break;
     }
   }
 }

Function to remove headers from tcp response

    char *removeHTTPHeader(char *buffer) {
    char *t = strstr(buffer, "\r\n\r\n");
    t = t + 4;
    return t;
}

Body:
This smells like the classic dynamic memory thrashing problem.  You don't say what ethernet library(ies) you are using, so I won't venture to guess whether they are using malloc et al.

I can say that the JSON library does not use dynamic memory, so I doubt the slow-down has anything to do with parsing the response.

Without the complete code set, I would suggest freeing up as much RAM as you can, to alleviate the "search" for memory by malloc.  The single biggest culprit is your use of double-quoted string constants.  Wrap all string literals you print with the F macro:

Serial.print( F("comanda: ") );

You did that for some, but not all.  Also, the JSON library appears to support using FLASH strings, so change all your references to:

const char* command = root[ F("command") ];

This does not save any memory in the JSON object itself, but it does save the RAM for that identifier.

This may do nothing but extend the time you can run.

After that, you may want to look at what functions in the ethernet/Stash code do, to determine if you can limit your use of calls that fragment the heap.  If there's nothing obvious, you may want to use the Watch Dog Timer to force a reset after some predetermined time.

Yay dynamic memory in embedded systems.  -_-


问:
Split vector of floats by whole integer value
Suppose that I have a vector like the following

```<code>> head(samp)
[1] 1959.000 1959.083 1959.167 1959.250 1959.333 1959.417
> tail(samp)
[1] 1997.500 1997.583 1997.667 1997.750 1997.833 1997.917
</code>```

This vector represents x-values for a plot that I am constructing. I want to superimpose each year's values on top of one another for my plot. To do so, I figure that I have to split this samp vector by whole integer value.

What is the easiest way to do so ?

The only solution I have come up with is taking a sequence for all of the years with

```<code>years <- seq(floor(min(samp)),
             ceiling(max(samp)))
</code>```

and then looping through the years and indexing to find the values belonging to each year. There feels like there should be some way to cut my vector up by year like this more easily than an explicit loop, though.

答:
I just make my comment into an answer:
You are looking for the split function (see ?split to check out some examples)
It takes as arguments your vector and a vector of the same length of factors (numeric is OK) defining how to group the values. The output of split is a list.

```<code>samp = c(1959.000 ,1959.083 ,1959.167 ,1959.250, 1960.000 ,1960.083)
split(samp, floor(samp))
#### $`1959`
#### [1] 1959.000 1959.083 1959.167 1959.250
####
#### $`1960`
#### [1] 1960.000 1960.083
</code>```

Body:
Suppose that I have a vector like the following

> head(samp)
[1] 1959.000 1959.083 1959.167 1959.250 1959.333 1959.417
> tail(samp)
[1] 1997.500 1997.583 1997.667 1997.750 1997.833 1997.917

This vector represents x-values for a plot that I am constructing. I want to superimpose each year's values on top of one another for my plot. To do so, I figure that I have to split this samp vector by whole integer value.

What is the easiest way to do so ?

The only solution I have come up with is taking a sequence for all of the years with

years <- seq(floor(min(samp)),
             ceiling(max(samp)))

and then looping through the years and indexing to find the values belonging to each year. There feels like there should be some way to cut my vector up by year like this more easily than an explicit loop, though.

Body:
I just make my comment into an answer:
You are looking for the split function (see ?split to check out some examples)
It takes as arguments your vector and a vector of the same length of factors (numeric is OK) defining how to group the values. The output of split is a list.

samp = c(1959.000 ,1959.083 ,1959.167 ,1959.250, 1960.000 ,1960.083)
split(samp, floor(samp))
#### $`1959`
#### [1] 1959.000 1959.083 1959.167 1959.250
####
#### $`1960`
#### [1] 1960.000 1960.083


问:
Using AWS SES with international email addresses - RFC 2047
I'm working on a product for Japanese clients and am getting an error when trying to send to email addresses like ああ@ああ.blah.jp AWS SES (simple email service) rejects the email address:
Aws::SES::Errors::InvalidParameterValue (Local address contains control or whitespace)

The SES docs say that you need to use RFC 2047 encoding which I am. ActionMailer encodes these addresses automatically so what gets sent to SES looks like:

```<code>=?UTF-8?Q?=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E6=83=85=E5=A0=B1=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E6=83=85=E5=A0=B1=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E6=83=85=E5=A0=B1=E3=83=A6=E3=83=BCsfd=E3=82=B6=E3=83=BC=E6=83=85=E5=A0=B1@sdfds.com?=
</code>```

I don't understand why I'm getting the error.

答:
Looks like it's not supported by SES yet. Documentation is confusing on this topic.

Duplicate of this question.

Body:
I'm working on a product for Japanese clients and am getting an error when trying to send to email addresses like ああ@ああ.blah.jp AWS SES (simple email service) rejects the email address:
Aws::SES::Errors::InvalidParameterValue (Local address contains control or whitespace)

The SES docs say that you need to use RFC 2047 encoding which I am. ActionMailer encodes these addresses automatically so what gets sent to SES looks like:

=?UTF-8?Q?=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E6=83=85=E5=A0=B1=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E6=83=85=E5=A0=B1=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E6=83=85=E5=A0=B1=E3=83=A6=E3=83=BCsfd=E3=82=B6=E3=83=BC=E6=83=85=E5=A0=B1@sdfds.com?=

I don't understand why I'm getting the error.


问:
Calculating assignemnt operators
Can someone explain to me why the answer to this problem isn't 25,102?

For the following code, suppose the if statement is true 50% of the time.  If so, how many assignment operations occur?  (Don't forget to count the initializations of i and j.  Also remember that i++ and j++ are assignments.)

```<code>for (int i = 0; i < 100; i++) {
  for (int j = 0; j < 100; j++) {
    if (arr[j] < arr[i]) {
      temp = arr[i];
      arr[i] = arr[j];
      arr[j] = temp;
    }
  }
}
</code>```

答: I can see how you got 25102, but I think you've not counted the j loop properly - it doesn't just add one j=0 to the total because the whole loop happens multiple times.

Title: Calculating assignemnt operators

Body:
Can someone explain to me why the answer to this problem isn't 25,102?

For the following code, suppose the if statement is true 50% of the time.  If so, how many assignment operations occur?  (Don't forget to count the initializations of i and j.  Also remember that i++ and j++ are assignments.)

for (int i = 0; i < 100; i++) {
  for (int j = 0; j < 100; j++) {
    if (arr[j] < arr[i]) {
      temp = arr[i];
      arr[i] = arr[j];
      arr[j] = temp;
    }
  }
}