WebMethod with OUT parameters, then calling method in javascript - c#

I am Calling an ASP.NET C# Method (Web Method) Using JavaScript.
C#:
[WebMethod]
public static List<Employee> GetEmployeeList(int DeptID,out int TotalRecordsCount)
{
<Employee> obj = new List<Employee>();
//obj = Geting reocrds from Database
TotalRecordsCount = obj.Count();
return obj;
}
Javascript:
function BindList(){
var DeptID = 10;
var TotalRecordsCount = 0;
PageMethods.GetEmployeeList(DeptID,TotalRecordsCount,onsuccess);
}
Now I am getting errors, while calling above js method. Please suggest me where I done mistake.
My main aim is that, Instead of returning single list, Can I add 2 or more different lists ?
Thanks in adv.

Out methods should contain the out key word when it is called like
PageMethods.GetEmployeeList(DeptID,out TotalRecordsCount, onsuccess);
But out is not a keyword in js. So I don't know if it is possible (I would be surprised). Why not return the out parameter as part of the result. So instead of just a list, a list with another value. Another thing that is unusual in your code is that you are trying to set the out parameter before calling the method.
I have never tried using an out when calling the method in Js and its probably not very good design even if it is allowed.
Also see
Is it unusual for a web service call to have an "out" parameter?

Related

Getting value from one action method to other inside same controller

I have two action methods inside a controller. With the help of first action method, I am fetching the required data from database and I need to get this fetched data inside the second action method. I need to achieve this without passing any parameter to the second method. I don’t know how to do this as I am new to MVC.
Method 1:
public ActionResult GetData(HttpPostedFileBase file)
{
string folderPath = Server.MapPath(ConfigurationManager.AppSettings["BackupPath"]);
List<string> invalidRecords = new List<string>();
string backupFileName = FileUpload.BackupFile(file, folderPath);
invalidRecords = File.GetDataFromDB(backupFileName);
List<DataVM> lst = serviceData.GetAllData();
return View(lst);
}
Method 2:
[HttpPost]
public JsonResult GetInvalidRecords()
{
List<string> InvalidVehicleId = InvalidRecords;
return new JsonResult { Data = InvalidRecords };
}
You can use a session variable to hold the value of your 'lst' variable in your 'GetData' action:
Session["data"] = lst
Then you can retrieve it as follows and cast it to the appropriate type:
var data = (List<DataVM>)Session["data"]
https://msdn.microsoft.com/en-us/library/ms178581.aspx
You can use TempData as well
TempData["Name of Tempdata variable "]= File.GetDataFromDB(backupFileName)
and in other action you can recieve it
var getdatafromanotherAction= TempData["Name of Tempdata variable"]
If you want to call both action methods in single call, You can use
return RedirectToAction("GetInvalidRecords") in the first method. Also, you can create a class level private variable _listdata. Set it in first method , get in second method.
If you want to keep data between the 2 calls, use Tempdata.Keep and Tempdata.Peek but you need to make sure that call for second method immediately follows first method. Tempdata works between 2 requests only unless you extend its duration by using .Keep and .Peek once more.
If these two methods are to be called few calls apart, you can use session variable to keep the data.
Alternatively, you can keep the parameter of the second method call optional. So, it won't hurt other calls of the jsonresult method. Inside the method, you can check whether parameter is empty or not.

How to optimise ASP.NET MVC controller to minimise the number of database query

My controller has different methods that use the same result returned by a stored procedure called by a LINQ query,
Is there a way to create a global variable that contains the result after making only one call to the procedure ??
I tried creating a constructor but every time the variable (ListePays) is used a new query is executed
public class BUController : Controller {
private NAV_MAUIEntities db = new NAV_MAUIEntities();
public DbSet<liste_pays> ListePays;
public BUController() {
ListePays = db.liste_pays();
}
public JsonResult BillPh(string Pays) {
var x = from pays in ListePays
where pays.Pays.ToUpper() == Pays.ToUpper()
select pays.code_pays;
string CodePays = x.FirstOrDefault().ToString();
}
public JsonResult BillPh2(string Pays) {
var x = from pays in ListePays
where pays.Pays.ToUpper() == Pays.ToUpper()
select pays.code_pays;
string CodePays = x.FirstOrDefault().ToString();
}
}
If the methods are all called as part the processing of the same HTTP request, just make sure some central actor (say, the action method) calls the procedure and passes the result to each method.
public ActionResult MyAction()
{
var data = db.liste_pays();
Method1(data);
Method2(data);
return View();
}
On the other hand, if you want to share the result across HTTP requests, you can cache the result of the procedure call in a number of locations (this is not an exhaustive list):
In the ASP.NET session
In a static variable
In System.Web.Caching.Cache
Not knowing more about your specific scenario, I can't recommend one over the other. However, be aware that the two latter options will potentially share the data between users, which may or may not be what you want.
NOTE: As your code stands at the moment, the call to db.liste_pays() is inside the constructor of BUController, so it is called every time a controller is created, that is, every time a new incoming HTTP request arrives. In other words, your assumption that it is being called every time the variable is used is not entirely correct.
First of all, there is no need for a constructor into an ASP.NET MVC controller.
What you did, means that every time a user makes a call to this controller, a call will be made to the DB to retrieve all your "pays".
I assume you are using Entity Framework. And the way you use Linq is "LinqToEntities". Do not worry about your DB calls, those are managed by the entity framework.
So, now, you just have to use linq that way :
public JsonResult BillPh(string Pays)
{
string codePays = db.liste_pays.FirstOrDefault(f =>
f.Pays.ToUpper() == Pays.ToUpper())
.CodePays.ToString();
}
And the syntax for the query is called "Lambda expressions".
Good luck ;-)

Assign values in Action list?

i had a null value error in my test class
[Test]
public void when_send_the_command_it_execute_correct_command_handler()
{
//Arrange
var commandBus = new CommandBus();
ICommand commandforsend=null;
IMetaData metaDataforsend=null;
Action<ICommand, IMetaData> fakeHandler = (fakecommand, fakemetadata) =>
{
commandforsend = fakecommand;
metaDataforsend = fakemetadata;
};
commandforsend and metaDataforsend values are still null
what can happen ? help me thank you !
You are defining an Action but you are never calling it. Your code is equivalent to a separate method that assigns the values but that you don't call so the code inside the method never runs.
If you want to execute the fakeHandler you should add the following line below the declaration:
fakeHandler(aFakeCommand, aFakeMetadata);`
As you can see, this is the same as calling a regular method. You need to supply values for both parameters (fakecommand and fakemetadata).
You can find more info in the MSDN documentation.
Since your code doesn't execute fakeHandler, this behavior is OK, because you've just declared a anonymous method without executing it.

Need help to understand this piece of code in MVCContrib Grid

I'm a bit new to the concept of "Action" in C# and delegate in general.
I'm trying to study how to build a custom html component in MVC, and I chose the grid component of MVCContrib to start.
To add columns, typically we do
<%= Html.Grid(Model).Columns(column =>
{
column.For(model => model.Date).Format("{0:d}");
column.For(model => model.DayAmount);
column.For(model => model.LeaveType);
})
%>
and I see the source of Columns like the following
public IGridWithOptions<T> Columns(Action<ColumnBuilder<T>> columnBuilder)
{
var builder = new ColumnBuilder<T>();
columnBuilder(builder);
foreach (var column in builder)
{
if (column.Position == null)
{
_gridModel.Columns.Add(column);
}
else
{
_gridModel.Columns.Insert(column.Position.Value, column);
}
}
return this;
}
What I'm confused of is the Action parameter In this instance, Type is CustomBuilder, so when did the "CustomBuilder" object got instantiated?
I suppose, i can rewrite the calling statement above as
Html.Grid(Model).Columns(delegate(CustomBuilder<T> column)
{
});
or a bit more explicit as
Html.Grid(Model).Columns(new Action<CustomBuilder<T>>(delegate(CustomBuilder<T> column)
{
});
);
So are we saying, when the Action was instantiated with the "new" keyword above, the param "CustomBuilder" was instantiated as well?
Lastly, in the
"public IGridWithOptions<T> Columns(Action<ColumnBuilder<T>> columnBuilder)"
function,
the first two lines are
var builder = new ColumnBuilder<T>();
columnBuilder(builder);
What do they do? Looks like it's instantiating ColumBuilder object and pass it as a parameter to Action method columBuilder. Is this where you instantiate the parameter?
Thank you all.
It's nothing to do with action concept.
The delegates is present in .net from the beginning so you should start with the first step. Should build the wall before the roof.
Delegates
Lambda Expressions
Expression trees
But you should know about generic classes and methods, extension methods...
Got it after read this excellent article.
http://www.codeproject.com/Articles/47887/C-Delegates-Anonymous-Methods-and-Lambda-Expressio
while it's talking about Func, the concept applies to Action, which does not return any results.
Looks like the magic happens here
var builder = new ColumnBuilder();
columnBuilder(builder);
I obviously didn't understand the fact that delegate, is just a pointer to a function (anonymous or not). You still need to supply the parameter when calling it. (Duh!).
All cleared up now.
Thank you.

Calling static function via classname as a string in c#

My Problem
I have a Problem which i can not solve my self. I dont want to use so much code, because i have multiple Classes which extend another class (in my case its called "Data").
I have a log file, where each Data Group is beginning with a specific Group Name, for example "MitarbeiterSet". The abstract Data-Class is used to prefent to much code, where I implemented variables like "String[] data" (for the data beeing parsed from the log file e.g. < 101 4 3 6 3 30 80 2 0 0 1 300 >) or "static String parseInduction", which is used to determin, if this Class is the right one to create Objects from.
I have another Class, called ParseMonitor, which creates the StreamReader to parse the log-file. So if the right Class is found, i induct the setDataArray(StreamReader sr) function from the right Class, to parse the Data Array. (At this point i have to tell you, that i need those different Classes, because i need to upload them to a sql server specificly.)
This static function creates an object of it self and uses the parseLine(String line) Function to fill the object with data from the given line.
WHAT I NEED.
I want to call the static function of any class, just by having the name of this class. So i dont have to use that much code and be able to add more classes.
Later on i want to call every class and use the uploadToServer() to Upload it to the server.
Is this possible?
Since your static method is creating an instance of its class anyway, I suggest a different approach:
Create an interface that all classes that contain ParseLine can implement. (Change out the return type for the correct one):
public interface IParseLine
{
string ParseLine(string line);
}
Have all of the classes that contain ParseLine() implement IParseLine.
Create an instance of the class, cast it to an IParseLine, and execute the method:
IParseLine pl = Activator.CreateInstance(Type.GetType(className)) as IParseLine;
if (pl != null)
{
string parsedString = pl.ParseLine(line);
// ...
}
Edit From comments:
I want to create a while loop, which can be stated as followed:
while{!sr.EndofStream){ line = sr.ReadLine(); for(int i = 0; i <
classNames.length; i++){ if(line.Contains(classNames[i].MYINDICATOR){
CALL classNames[i] STATIC METHOD TO PARSE THE FOLLOWING LINES AND
CREATE DATA Objects of its Class } }
I didn't test this, but you can change the code to something like this (caching the reflection required to get MYINDICATOR):
IList<KeyValuePair<string, Type>> typeIndicators = classNames.Select(x => {
Type t = Type.GetType(x);
string indicator = (string)t.GetField("MYINDICATOR", BindingFlags.Public | BindingFlags.Static).GetValue(null);
return new KeyValuePair(indicator, t);
});
while (!sr.EndOfStream)
{
line = sr.ReadLine();
foreach (var types in typeIndicators)
{
if (line.Contains(types.Key))
{
IParseLine pl = Activator.CreateInstance(types.Value) as IParseLine;
if (pl != null)
{
string parsedString = pl.ParseLine(line);
}
}
}
}
I want to call the static function of any class, just by having the name of this class.
Well, you can use Type.GetType(className) to get a Type (note that the name needs to at least be fully qualified including the namespace, and may also need the assembly name depending on your exact scenario), then Type.GetMethod to get a MethodInfo. Finally, call MethodBase.Invoke to invoke the method.
If you could use typeof(Foo) instead of using a string, it would make the code simpler and more robust.
(Side-note: if your methods are really called parseLine, parseInduction, setDataArray etc, you should consider renaming them to follow .NET naming conventions :)
I think I see where you're coming from. In this simple exmaple below, I have a static class with a method in it (nothing amazing about that).
public static class MyStaticClass
{
public static DateTime GetTime()
{
return DateTime.Now;
}
}
If I want to invoke that method using reflection, I can just use the following code, but it does assume that the MyStaticClass class is available via a reference or inthe same project etc.
MethodInfo method = typeof(MyStaticClass).GetMethod("GetTime");
object result = method.Invoke(null, null);
if (result is DateTime)
{
Console.WriteLine(((DateTime)result).ToLongTimeString());
}
What you seem ot be asking for is a moethod of doing this when you don't have a reference to the class. In which case, try something like this:
MethodInfo method = Type.GetType("PocStaticReflect.MyStaticClass, PocStaticReflect, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null").GetMethod("GetTime");
object result = method.Invoke(null, null);
if (result is DateTime)
{
Console.WriteLine(((DateTime)result).ToLongTimeString());
}
Notice the fully qualified class name!
If you get that working, then you can simply loop though your class names and call the method you desire. Obviously, you'll probably want more error checking and more detail in the GetMethod() calls, but this shlud give you the gist of it. I've done something similar before looping though assemblies in a folder to pickup plug-ins for an application. That time, each of the classes implemented an interface to make them easier to locate, which may be helpful path to follow.
Or try this:
private static object GetResultFromStaticMethodClass(string qualifiedClassName, string method)
{
Type StaticClass = Type.GetType(qualifiedClassName);
MethodInfo methodInfo = StaticClass.GetMethod(method);
object result = methodInfo.Invoke(null, null);
return result;
}
Use:
object result = GetResultFromStaticMethodClass(
"Utilities.StringHelper,DaProject",
"ToList"
);
This call the static method ToList in the StringHelper class, in the Utilities namespace, in the DaProject project (same assembly and project name).
If you need parameters, add them in the second parameter in the methodInfo.Invoke(null, null) call

Categories

Resources