Json File:
{
"ActionName": "JobGenertorTestActions",
"ActionValue": "Test",
"AppSource": "JobGeneratorApp",
"AppText": "This is a test for a job generater app",
"DetailName": "JobGenertorTestDetails",
"DetailValue": "Test",
"Filter": true,
"FormID": "AccountingCheck",
"UserID": 12345
}
string JobEditorPath = "C:/Git/JobGeneratorApp/JobGeneratorApp/JobEditor.json";
StreamReader JobEditorReader = new StreamReader(JobEditorPath);
try
{
string jobEditorString = JobEditorReader.ReadToEnd();
JobInfoLibrary JobEditor = JsonConvert.DeserializeObject<JobInfoLibrary>(jobEditorString);
JobEditor.AppSource = JobInfo.AppSource;
JobEditor.AppText = JobInfo.AppText;
JobEditor.UserID = JobInfo.UserID;
JobEditor.Filter = JobInfo.Filter;
JobEditor.FormID = JobInfo.FormID;
JobEditor.DetailName = JobInfo.DetailName;
JobEditor.DetailValue = JobInfo.DetailValue;
JobEditor.ActionName = JobInfo.ActionName;
JobEditor.ActionValue = JobInfo.ActionValue;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
nulls in debug
json during runtime
you have to swap your instances. You are trying to assign to already assigned
using (StreamReader JobEditorReader = new StreamReader(JobEditorPath))
{
string json = JobEditorReader.ReadToEnd();
JobInfoLibrary JobEditor =
JsonConvert.DeserializeObject<JobInfoLibrary>(json);
var JobInfo= new JobInfoLibrary();
JobInfo.AppSource= JobEditor.AppSource;
... and so on
}
I only don know why you don't use JobInfo instead of JobEditor. You don't need both
Related
I am using a C# lambda to integrate with API gateway. I want API gateway to return proper error codes like 400, 404, 500 etc.
API gateway module tf file
provider "aws" {
version = "<= 2.70.0"
region = "${var.aws_region}"
profile = "${var.aws_profile}"
}
terraform {
# The configuration for this backend will be filled in by Terragrunt
backend "s3" {}
}
data "terraform_remote_state" "api_state" {
backend = "s3"
config {
region = "${var.aws_region}"
profile = "${var.aws_profile}"
bucket = "${var.s3_remote_state_bucket_name}"
key = "${var.s3_remote_state_key_name_api}"
}
}
data "terraform_remote_state" "resource_state"{
backend = "s3"
config {
region = "${var.aws_region}"
profile = "${var.aws_profile}"
bucket = "${var.s3_remote_state_bucket_name}"
key = "${var.s3_remote_state_key_name_resource}"
}
}
data "terraform_remote_state" "lambda_alias"{
backend = "s3"
config {
region = "${var.aws_region}"
profile = "${var.aws_profile}"
bucket = "${var.s3_remote_state_bucket_name}"
key = "${var.s3_remote_state_key_name_lambda}"
}
}
resource "aws_api_gateway_method" "http-method" {
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
http_method = "GET"
authorization = "CUSTOM"
authorizer_id = "${data.terraform_remote_state.api_state.Authorizers[var.Authorizer]}"
request_parameters = "${var.api_request_params_required}"
}
resource "aws_api_gateway_integration" "integration_GET" {
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
http_method = "${aws_api_gateway_method.http-method.http_method}"
integration_http_method = "POST"
type = "AWS"
uri = "arn:aws:apigateway:${var.aws_region}:lambda:path/2015-03-31/functions/${data.terraform_remote_state.lambda_alias.alias_lambda_arn}/invocations"
passthrough_behavior = "WHEN_NO_TEMPLATES"
request_templates = {
"application/json" = "${file("api_gateway_body_mapping.template")}"
}
}
resource "aws_api_gateway_model" "error_response" {
rest_api_id = "${aws_api_gateway_rest_api.api_gateway_rest_api.id}"
name = "ErrorResponse"
description = "The error respone object for all endpoints"
content_type = "application/json"
schema = <<EOF
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type" : "object",
"properties": {
"body": {
"type": "string"
},
"statusCode" : {
"type": "number"
}
}
}
EOF
}
resource "aws_api_gateway_method_response" "method_response" {
depends_on = ["aws_api_gateway_method.http-method"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "200"
}
resource "aws_api_gateway_method_response" "method_bad_request" {
depends_on = ["aws_api_gateway_method.http-method"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "400"
response_models {
"application/json" = "${aws_api_gateway_model.error_response}"
}
}
resource "aws_api_gateway_method_response" "method_not_found" {
depends_on = ["aws_api_gateway_method.http-method"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "404"
response_models {
"application/json" = "${aws_api_gateway_model.error_response}"
}
}
resource "aws_api_gateway_method_response" "method_error" {
depends_on = ["aws_api_gateway_method.http-method"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "500"
response_models {
"application/json" = "${aws_api_gateway_model.error_response}"
}
}
resource "aws_api_gateway_integration_response" "get_integration_response_success" {
depends_on = ["aws_api_gateway_method_response.method_response", "aws_api_gateway_integration.integration_GET"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "${aws_api_gateway_method_response.method_response.status_code}"
response_templates {
"application/json" = ""
}
}
resource "aws_api_gateway_integration_response" "get_integration_response_error" {
depends_on = ["aws_api_gateway_method_response.method_error", "aws_api_gateway_integration.integration_GET"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "${aws_api_gateway_method_response.method_error.status_code}"
selection_pattern = ".*statusCode['\"]\\s*:\\s*['\"]?500.*"
response_templates {
"application/json"="${file("api_gateway_exception_mapping.template")}"
}
}
resource "aws_api_gateway_integration_response" "get_integration_response_bad_request" {
depends_on = ["aws_api_gateway_method_response.method_bad_request", "aws_api_gateway_integration.integration_GET"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "${aws_api_gateway_method_response.method_bad_request.status_code}"
selection_pattern = ".*statusCode['\"]\\s*:\\s*['\"]?400.*"
response_templates {
"application/json"="${file("api_gateway_exception_mapping.template")}"
}
}
resource "aws_api_gateway_integration_response" "get_integration_response_not_found" {
depends_on = ["aws_api_gateway_method_response.method_not_found", "aws_api_gateway_integration.integration_GET"]
http_method = "${aws_api_gateway_method.http-method.http_method}"
resource_id = "${data.terraform_remote_state.resource_state.api_resource_id}"
rest_api_id = "${data.terraform_remote_state.api_state.api_gateway_rest_api_id}"
status_code = "${aws_api_gateway_method_response.method_not_found.status_code}"
selection_pattern = ".*statusCode['\"]\\s*:\\s*['\"]?404.*"
response_templates {
"application/json"="{}"
}
}
api_gateway_exception_mapping.template:
#set($inputRoot = $util.parseJson($input.path('$.errorMessage')))
{
"Error":"$inputRoot.body"
}
The integration response mapping is as in below snapshot
We have create APIs with lambda integration in python where I threw a custom APIException as below and it worked.
class ApiException(Exception):
"""Our custom APIException class which derives from the built-in Exception class"""
def __init__(self, status_code, message: str, **kwargs):
self.status_code = status_code
self.message = message
kwargs["statusCode"] = status_code
kwargs["body"] = message
super().__init__(json.dumps(kwargs))
Inside the lambda handler:
from .utils import ApiException
def lambda_handler(event, context):
try:
"""
CODE FOR LAMBDA HANDLER
"""
except Exception:
ex = ApiException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
message='Internal Error')
print("exception string: %s", ex)
raise ApiException(
status_code=500,
message='Internal server error')
When I logged the exception, I got the following output
{
"statusCode": 500,
"body": "Internal Server Error"
}
I also referred this stackoverflow answer on how to get proper error codes in API Gateway response. I modified that a little bit to throw an exception instead of just returning a json with statusCode, response body and headers as I am not using AWS_PROXY integration type
APIException.cs
public class APIException : Exception
{
public int statusCode;
public string body;
public APIException() : base() {}
public APIException(int statusCode, string message): base(message) {
this.statusCode = statusCode;
JObject json = JObject.Parse(message);
this.body = json["body"].ToString();
}
}
Lambda handler:
namespace LambdaFunction
{
public class Function
{
public async Task<JObject> FunctionHandler(JObject events, ILambdaContext context)
{
try
{
ValidateQueryParams(events, context);
JObject response = JObject.Parse(#"{
'mesage': 'success',
}");
return response;
}
catch(HttpListenerException ex)
{
string err = (new JObject(
new JProperty("statusCode", ex.ErrorCode),
new JProperty("body", ex.Message)
)).ToString();
return new APIException(ex.ErrorCode, err);
}
catch(Exception ex)
{
int err_code = (int)HttpStatusCode.InternalServerError
string err = (new JObject(
new JProperty("statusCode", err_code),
new JProperty("body", "Internal Server Error")
)).ToString();
var err_ex = new APIException(err_code, err);
context.Logger.LogLine("Unhandled exception occurred: " + ex.ToString());
return err_ex;
}
}
}
}
I've logged the exception before throwing it to see what we are getting and this is what I got
{
"statusCode": 500,
"body": "Internal Server Error",
"StackTrace": null,
"Message": "{\n \"statusCode\": 500,\n \"body\": \"Internal Server Error\"\n}",
"Data": {},
"InnerException": null,
"HelpLink": null,
"Source": null,
"HResult": -2146233088
}
But with the above code, I'm still just getting response code as 200 with below response body
{
"errorType": "APIException",
"errorMessage": "{\n \"statusCode\": 500,\n \"body\": \"Internal Server Error\"\n}",
"stackTrace": [
"..."
]
}
I am not sure where I am going wrong. Any help will be appreciated. Thanks.
I've figured out the issue. C#'s .ToString() function which converts JObject into a string is formatting the string and adding new line characters \n by default. But the regex used in API gateway to identify error codes does not consider new line characters. The fix was pretty simple. We need to tell the .ToString() function that it shouldn't do any formatting. So, instead of
new JObject(
new JProperty("statusCode", err_code),
new JProperty("body", "Internal Server Error")
)).ToString();
You need to do
new JObject(
new JProperty("statusCode", err_code),
new JProperty("body", "Internal Server Error")
)).ToString(Formatting.None);
And it worked.
In my stored procedure, I am getting the right nested json, but when I call the api from Postman, the result is returned with slashes as shown below. How to remove these backslashes from my result? Is this approach correct, or should I go for some different approach?
The procedure is below
ALTER PROCEDIRE [dbo].[USP_MobileApp_MenuList]
AS
BEGIN
SELECT
MMM.userid AS userid,
MMM.type AS type,
MMM.pid AS pid,
mmm.pname AS pname,
mmm.url AS url,
Smenu = (SELECT
MMS.sid AS sid,
MMS.sname AS sname,
MMS.icon AS icon,
MMS.url AS url
FROM M_MobileApp_SubMenu MMS
WHERE MMS.pid = MMM.pid
FOR JSON PATH)
FROM
M_MobileApp_Menu MMM) A
END
The web Api call code is
[HttpGet]
[Route("getMobileMenulist")]
public HttpResponseMessage GetMobileMenuliste(HttpRequestMessage objrequest)
{
DBdata objLogin = new DBdata();
HttpResponseMessage respone = Request.CreateResponse(HttpStatusCode.OK, objLogin.GetMobileMenulist());
return respone;
}
public object GetMobileMenulist()
{
DataTable objData = new DataTable();
Query = "USP_MobileApp_MenuList";
try
{
using (ObjSqlConnection = new SqlConnection(MDMSConnectionString))
{
using (ObjSqlCommand = new SqlCommand(Query, ObjSqlConnection))
{
ObjSqlCommand.CommandType = CommandType.StoredProcedure;
using (SqlDataAdapter sda = new SqlDataAdapter())
{
ObjSqlConnection.Open();
sda.SelectCommand = ObjSqlCommand;
sda.Fill(objData);
//for (int i = 0; i <= objData.Rows.Count - 1; i++)
//{
// objData.Rows[i][1] = objData.Rows[i][1].ToString().Replace(#"\", "");
//}
ObjSqlConnection.Close();
}
}
}
return objData;
}
catch (Exception ex)
{
Log = new Logger();
Log.writeErrorLog(ex, 0, ex.Message);
//objLog.LogError(ex);
}
finally
{
if (ObjSqlConnection.State != ConnectionState.Closed)
{
ObjSqlConnection.Close();
ObjSqlConnection.Dispose();
}
}
return objData;
}
The result I am getting in Postman:
[
{
"userid": 1,
"type": "APP ",
"PID": 2,
"PNAME": "Consumtion Log",
"URL": "/ConsumtionLog",
"smenu": "[{\"sid\":1,\"sname\":\"Comparison\",\"icon\":\"fa fa-shower\",\"url\":\"/ConsumtionLog/Comparison\"},{\"sid\":2,\"sname\":\"History\",\"url\":\"/ConsumtionLog/History\"}]"
},
{
"userid": 1,
"type": "APP ",
"PID": 3,
"PNAME": "Billing",
"URL": "/Billing",
"smenu": "[{\"sid\":3,\"sname\":\"Pay my bill\",\"url\":\"/ Billing/Paymybill\"},{\"sid\":4,\"sname\":\"Billing History\",\"url\":\"/Billing/BillingHistory\"}]"
}]
The SQL Server has no native JSON type (or BJSON) and store the JSON as string. After read, just convert it to JSON:
let x = "[{\"sid\":1,\"sname\":\"Comparison\",\"icon\":\"fa fa-shower\",\"url\":\"/ConsumtionLog/Comparison\"},{\"sid\":2,\"sname\":\"History\",\"url\":\"/ConsumtionLog/History\"}]"
let y = JSON.parse(x)
I am writing to you because i got error during using the AutoML API from google.cloud.
Documentation website:
https://cloud.google.com/translate/automl/docs/predict#automl_translate_predict-csharp
public async Task<IActionResult> UploadToTranslate(IFormFile excelFile)
{
//rest of code...
string credential_path = #"xxxx.json";
System.Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", credential_path);
var client = PredictionServiceClient.Create();
var modelName = ModelName.Format(_config.GetValue<string>("ValuesEnPl:projectId"), _config.GetValue<string>("ValuesEnPl:location"), _config.GetValue<string>("ValuesEnPl:modelId"));
var predictionRequest = new PredictRequest
{
Name = modelName,
Payload = new ExamplePayload
{
TextSnippet = new TextSnippet
{
Content = "Tom goes home"
},
},
};
try
{
var response = client.Predict(predictionRequest, CallSettings.FromCallTiming(CallTiming.FromDeadline(DateTime.UtcNow.AddSeconds(100))));
foreach (var payload in response.Payload)
{
Console.Write($"Translated Content: {payload.Translation.TranslatedContent.Content}");
}
}
catch (RpcException ex)
{
}
//rest of code...
}
Exception: Message = "Status(StatusCode=Unavailable, Detail=\"failed
to connect to all addresses\")"
I Have to Upload the file to my teamdrive, the file has been created to team drive but I can not upload the file chunks to it. So, please help to solve it.
On Writing a Chunk I am facing the Error of "The remote server returned an error: (404) Not Found."
I am getting the Teamdrive ID and the File ID which has been created.
/*** Creation of a File to Team Drive ***/
f_ObjFile.TeamDriveId = "/*TeamDrive ID*/";
try
{
f_ObjNewFile.Parents = f_ObjFile.Parents; // f_ObjFile = <Team Driv ID>
f_ObjNewFile.Name = f_ObjFile.Name;
f_ObjNewFile.MimeType = f_ObjFile.MimeType;
f_ObjNewFile.TeamDriveId = f_ObjFile.TeamDriveId;
f_CreateRequest = GoogleHelper.InvokeApiCall(() => { return this.DriveServiceObj.Files.Create(f_ObjNewFile); }, this);
if (f_CreateRequest != null)
{
f_CreateRequest.SupportsTeamDrives = true;
f_CreateRequest.Fields = "*";
f_ObjNewFile = GoogleHelper.InvokeApiCall(() => { return f_CreateRequest.Execute(); }, this);
}
f_ObjDocumentItem = new DocumentItem(UserEmailID, f_ObjNewFile);
f_ObjDocumentItem.ItemID = f_ObjNewFile.Id;
string f_Url = GoogleHelper.CreateChunkURL("https://www.googleapis.com/upload/drive/v3/files/{0}?uploadType=resumable", f_ObjNewFile.Id);
f_ObjDocumentItem.ChunkUploadURL = InitiateResumeRequest(f_Url, f_ObjNewFile.Id);
}
catch(Exception ex) { }
finally
{
f_ObjNewFile = null;
f_CreateRequest = null;
}
/* Writing the chunks to the file in TeamDrive */
try
{
httpRequest = GoogleHelper.CreateHttpWebRequestObj(f_ObjChunkData.ChunkUploadURL,true);
httpRequest.Method = GoogleConstant.PATCH;
httpRequest.ContentLength = f_ObjChunkData.FileData.Length;
httpRequest.SendChunked = true;
httpRequest.Headers["Content-Range"] = "bytes " + f_ObjChunkData.StartOffset +
"-" +
f_ObjChunkData.EndOffset + "/" +
f_ObjChunkData.FileSize.ToString();
using (System.IO.Stream f_ObjHttpStream = GoogleHelper.InvokeApiCall(() => { return httpRequest.GetRequestStream(); }, this))
{
if (f_ObjHttpStream != null)
{
System.IO.MemoryStream f_ChunkStream = null;
f_ChunkStream = new System.IO.MemoryStream(f_ObjChunkData.FileData);
f_ChunkStream.CopyTo(f_ObjHttpStream);
f_ObjHttpStream.Flush();
f_ObjHttpStream.Close();
f_ChunkStream.Close();
f_ChunkStream = null;
}
}
using (HttpWebResponse httpResponse = GoogleHelper.InvokeApiCall(() => { return (HttpWebResponse)(httpRequest.GetResponse()); }, this))
{
if (httpResponse != null)
{
if (httpResponse.StatusCode == HttpStatusCode.OK)
{
httpResponse.Close();
}
}
}
}
catch (Exception ex) { }
In Followin Line :
string f_Url = GoogleHelper.CreateChunkURL("https://www.googleapis.com/upload/drive/v3/files/{0}?uploadType=resumable", f_ObjNewFile.Id);
Insted Of
"https://www.googleapis.com/upload/drive/v3/files/{0}?uploadType=resumable"
Use following URL :
https://www.googleapis.com/upload/drive/v3/files/{0}?uploadType=resumable&supportsTeamDrives=true
and its Done...
Now you can upload the chunks...
I have a ASP MVC project with some Ajax Calls, where I am trying to pass from jquery/Ajax to my AjaxController (see bellow code) where in the controller sting item is receiving a json string like this
"[\n \"1002\",\n \"1003\"\n]"
And I get this error in my controller (See bellow code where the comment identifies the error)
Newtonsoft.Json.JsonSerializationException: Error converting value "1002" to type 'System.String[]'. Path '[0]', line 2, position 9. ---> System.ArgumentException: Could not cast or convert from System.String to System.String[]. at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType) at Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType) ...(continue)
This is my Json/Jquery creation function
function SaveObservations() {
var SerSel = $("#ServiceIdSelect2").val();
var obs = $("#observation").val();
var itemsX = [];
if (obs == "") {
mostrar_alert_ui("Validation message", "Observation cannot be null", 350);
} else {
//Start json creation
$("#ItemsPieces > input:checked").each(function () {
var id = $(this).val();
itemsX.push(id);
});
var itemsY = JSON.stringify(itemsX, null, 2);
//End json creation
Funciones_Ajax_conAlert("/Ajax/SendEmailItemsToClient/", { proyecto: SerSel, items: itemsY, observation: obs }, CloseObservations);
}
}
And here is my controller where the error is given
public JsonResult SendEmailItemsToClient(int proyecto, string items, string observation)
{
object data = null;
try
{
List<string[]> datax1 = JsonConvert.DeserializeObject<List<string[]>>(items); //Here is the issue Aqui tengo el problema
foreach (var item in datax1)
{
string test = item.ToString();
}
string mensaje = "";
int ProjectIdx = proyecto;
bool resp = CorreccionesController.SendItemsDifferentsToClient(ProjectIdx, mensaje);
if (resp) {
data = new
{
success = true,
titulo = "Notification",
mensaje = "A message explaining why the different items selected are used had been sent"
};
}
else
{
data = new
{
success = false,
titulo = "Notification",
mensaje = "The observation is Saved but the email couldn't be send, please contact support"
};
}
}
catch (Exception ex)
{
data = new
{
success = false,
titulo = "ERROR",
mensaje = ex.ToString()
};
}
return Json(data, JsonRequestBehavior.AllowGet);
}
The question would be how can I itterate that json string without receiving an error?
Your code need a little bit of refactoring; basically you have a json structure like this one:
[
"1002",
"1003"
]
That is basically an Array of Strings.
In your Controller you have the following line:
List<string[]> datax1 = JsonConvert.DeserializeObject<List<string[]>>(items);
Now, what this little chunk of code List<string[]> means? With that line you are trying to create a List of arrays of string, something like this:
[
["1002","1003"],
["1002","1003"]
]
So your deserializing methods fails with the following message: Could not cast or convert from System.String to System.String[]. Now makes sense.
So if you want to deserialize an json array of string you just needs:
List<string> datax1 = JsonConvert.DeserializeObject<List<string>>(items);
List<string> is just like and array of string(internally a list is constructed on an array basis, check this answer for more information about array and list: Array versus List<T>: When to use which?
Based on that info you can write your code this way too:
string[] datax1 = JsonConvert.DeserializeObject<string[]>(items); //Not tested, but should works.
Don't double Json encode, and let the WebAPI do all the work:
function SaveObservations() {
var SerSel = $("#ServiceIdSelect2").val();
var obs = $("#observation").val();
var itemsX = [];
if (obs == "") {
mostrar_alert_ui("Validation message", "Observation cannot be null", 350);
} else {
//Start json creation
$("#ItemsPieces > input:checked").each(function () {
var id = $(this).val();
itemsX.push(id);
});
//End json creation
Funciones_Ajax_conAlert("/Ajax/SendEmailItemsToClient/", { proyecto: SerSel, items: itemsX, observation: obs }, CloseObservations);
}
}
and
public JsonResult SendEmailItemsToClient(int proyecto, string[] items, string observation)
{
object data = null;
try
{
foreach (var item in items)
{
string test = item.ToString();
}
string mensaje = "";
int ProjectIdx = proyecto;
bool resp = CorreccionesController.SendItemsDifferentsToClient(ProjectIdx, mensaje);
if (resp) {
data = new
{
success = true,
titulo = "Notification",
mensaje = "A message explaining why the different items selected are used had been sent"
};
}
else
{
data = new
{
success = false,
titulo = "Notification",
mensaje = "The observation is Saved but the email couldn't be send, please contact support"
};
}
}
catch (Exception ex)
{
data = new
{
success = false,
titulo = "ERROR",
mensaje = ex.ToString()
};
}
return Json(data, JsonRequestBehavior.AllowGet);
}