I'm new in c# and want too call the bank web service,in bank document write this:
call the BatchBillPaymentRequest method with ClientBatchBillPaymentRequestData object for input argumant :
BatchBillPaymentRequest(ClientBatchBillPaymentRequestData data)
for that purpose write this class:
class ClientBatchBillPaymentRequestData
{
public string CallbackUrl { get; set; }
public string LoginAccount { get; set; }
public int OrderId { get; set; }
public string BillId { get; set; }
public string PayId { get; set; }
public string AdditionalData { get; set; }
}
and write this code:
payment.BillService behzad=new BillService();
ClientBatchBillPaymentRequestData datas = new ClientBatchBillPaymentRequestData();
datas.BillId = "1233";
datas.CallbackUrl = "google.com";
datas.LoginAccount = "213214";
datas.OrderId = 123;
datas.PayId = "2131243";
datas.AdditionalData = "23213";
behzad.BatchBillPaymentRequest(datas);
but in this line:
behzad.BatchBillPaymentRequest(datas);
get this error:
Severity Code Description Project File Line Suppression State
Error CS1503 Argument 1: cannot convert from 'ConsoleApplication1.ClientBatchBillPaymentRequestData' to 'ConsoleApplication1.payment.ClientBatchBillPaymentRequestData' ConsoleApplication1 L:\TEMP\ConsoleApplication1\ConsoleApplication1\Program.cs 23 Active
what happen?how can i solve that problem?thanks.
VS add this class too project:
public ClientBatchBillPaymentResponseData BatchBillPaymentRequest(ClientBatchBillPaymentRequestData requestData) {
object[] results = this.Invoke("BatchBillPaymentRequest", new object[] {
requestData});
return ((ClientBatchBillPaymentResponseData)(results[0]));
}
As per Adriano Repetti's comment - when you added the web service reference Visual Studio created a class for you to use - so change this code from this
payment.BillService behzad=new BillService();
ClientBatchBillPaymentRequestData datas = new ClientBatchBillPaymentRequestData();
datas.BillId = "1233";
datas.CallbackUrl = "google.com";
datas.LoginAccount = "213214";
datas.OrderId = 123;
datas.PayId = "2131243";
datas.AdditionalData = "23213";
behzad.BatchBillPaymentRequest(datas);
to this
payment.BillService behzad=new BillService();
var datas = new ConsoleApplication1.payment.ClientBatchBillPaymentRequestData();
datas.BillId = "1233";
datas.CallbackUrl = "google.com";
datas.LoginAccount = "213214";
datas.OrderId = 123;
datas.PayId = "2131243";
datas.AdditionalData = "23213";
behzad.BatchBillPaymentRequest(datas);
You can streamline this a little by doing this instead too
payment.BillService behzad=new BillService();
var datas = new ConsoleApplication1.payment.ClientBatchBillPaymentRequestData{
BillId = "1233",
CallbackUrl = "google.com",
LoginAccount = "213214",
OrderId = 123,
PayId = "2131243",
AdditionalData = "23213"
}
behzad.BatchBillPaymentRequest(datas);
You should also remove the ClientBatchBillPaymentRequestData class you created as its surplus to requirements.
For each of the Attributes in your object instantiation, highlight it and press CTRL-Space to get autocomplete to correctly case your parameter name.
If you don't know the structure of your Webservice call you can use Wizdler for Chrome https://chrome.google.com/webstore/detail/wizdler/oebpmncolmhiapingjaagmapififiakb?hl=en to find out what the packets should be .
Once you install it, enter the WSDL URL in chrome, click the wizdler button to the right of the address bar and select the method you want to call, this will let you see the parameters (including their names and casing).
Related
My overall goal is to run a query that shows all the collections with the amount of data / counts and so on.
I found the following command/query and try to run it like this:
MongoClient client = new MongoClient(server);
var db = client.GetDatabase(database);
const string mongoQueryA = "var collectionNames = db.getCollectionNames(), stats = []; " +
"collectionNames.forEach(function(n) { stats.push(db[n].stats()); }); " +
"stats = stats.sort(function(a, b) { return b['size'] - a['size']; }); ";
var command = new JsonCommand<BsonDocument>(mongoQueryA);
var test = db.RunCommand<BsonDocument>(command);
And the code fails here. Exceptions:
JSON reader was expecting a value but found 'var'.
My understanding is that this shoul be run as command?
Running the query in Robot T works as expected. Bonus the plan was to return the data in the following format ( Based on Json from running query manualy in Robot T)
class MongoCollectionInfo
{
public string ns { get; set; }
public long size { get; set; }
public long count { get; set; }
public long avgObjSize { get; set; }
public long storageSize { get; set; }
public long nindexes { get; set; }
public long totalIndexSize { get; set; }
}
What you're trying to achieve can be done purely in C# as it looks like what you've attempted to do is send javascript to the server to be executed which is not how commands work.
To start off with we'll need to get a list of all the collections within a database inside the MongoDB instance.
var client = new MongoClient();
var db = client.GetDatabase("test");
var collectionNames = await (await db.ListCollectionNamesAsync()).ToListAsync();
once we've got the collection names (collectionNames) we can then go ask the database for the stats on that collection by issue a command.
var allCollStats = new List<BsonDocument>(collectionNames.Count);
foreach (var name in collectionNames)
{
var collStatsResult = await db.RunCommandAsync(new BsonDocumentCommand<BsonDocument>(new BsonDocument("collStats", name)));
allCollStats.Add(collStatsResult);
}
The allCollStats then will hold all the stats for the collections and we can then use it as we see fit
foreach (var collStats in allCollStats)
{
Console.WriteLine($"ns: {collStats["ns"]}, size: {collStats["size"]}");
}
// ns: test.test, size: 117
// ns: test.people, size: 5092
Also, if you wanted to use a typed result instead of a BsonDocument you can pass this in as the generic agrument to the command.
var collStatsResult = await db.RunCommandAsync(new BsonDocumentCommand<MongoCollectionInfo>(new BsonDocument("collStats", name)));
Console.WriteLine($"ns: {collStatsResult .ns}, size: {collStatsResult .size}");
I'm new in c# and write this class:
public class MANAGER
{
public string VersionName { get; set; }
public Double Value { get; set; }
}
and use this:
List<MANAGER> lstSummary = new List<MANAGER>();
MANAGER summary = new MANAGER();
summary.VersionName = "12";
summary.Value =12;
lstSummary.Add(summary);
summary.VersionName = "13";
summary.Value = 19;
lstSummary.Add(summary);
but up code just save latest class record ,means just save VersionName=13 and Value=19,How can i solve that problem?thanks.
You have to re-instantiate the summary variable like so:
MANAGER summary = new MANAGER();
summary.VersionName = "12";
summary.Value =12;
lstSummary.Add(summary);
summary = new MANAGER(); // <-- add this
summary.VersionName = "13";
summary.Value = 19;
lstSummary.Add(summary);
The problem as described in another answer is that you add the same object to the list multiple times, so you need to have a separate one. You can do it that way or don't use explicit the variable at all, since C# allows initializers. It will be pretty much the same logic, but a bit more nice and readable.
var lstSummary = new List<MANAGER>
{
new Manager
{
VersionName = "12",
Value = 12
},
new Manager
{
VersionName = "13",
Value = 19
}
}
A have a "Billing" class that's describe my finance account model in multithreading application. If i want to transfer money from one billing to another i make patchcommand that is increment one property and decrement another. What is the right way to return actual property value after patching without redundant Load-query?
Billing class
public class Billing
{
public string Id { get; set; }
public decimal Balance { get; set; }
}
My patch method
public void TransferMoney(string billingSrc, string billingDst, decimal money)
{
_ctx.DatabaseCommands.Batch(new ICommandData[]
{
new ScriptedPatchCommandData
{
Key = billingSrc,
Patch = new ScriptedPatchRequest
{
Script = #"this.Balance -= money;",
Values = {{"money", money}}
}
},
new ScriptedPatchCommandData
{
Key = billingDst,
Patch = new ScriptedPatchRequest
{
Script = #"this.Balance += money;",
Values = {{"money", money}}
}
}
});
}
You can use the output() method to send values back to the user.
Since RavenDb v3, the set of predefined JavaScript functions available in ScriptedPatchRequest has method output(message), which allows to debug your patch and print passed messages in the output. See documentation for v3.0, v3.5, v4.0.
See example below:
var balancePatch = dbSession.Advanced
.DocumentStore
.DatabaseCommands
.Patch(
billingDst /* document ID */,
new ScriptedPatchRequest
{
Script = #"this.Balance += money; output(this.Balance);",
Values = {{"money", money}}
});
// Reading the debug output
var balance = balancePatch["Debug"].Values().First().Value<decimal>();
I have a problem with my web api application. I get an internal error 500 when i try to post(save) a new user in my db.
The function bellow is the one that i use to make the client call.
public void InsertNewUser(RegisterModel pNewUser, string pEmail)
{
// Build rest uri
string lREST_Uri_Browse = string.Format(#"api/accountapi/saveuserdata"
// User data
/*pModelSerialized*/);
// Complete URI
string lREST_Uri = Helpers_API.endPoint + lREST_Uri_Browse;
var client = new HttpClient();
client.BaseAddress = new Uri(Helpers_API.endPoint);
var newUser = new Models.Models_API.Users
{
Email = pNewUser.Email,
FName = pNewUser.FName,
LName = pNewUser.LName,
Inserted = DateTime.Now,
ActiveAcc = true,
AccType = pNewUser.AccType,
BCompanyID = pNewUser.CompanyID,
PID = pNewUser.PID,
Password = pNewUser.Password,
Token = GetToken(pEmail),
ThirdParty = 0,
Gender = pNewUser.Gender,
BirthDate = pNewUser.BirthDate
};
// Add an Accept header for JSON format.
//client.DefaultRequestHeaders.Accept.Add(
// new MediaTypeWithQualityHeaderValue("application/json"));
// Create the JSON formatter.
MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
// Use the JSON formatter to create the content of the request body.
HttpContent content = new ObjectContent<Models.Models_API.Users>(newUser, jsonFormatter);
var result = client.PostAsync(lREST_Uri_Browse, content).Result;
}
This is the model
public class Users
{
public int BrokerID { get; set; }
public DateTime Inserted { get; set; }
public string Email { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public bool ActiveAcc { get; set; }
public int BCompanyID { get; set; }
public int PID { get; set; }
public int AccType { get; set; }
public string Password { get; set; }
public string Token { get; set; }
public int Gender { get; set; }
public DateTime BirthDate { get; set; }
public int ThirdParty { get; set; }
}
And bellow is the POST in APIController:
public HttpResponseMessage SaveUserData(Users pNewUser)
{
bool createUser = false;
// First check for provided email in DB
Users existingUser = asigCtx.Users.Where(u => u.Email == pNewUser.Email).SingleOrDefault();
if (existingUser == null)
createUser = true;
else if (existingUser.ActiveAcc)
createUser = true;
if (createUser)
{
using (asigCtx = new AsigPrimeContext())
{
Users user = new Users()
{
Email = pNewUser.Email,
FName = pNewUser.FName,
LName = pNewUser.LName,
Inserted = DateTime.Now,
ActiveAcc = true,
AccType = pNewUser.AccType,
BCompanyID = pNewUser.BCompanyID,
PID = pNewUser.PID,
Password = pNewUser.Password,
Token = pNewUser.Token,
ThirdParty = 0,
Gender = pNewUser.Gender,
BirthDate = pNewUser.BirthDate,
};
asigCtx.Users.Add(user);
asigCtx.SaveChanges();
}
}
var response = Request.CreateResponse<Users>(HttpStatusCode.Created, pNewUser);
return response;
}
Can anyone give me piece of advice with this code because i'm new in this and i just want to do it wright. TNX
You have an error in your code. A 500 error indicates that your code contains an unhandled exception that killed its worker process.
Change your web.config file so that your application outputs the full error message.
A few things I would check/try to get to the bottom of the issue:
Is the code above exactly the same as in your application or have you changed anything (even if only to make it simpler)?
Is the Users object used in SaveUserData controller method definitely from the same assembly as the one that you are posting from the InsertNewUser method?
Is the Users object complete on the listing (e.g. does it have any constructors)?
Have you tried executing the request to the endpoint through fiddler? This way you take any potential bugs in the client call out of the equation to see if the controller method on its own works.
I've noticed this line:
string lREST_Uri_Browse = string.Format(#"api/accountapi/saveuserdata"
// User data
/*pModelSerialized*/);
Are you formatting the url and passing any params to it? If so, what are the params and what does your WebApi route look like?
That should be enough for a start - let me know how you get on.
BTW: Two things that strike me in your code (unrelated to the question):
It's very confusing to have a class called 'Users' representing a single user. If it's you're code I'd advise to change that to singular.
the properties on the Users object are using abbreviations - I don't think it's that expensive to spell them out and I can guarantee you that anyone new to this code will be grateful if you put a full name rather than a mysterious BCompanyID, or less mysterious but still hard to read (and write for that matter) FName
I had the same problem a few weeks ago. After doing a few tests, I've realized that my WebApi application was using DataContractJsonSerializer by default, instead of Newtonsoft. To fix it, you can change the default serializer on your server to NewtonSoft or to use DatacontractJsonSerializer to serialize your object and pass it to HttpWebRequest.
I would use jQuery to post some Json to the same URL ($.post(#"api/accountapi/saveuserdata", { Email: "e#example.com", FName = "Vlad" ... })), thus eliminating InsertNewUser from the equation. If you still get a null pNewUser parameter in SaveNewuser, then I would look at your API's route configuration to make sure the server expects SaveUserData(Users). If you get a non-null pNewUser from jQuery, then I would look closer at the output from InsertNewUser. If I had to bet, I would put my money on the routing configuration.
it seemed that i had an error with the LINQ code
Users existingUser = asigCtx.Users.Where(u => u.Email == pNewUser.Email).SingleOrDefault();
After i solved this the request was ok.
Tnx for the help :) Appreciate.
I'm working on a WCF RESTful web service hosted in IIS. I'm currently working on a fairly simple post request, sending the following XML to the endpoint:
<StockListRequestData xmlns="http://myWebService.com/endpoint">
<UserID>2750</UserID>
<StockDatabase>stockLeekRoadVenue</StockDatabase>
<InStockOnly>true</InStockOnly>
</StockListRequestData>
This XML matches a DataContract on my web service:
[DataContract(Namespace = "http://myWebService.com/endpoint")]
public class StockListRequestData
{
[DataMember]
public string UserID { get; set; }
[DataMember]
public string StockDatabase { get; set; }
[DataMember]
public bool InStockOnly { get; set; }
}
The problem is the <InStockOnly>true</InStockOnly> element, when I set this to true or false it will always be interpreted as false...
Here is the code that handles the request:
public StockListResponseData GetListOfProducts(StockListRequestData requestData)
{
var stockList = new StockList(requestData.InStockOnly, requestData.StockDatabase);
StockListResponseData response;
if (stockList.Any())
{
var stockArray = new Stock[stockList.Count];
var i = 0;
foreach (var s in stockList)
{
stockArray[i] = s;
i++;
}
response = new StockListResponseData
{
StockList = stockArray,
WasSuccessful = true,
};
return response;
}
response = new StockListResponseData
{
WasSuccessful = false
};
return response;
}
The StockList class:
[DataContract]
public class StockList : List<Stock>
{
public StockList(bool inStockOnly, string stockDb)
{
if (inStockOnly)
{
// Get only products that are in stock
var conn = AndyServerDatabase.ConnectToStockMovementByDb(stockDb);
conn.Open();
// Compile SQL query
var q = new SqlCommand(null, conn) { CommandText = "SELECT StockID, Name, PerBox FROM Stock WHERE InStock = 1;" };
// Execute query
var rdr = q.ExecuteReader();
// Check that the output isn't null
if (rdr.HasRows)
{
while(rdr.Read())
{
var id = Convert.ToInt32(rdr[0]);
var name = rdr[1].ToString();
var perBox = Convert.ToInt32(rdr[2]);
Add(new Stock(id, name, perBox));
}
conn.Close();
}
// Output is null
conn.Close();
}
else
{
// Get all products
// Get only products that are in stock
var conn = AndyServerDatabase.ConnectToStockMovementByDb(stockDb);
conn.Open();
// Compile SQL query
var q = new SqlCommand(null, conn) { CommandText = "SELECT StockID, Name, PerBox FROM Stock;" };
q.Prepare();
// Execute query
var rdr = q.ExecuteReader();
// Check that the output isn't null
if (rdr.HasRows)
{
while (rdr.Read())
{
var id = Convert.ToInt32(rdr[0]);
var name = rdr[1].ToString();
var perBox = Convert.ToInt32(rdr[2]);
Add(new Stock(id, name, perBox));
}
conn.Close();
}
// Output is null
conn.Close();
}
// Add();
}
}
Resultant XML:
<StockListResponseData xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<StockList xmlns:a="http://schemas.datacontract.org/2004/07/SMS">
<a:Stock>
<a:Id>1</a:Id>
<a:Name>Smirnoff Vodka (70cl)</a:Name>
<a:PerBox>6</a:PerBox>
<a:Quantity>0</a:Quantity>
<a:Remains>0</a:Remains>
</a:Stock>
<a:Stock>
<a:Id>2</a:Id>
<a:Name>Jagermeister (70cl)</a:Name>
<a:PerBox>6</a:PerBox>
<a:Quantity>0</a:Quantity>
<a:Remains>0</a:Remains>
</a:Stock>
</StockList>
<WasSuccessful>true</WasSuccessful>
I hope this is enough to go on, I've been stumped for ages and just can't figure out why it's behaving in such a way.. if you need additional code I haven't included please feel free to ask.
Many thanks,
Andy
Edit:
To add some context to show what is happening:
For example, I know that:
<a:Stock>
<a:Id>2</a:Id>
<a:Name>Jagermeister (70cl)</a:Name>
<a:PerBox>6</a:PerBox>
<a:Quantity>0</a:Quantity>
<a:Remains>0</a:Remains>
</a:Stock>
Has its InStock row set to 0, which means that this should not be displayed in the resultant XML if I pass in true.
I have changed the StockList constructors if(inStockOnly) to if(!inStockOnly) - I then pass in <InStockOnly>true</InStockOnly> - when it gets to the StockList constructor it is then inverted and the correct data is displayed - so it must be reading it as false by the time it gets to this if statement.
If I pass in <InStockOnly>false</InStockOnly> it still displays the "correct" results, therefore it is reading it as false until it gets to the inversion!
Likewise if I leave it as if(inStockOnly) and pass in <InStockOnly>false</InStockOnly> it displays the data for false!
I have also added requestData.InStockOnly to the StockListResponseData DataContract and there it displays it outputs the value of requestData.InStockOnly as false.
Your discovery has led me to the explanation, and someone with a problem similar to yours:
WCF DataContract DataMember order?
http://msdn.microsoft.com/en-us/library/ms729813.aspx
Next in order are the current type’s data members that do not have the Order property of the DataMemberAttribute attribute set, in alphabetical order.
When the order of data members is not explicitly specified, their serialization order is alphabetical. That explains why InStockOnly worked when it was moved to the top, because it's first alphabetically. On the other hand, why StockDatabase worked is a bit of a mystery, because that's after UserId alphabetically (does AndyServerDatabase.ConnectToStockMovementByDb() use a default value if StockDb is null?).
For the sake of argument, if for whatever reason you wanted to keep the order you have there, you could do this:
[DataContract(Namespace = "http://myWebService.com/endpoint")]
public class StockListRequestData
{
[DataMember(Order = 0)]
public string UserID { get; set; }
[DataMember(Order = 1)]
public string StockDatabase { get; set; }
[DataMember(Order = 2)]
public bool InStockOnly { get; set; }
}
In fact, it's probably a good practice to explicitly indicate the order, so adding new properties later doesn't break anything.
I tried the suggestion above and it still didn't work! Kept searching and found another solution, actually setting the 'Specified' property to true:
PackageImagesPayload payload = new PackageImagesPayload();
payload.UsesSplitBy = usesSplitBy;
payload.UsesSplitBySpecified = true;