Couldn't send and store String data to database through WCF - sql-server

I have created a Windows 8 app, I have a table in SQL server database to store people's name, " [Name] VARCHAR (50)"
I have manage to send and save integer values to database, but when i modified my coding to store the string, it does not work, table data is empty. Please help!
itemDetail.html
<div>
<input id="join1" type="text" />
<button id="joinbtn">insert</button>
</div>
itemDetail.js
var joinButton = document.getElementById('joinbtn');
// Register Click event
joinButton.addEventListener("click", joinButtonClick, false);
function joinButtonClick() {
// Retrieve element
var baseURI2 = "http://localhost:45573/AddService.svc/Join";
var jointext = document.getElementById('join1').value;
WinJS.xhr({
type: "POST",
url: baseURI2,
headers: { "Content-type": "application/json" },
data: '{"namet":' + jointext + '}'
}).then(function complete(request) {
var resdata = request.responseText;
}, function error(er) {
var err = er.statusText;
})
}
AddService.svc.cs
public void Join(string namet)
{
string connectionString = System.Configuration.ConfigurationManager.
ConnectionStrings["Database1ConnectionString1"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
string sql = "INSERT INTO Table2(Name) VALUES (#Name)";
SqlCommand cmd = new SqlCommand(sql, con);
cmd.Parameters.AddWithValue("#Name", namet);
try
{
con.Open();
int numAff = cmd.ExecuteNonQuery();
}
con.Close();
}
IAddService.cs
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
void Join(string namet);
Thank you!

I think the problem may be in this line
data: '{"namet":' + jointext + '}'
Try changing it to
data: '{"namet":\'' + jointext + '\'}'

Related

Ef core could not translate my custom sql server STRING_AGG function

String.Join in efcore not support and I want to get list of string with separator like sql function String_Agg
I tried to create custom sql server function but i get this error:
The parameter 'columnPartArg' for the DbFunction 'QueryHelper.StringAgg(System.Collections.Generic.IEnumerable`1[[System.String, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=]],System.String)' has an invalid type 'IEnumerable'. Ensure the parameter type can be mapped by the current provider.
This is my function and OnModelCreatingAddStringAgg for register it in my dbcontext
public static string StringAgg(IEnumerable<string> columnPartArg, [NotParameterized] string separator)
{
throw new NotSupportedException();
}
public static void OnModelCreatingAddStringAgg(ModelBuilder modelBuilder)
{
var StringAggFuction = typeof(QueryHelper).GetRuntimeMethod(nameof(QueryHelper.StringAgg), new[] { typeof(IEnumerable<string>), typeof(string) });
var stringTypeMapping = new StringTypeMapping("NVARCHAR(MAX)");
modelBuilder
.HasDbFunction(StringAggFuction)
.HasTranslation(args => new SqlFunctionExpression("STRING_AGG",
new[]
{
new SqlFragmentExpression((args.ToArray()[0] as SqlConstantExpression).Value.ToString()),
args.ToArray()[1]
}
, nullable: true, argumentsPropagateNullability: new[] { false, false }, StringAggFuction.ReturnType, stringTypeMapping));
}
and this code run above function
_context.PersonnelProjectTimeSheets.GroupBy(c => new { c.Date.Date, c.PersonnelId, c.Personnel.PersonnelCode, c.Personnel.FirstName, c.Personnel.LastName})
.Select(c => new PersonnelProjectTimeOutputViewModel
{
IsConfirmed = c.Min(c => (int)(object)(c.IsConfirmed ?? false)) == 1,
PersonnelDisplay = c.Key.PersonnelCode + " - " + c.Key.FirstName + " " + c.Key.LastName,
PersonnelId = c.Key.PersonnelId,
Date = c.Key.Date,
ProjectName = QueryHelper.StringAgg(c.Select(x=>x.Project.Name), ", "),
TotalWorkTime = 0,
WorkTimeInMinutes = c.Sum(c => c.WorkTimeInMinutes),
});
And also i change my StringAgg method input to
string columnPartArg
and change SqlFunctionExpression of OnModelCreatingAddStringAgg to
new[]
{
new SqlFragmentExpression((args.ToArray()[0] as
SqlConstantExpression).Value.ToString()),
args.ToArray()[1]
}
and change my query code to
ProjectName = QueryHelper.StringAgg("Project.Name", ", ")
now when run my query, sql server could not recognize the Project
i guess the parameter 'columnPartArg' of dbfunction 'STRING_AGG' is varchar or nvarchar. right?
most database function or procedure has not table value as parameter.
in this case,use EFCore's 'client evaluation' is good sulution. linq like below:
_context.PersonnelProjectTimeSheets.GroupBy(c => new { c.Date.Date, c.PersonnelId, c.Personnel.PersonnelCode, c.Personnel.FirstName, c.Personnel.LastName})
.Select(c => new PersonnelProjectTimeOutputViewModel
{
IsConfirmed = c.Min(c => (int)(object)(c.IsConfirmed ?? false)) == 1,
PersonnelDisplay = c.Key.PersonnelCode + " - " + c.Key.FirstName + " " + c.Key.LastName,
PersonnelId = c.Key.PersonnelId,
Date = c.Key.Date,
ProjectName = string.Join(", ",c.Select(x=>x.Project.Name)),//Client evaluation
TotalWorkTime = 0,
WorkTimeInMinutes = c.Sum(c => c.WorkTimeInMinutes),
});

Angular 11 HTTP POST to SQL Server Database

I am trying to post my inputs to my SQL Server database. I can in fact POST to the database, but I get back a blank response. I know it's because I am returning "Success" instead of my variables but how to I correctly format that for the return statement?
POST method:
[HttpPost]
public JsonResult Post(Weather Wea)
{
string query = #"INSERT INTO dbo.Information (Date, TemperatureC, TemperatureF, Summary) VALUES ('" + Wea.Date + #"'
,'" + Wea.TemperatureC + #"'
,'" + Wea.TemperatureF + #"'
,'" + Wea.Summary + #"'
)";
DataTable table = new DataTable();
string sqlDataSource = _configuration.GetConnectionString("WeatherAppCon");
SqlDataReader myReader;
using (SqlConnection myCon = new SqlConnection(sqlDataSource))
{
myCon.Open();
using (SqlCommand myCommand = new SqlCommand(query, myCon))
{
myReader = myCommand.ExecuteReader();
table.Load(myReader);
myReader.Close();
myCon.Close();
}
}
return new JsonResult("Success");
}
Front-end POST
export class PostDataComponent {
baseUrl: string;
date: number;
temperatureC: number;
summary: string;
weatherForm: FormGroup;
constructor(public http: HttpClient, #Inject('BASE_URL') baseUrl: string, private formBuilder: FormBuilder) {
this.baseUrl = "https://localhost:44347/WeatherForecast";
this.weatherForm = formBuilder.group({
Date: new FormControl(),
TemperatureC: new FormControl(),
Summary: new FormControl()
});
}
CreateData() {
const params = new HttpParams({
fromObject: {
'date': this.weatherForm.value.Date.toString(),
'temperatureC': this.weatherForm.value.TemperatureC.toString(),
'summary': this.weatherForm.value.Summary.toString()
}
});
console.log(params);
this.http.post(this.baseUrl, {},{ params: params }).subscribe(data => {
console.log(data);
});
}
}
Couple things here.
As marc_s commented, you should be using parameterization instead of concatenating to avoid any potential SQL injection:
string query = #"INSERT INTO dbo.Information (Date, TemperatureC, TemperatureF, Summary) VALUES (#Date, #TemperatureC, #TemperatureF, #Summary)";
...
using (System.Data.SqlClient.SqlCommand myCommand = new SqlCommand(query, myCon))
{
myCommand.Parameters.AddWithValue("#Date", Wea.Date);
myCommand.Parameters.AddWithValue("#TemperatureC", Wea.TemperatureC);
myCommand.Parameters.AddWithValue("#TemperatureF", Wea.TemperatureF);
myCommand.Parameters.AddWithValue("#Summary", Wea.Summary);
...
Unless you have a trigger on your target table with an output, your query isn't returning any data (just the number of rows inserted) and your SqlDataReader is empty. You could get rid of the reader/DataTable and use myCommand.ExecuteScalar() instead in this case. If you do have a trigger outputting the inserted data, disregard this.
If you don't have an output trigger but do still need to return the inserted values for whatever reason, you could keep your SqlDataReader and update your query to the following
string query = #"INSERT INTO dbo.Information (Date, TemperatureC, TemperatureF, Summary)
OUTPUT inserted.Date,inserted.TemperatureC,inserted.TemperatureF,inserted.Summary
VALUES (#Date, #TemperatureC, #TempreatureF, #Summary)";
Without knowing the response format you're looking for, it's hard to give an answer on how to generate it. If you need to return the inserted values, you could use the OUTPUT keyword as in the previous bullet and serialize your DataTable.

$resource POST Error 400

Hi guys i'm working with angular $resource to make POST call. This is my FE function
$scope.showPrompt = function (ev) {
$scope.usernameSelected = [];
$scope.users.forEach(function (element) {
if (element.checked)
$scope.usernameSelected.push(element);
console.log($scope.usernameSelected);
});
var conferma = $mdDialog.prompt()
.title('Insert group name?')
.clickOutsideToClose(true)
//.textContent('Bowser is a common name.')
.placeholder('Group name')
.ariaLabel('Group name')
.targetEvent(ev)
.ok('Crea gruppo')
.cancel('Annulla');
$mdDialog.show(conferma).then(function (result) {
GroupService.group({}, {
creatore: $cookieStore.get('username'),
gruppo: result,
partecipanti: $scope.usernameSelected},
function (data) {
console.log("GRUPPO", data);
});
$scope.status = 'NOMEGRUPPO: ' + result + '.'; //inserito il nome gruppo
}, function () {
$scope.status = 'INSERT NOME GRUPPO';
});
};
This the GroupService:
var groupService = angular.module("groupService",['ngResource']);
groupService.factory("GroupService",['$resource',
function($resource){
var url = "";
return $resource("",{},{
group: {method : "POST", url:url+"group", isArray: false},
findGroup: {method : "GET", url:url+"findGroup", isArray: true}
});
}]);
I have this error:
angular.js:14328 Possibly unhandled rejection: {"data":"<!DOCTYPE html><html><head><title>Apache Tomcat/8.5.11 - Error report</title><style type=\"text/css\">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style> </head><body><h1>HTTP Status 400 - </h1><div class=\"line\"></div><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The request sent by the client was syntactically incorrect.</u></p><hr class=\"line\"><h3>Apache Tomcat/8.5.11</h3></body></html>","status":400,"config":{"method":"POST","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"group","data":{"creatore":"ciro","gruppo":"nuovo","partecipanti":[{"id":0,"username":"a","email":"a#aa","password":null,"name":"a","surname":"a","longitude":0,"latitude":0,"checked":true},{"id":0,"username":"ciao","email":"ciao#ciao","password":null,"name":"ciao","surname":"ciao","longitude":0,"latitude":0,"checked":true}]},"headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json;charset=utf-8"}},"statusText":""}
This is my BE code. I have a spring controller that manage client requests
#RequestMapping(value = "/group", method = RequestMethod.POST)
public #ResponseBody
Group createGroup(#RequestBody Group json, HttpServletRequest request) throws SQLException, ClassNotFoundException {
Group g = DBUtils.insertGroup(json.getPartecipanti(), json.getGruppo(), json.getCreatore());
return g;
}
This is my DBUtils.insertGroup
public static Group insertGroup(List<String> members, String groupName, String userCreator) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn;
conn = DriverManager.getConnection(DB_URL, USER, PASS);
String sql = "insert into gruppo \n"
+ " (idCreatorUser,groupName,idPartecipante,data) values (?,?,?,?) ";
PreparedStatement pstm = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
java.util.Date date = new Date();
Timestamp timestamp = new Timestamp(date.getTime());
Utente creator = DBUtils.findUser(userCreator);
pstm.setInt(1, creator.getId());
pstm.setString(2, groupName);
pstm.setInt(3, creator.getId());
pstm.setTimestamp(4, timestamp);
int res = pstm.executeUpdate();
ResultSet rsId = pstm.getGeneratedKeys();
rsId.next();
int idGruppo = rsId.getInt(1);
Group response = new Group();
response.setIdGruppo(idGruppo);
response.setGruppo(groupName);
response.setIdCreatore(creator.getId());
response.setData(timestamp);
response.setPartecipanti(members);
response.setCreatore(creator.getUsername());
System.out.println(response);
sql = "insert ignore into gruppo \n"
+ " (idGruppo,idCreatorUser,groupName,idPartecipante,data) values (?,?,?,?,?) ";
pstm = conn.prepareStatement(sql);
Utente part;
for (int i = 0; i < members.size(); i++) {
pstm.setInt(1, idGruppo);
pstm.setInt(2, creator.getId());
pstm.setString(3, groupName);
part = DBUtils.findUser(members.get(i));
pstm.setInt(4, part.getId());
pstm.setTimestamp(5, timestamp);
pstm.executeUpdate();
}
conn.close();
return response;
}
I want to send in body some parameters but I can't to figure out what is the syntact error made.

Returning a Json object from c# to an Angular controller

I am trying to return a Json object from a C# WebAPI method. My current c# code creates an IEnumerable type, populates the object of a class, then returns it to the JavaScript call. However it's returning a 5 element array rather than a single Json object of 5 fields.
What I would like to do is simply return a single Json object with 5 fields, in this format:
{"domain":"localhost", "spaceName":"rz64698", etc...}
This way in javascript I can simply access each field as
_domain = rzEnvParams.domainName;
_space = rzEnvParams.spaceName;
The response object returned from c# (to my Angular service) is this array. i'm only showing two of five elements here. :
$id: "1"
$type: "RgSys.Controllers.RgController+RzEnvParameters, RgSys"
clConfig: "C:\Rz\rz64698\master\bin\cl_config.xml"
domainName: null
envName: null
port: null
spaceName: null
$id: "2"
$type: "RgSys.Controllers.RgController+RzEnvParameters, RgSys"
clConfig: "null
domainName: null
envName: null
port: null
spaceName: "rz64698"
and so on until $id: "5"
Here's how I'm current accessing the array in javaScript (it works but I feel there's a more efficient way) :
$http({
method: 'GET',
encoding: 'JSON',
url: 'breeze/breeze/GetRzEnv'
}).success(function (data, status, headers, config) {
rzEnvParams = data;
deferred.resolve(rzEnvParams);
$.each(rzEnvParams, function(key,value){
if (value.domainName != null) {
_domain = value.domainName;;
}
if (value.port != null) {
_port = value.port;
}
});
});
and here's the current c# code which return :
public class RzEnvParameters{
public string clConfig;
public string envName;
public string spaceName;
public string domainName;
public string port;
}
[HttpGet]
public IEnumerable<RzEnvParameters> GetRzEnv()
{
string clConfig = System.Configuration.ConfigurationManager.AppSettings["ClConfig"].ToString();
string envName = System.Configuration.ConfigurationManager.AppSettings["EnvironmentName"].ToString();
string spaceName = System.Configuration.ConfigurationManager.AppSettings["SpaceName"].ToString();
string domainName = System.Configuration.ConfigurationManager.AppSettings["DomainName"].ToString();
string port = System.Configuration.ConfigurationManager.AppSettings["Port"].ToString();
var razParams = new List<RzEnvParameters>{
new RzEnvParameters{clConfig=clConfig},
new RzEnvParameters{envName=envName},
new RzEnvParameters{spaceName=spaceName},
new RzEnvParameters{domainName=domainName},
new RzEnvParameters{port=port}
};
return rzParams;
}
Bottom line: how do I refactor that c# code to return the Json object rather than an array of 5 elements.
thanks.
Bob
It looks like you're returning a list of RzEnvParameters where only one property of each is set. Is there a reason you are doing that instead of just returning one RzEnvParameters object with all the properties set?
[HttpGet]
public RzEnvParameters GetRzEnv()
{
string clConfig = System.Configuration.ConfigurationManager.AppSettings["ClConfig"].ToString();
string envName = System.Configuration.ConfigurationManager.AppSettings["EnvironmentName"].ToString();
string spaceName = System.Configuration.ConfigurationManager.AppSettings["SpaceName"].ToString();
string domainName = System.Configuration.ConfigurationManager.AppSettings["DomainName"].ToString();
string port = System.Configuration.ConfigurationManager.AppSettings["Port"].ToString();
var razParams = new RzEnvParameters
{
clConfig = clConfig,
envName = envName,
spaceName = spaceName,
domainName = domainName,
port = port
};
return razParams;
}
And that would change your javascript to something like this:
$http({
method: 'GET',
encoding: 'JSON',
url: 'breeze/breeze/GetRzEnv'
}).success(function (data, status, headers, config) {
rzEnvParams = data;
deferred.resolve(rzEnvParams);
_domain = rzEnvParams.domainName;
_port = rzEnvParams.port;
//etc
});
});
If I understand your question correctly, you need to do something like the following.
[HttpGet]
public object GetRzEnv()
{
string clConfig = System.Configuration.ConfigurationManager.AppSettings["ClConfig"].ToString();
string envName = System.Configuration.ConfigurationManager.AppSettings["EnvironmentName"].ToString();
string spaceName = System.Configuration.ConfigurationManager.AppSettings["SpaceName"].ToString();
string domainName = System.Configuration.ConfigurationManager.AppSettings["DomainName"].ToString();
string port = System.Configuration.ConfigurationManager.AppSettings["Port"].ToString();
var razParams = new {
clConfig=new RzEnvParameters{clConfig=clConfig},
envName=new RzEnvParameters{envName=envName},
spaceName=new RzEnvParameters{spaceName=spaceName},
domainName=new RzEnvParameters{domainName=domainName},
port=new RzEnvParameters{port=port}
};
return rzParams;
}
may be i am wrong here, but why are you creating 5 separate objects, rather than one object with all 5 properties set.
public RzEnvParameters GetRzEnv()
{
string clConfig = System.Configuration.ConfigurationManager.AppSettings["ClConfig"].ToString();
string envName = System.Configuration.ConfigurationManager.AppSettings["EnvironmentName"].ToString();
string spaceName = System.Configuration.ConfigurationManager.AppSettings["SpaceName"].ToString();
string domainName = System.Configuration.ConfigurationManager.AppSettings["DomainName"].ToString();
string port = System.Configuration.ConfigurationManager.AppSettings["Port"].ToString();
var razParams = new RzEnvParameters{clConfig=clConfig,
envName=envName,
spaceName=spaceName,
domainName=domainName,
port=port
};
return rzParams;
}
Use a JSON serializer, http://msdn.microsoft.com/en-us/library/bb412179(v=vs.110).aspx. This is the one with .NET, but there are several out there. This is a simple code snippet to just illustrate the serialization.
// your code to set your list List<RzEnvParameters>, var razParams = ...
MemoryStream stream1 = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<RzEnvParameters>));
ser.WriteObject(stream1, razParams);
stream1.Position = 0;
StreamReader sr = new StreamReader(stream1);
var jsonToReturn = sr.ReadToEnd();

Facing trouble while inserting bulk data into sql

In MVC4 , i have following code in my view :
<script>
var things = [];
function fun () {
var Quran = {
"surah": things[1].surah,
"ayah": things[1].ayah,
"verse": things[1].verse
};
things.push(Quran);
for (var n = 0; n < length; n++) {
$.ajax({
contentType: 'application/json; charset=utf-8',
method: 'GET',
url: "Gateway/DB_Rola?action=1",
data: things[n],
success: function (Data) {
var mera_obj = Data.key;
document.getElementById("Param2").value = '(' + mera_obj.Response_Code + ' , ' + mera_obj.Response_Description + ')';
},
error: function () {
alert("ERROR: can't connect to Server this time");
return false; }
});
alert("done for "+(n+1));
} // loop ends
return false;
}; // function ends
and controller method is :
public ActionResult DB_Rola(thing things)
{
string connectionString = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\PROGRAM FILES (X86)\MICROSOFT SQL SERVER\MSSQL.1\MSSQL\DATA\PEACE_QURAN.MDF;Integrated Security=True";
System.Data.SqlClient.SqlConnection connection = new SqlConnection(connectionString);
int surah = things.surah;
int ayah =things.ayah;
String verse = things.verse;
// designing parametiric_query from the parameters
string query = "insert into Ayyat_Translation_Language_old_20131209 values(null,null,#Surah,#Verse)";
SqlCommand cmd = new SqlCommand(query, connection);
connection.Open();
//setting parameters for parametric query
SqlParameter Parm1 = new SqlParameter("Surah", surah);
SqlParameter Parm2 = new SqlParameter("Ayah", ayah);
SqlParameter Parm3 = new SqlParameter("Verse", verse);
//adding parameters
cmd.Parameters.Add(Parm1);
cmd.Parameters.Add(Parm2);
cmd.Parameters.Add(Parm3);
cmd.ExecuteNonQuery();
System.IO.StreamWriter file = new System.IO.StreamWriter(#"E:\Office_Work\Peace_Quran\Peace_Quran\Files\hisaab.txt", true);
file.WriteLine(" "+things.ayah);
file.Close();
connection.Close();
return View();
}
as mentioned above in code ,there is loop in my view page that passes single object at a time which is received in above controller method .it works for small amount of data but when i send bulk .i.e. 50+ records at once, some of records are not saved in my DB. i don't know what's wrong with my DB code. please help me figure it out.

Resources