Question about Out and Return? - c#

In this code (from the WCF REST starterkit - preview2):
protected override SampleItem OnAddItem(SampleItem initialValue, out string id)
{
// TODO: Change the sample implementation here
id = Guid.NewGuid().ToString();
this.items.Add(id, initialValue);
return initialValue;
}
Am I getting back id as String, or the initialValue as SampleItem?
Edit:
Looks like I get both back, so what would a simple example of the method call look like assigned to a couple of variables?

You will get back id in the string that you pass as a parameter to the method. Also, the method will return the SampleItem instance.
SampleItem myItem = new SampleItem();
string newId = string.Empty;
myItem = OnAddItem(myItem, out newId);
// now myItem will be assigned with SampleItem returned from the
// OnAddItem method, and newId will be updated with the id assigned
// within that method

You're getting both.

You are getting back both.
You will pass in a string variable for ID and that will be returned to you via the 'out' modifier. The function will also return the SampleItem instance initialValue that you passed in.

You are getting back both. An out parameter is just an additional way to to return a value offered by some programming languages.

Related

How to pass the parameter to a method when calling in MVC5?

I have a method defined like this:
public ActionResult MatchedBusinesses(List<Business> businesses)
{
if (businesses != null)
{
return View(businesses);
}
return View("NoMatchFound");
}
Then, in my other method I have something similar to this one:
var list = results.AsEnumerable().OrderBy(b => Math.Abs(Convert.ToInt32(temp) - Convert.ToInt32(b.Zip))).Take(5).ToList();
return RedirectToAction("MatchedBusinesses", "Home", list);
The point is that, for the list variable I get the 5 entries that I select using the query. But, then I want to pass that result to my other method, which will be used in other method's view. The problem is, when I call the other method, the businesses parameter is always null. How can I solve the problem? Clearly, I'm not passing the parameter to my MatchedBusinesses method correctly. Any idea, how to solve the problem?
You are using the overload of RedirectToAction where the 3rd parameter is object routeValues. Internally the method uses reflection to build the route values based on the names and the ToString() values of the objects properties.
It works only for properties that are value types, but for properties that are complex types, including collections, it will not bind because (in your case) the value is a string "List<YourAssembly.Business>" and a string cannot be bound to a collection.
You need to persist the collection before redirecting (e.g. database, session, TempData) and then retrieve the collection in the action result.
For example
var list = results.AsEnumerable()....
TempData["results"] = list;
return RedirectToAction("MatchedBusinesses", "Home");
public ActionResult MatchedBusinesses()
{
List<Business> businesses = (List<Business>)TempData["results"];
}
but use TempData with caution (if the user refreshes the browser, the data will be lost). Its better to persist the information to the database with some key, and then pass the key as a route parameter to the MatchedBusinesses() method so that you can retrieve the data from the database.
Edit
What you're trying to do doesn't make much sense. You cannot, and should not, attempt to send large and/or complex objects, like a List, using Route. Instead you should use POST, or follow Stephen Muecke's suggestion in using TempData
However, here's how you can correctly send simple values using RouteValue
You pass parameters by using
return RedirectToAction("ActionName", "ControllerName",
new { paramName = paramValue });
Or if the target Action it's in the same controller
return RedirectToAction("ActionName", new { paramName = paramValue });
The parameter name, is optional. But using
return RedirectToAction("ActionName", new { paramName = paramValue });
Implies that the target action accepts a parameter with the name paramValue.
Here are all the overloads for RedirectToAction
http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.redirecttoaction%28v=vs.118%29.aspx
Try wrapping your parameter in your return statement in a blank object variable like so:
return RedirectToAction("MatchedBusinesses", "Home", new { businesses = list });
All of the route values for an action have to be one parameter, so it's passed as an object, and then split into the various parameters of the receiving action. Even if you have only one param, it's still looking for an object to split.

Why in this C# .NET controller method do I have this signature?

I am pretty new to C# .NET and I have the following doubt.
On a page on which I am working on I found the following link:
<a class="ui-btn-inline ui-btn ui-icon-delete ui-btn-icon-notext ui-corner-all" href="#Url.Action("Delete", "Groups", new { id = item.gruppoId })">Delete</a>
This link call a Delete() method on a GroupsController class.
Ok, this is this method:
public ActionResult Delete(int id = 0)
{
.......................
.......................
.......................
DO SOME STUFF
.......................
.......................
.......................
return View(model);
}
My doubt is related to the signature of this method: why is the parameter int id = 0 ?
What does the = 0 mean? To begin with I thought that this was a simple initialization and that it change the it value to 0 but using the debbugger I discovered that it don't change the id value. So what it exactly do?
It's called an optional parameter. It means you can call the method with no argument, like this:
Delete();
If you do that, the value of the id parameter in the function will be 0.
You're right in saying that the = 0 sets the value of the id parameter.
But it's important to note that it only does so when you do not pass that parameter.
Take for example:
public void SaySomething( var something = "Hello" )
{
Console.WriteLine( something );
}
//...
SaySomething();
SaySomething("I am sleeping.");
The first call to the function does not pass a parameter. Therefore, the default value "Hello" is used to write to the console.
The second call already sets a value for the parameter, so it does not get overwritten by the default value you set up. "I am sleeping." will be printed in this case.

Upcasting an IEnumerable<object> in controller?

I'm using a repository for my models like this
public IEnumerable<object> GetDetailList(int userId, int page, int rp, string sortname, string sortorder, ref int num, ref int numpg)
{
var details = (from access in context.erp_sec_companyaccesses
join company in context.erp_maint_companies on Convert.ToInt32(access.company_id) equals company.company_id
where access.user_id == userId
select new
{
pkey = access.company_access_id,
company_access_id = access.company_access_id,
company_code = company.company_code,
company_name = company.company_name,
company_id = company.company_id
});
num = details.Count();
numpg = (int)Math.Ceiling((float)(num / rp));
details = details.OrderBy(sortname+" "+sortorder).Skip(page * rp).Take(rp);
return details;
}
But I'm struggling to upcast the IEnumerable<object> returned to the controller. Is there any alternative than this ?
Update : I give up up-casting, I'll send a typed object instead of anonymous, thanks everybody
You should not be passing around anonymous objects. I have tried doing it yesterday and did not find an easy solution. So the best thing to do is create another class for your data.
Here is the answer from Skeet: Why should anonymous types cannot be passed around methods?
I'm guessing that you probably want to create a concrete type e.g. Details and return an IEnumerable<Details> from your function rather than an IEnumerable<object>.
I'm assuming this because it appears you probably want to access the fields of your anonymous type created inside the function elsewhere in your code.
Why not use Generics and pass the Object type you want to your method and returning this?

c# get attributes from object

I'm a bit new to C# and I got this script that gets a record from a mssql database. There it converts the key to an object.
Its:
Object obj = result[i];
When I enable a breakpoint on the line after the declaration I see the data that is inside the object. Now I need to access the attribute with the data but because Im a bit new to C# I dont know how to do that.
Lets say the attribute is called: name
I made a new class of my own also with the attribute name.
When I try to get the name of the key to my object with:
myObject.Name = (string) obj.Name;
The IDE already gives an error that the attribute in the obj isnt available.
How can I access the name attribute of the object to get it to my own object?
Thanks!
So result[i] is an instance of your class (which I'll call Foo for convenience)? Then you can say
Foo obj = result[i];
myObject.Name = obj.Name;
or
Object obj = result[i];
myObject.Name = ((Foo)obj).Name;
You need to cast your object to proper type. E.g. if your object is:
class MyObject
{
public string Name { get; set; }
}
than you need to cast it like:
MyObject obj = (MyObject)result[i];
you're trying to access an attribute of the Object class, and it has no attributes. You either have to cast your obj to the class that you created, the one that has the Name attribute, or (more simply), when reading the database read it directly into an instance of your class, something like:
MyClass obj = result[i]
What data is present in result[i]? Is it just a string from a field in the record in the database? (That is, is result a DataRow?) As it stands, you're placing it inside of just an Object which doesn't know much about it. Basically, you're "boxing" it and removing knowledge of the object's data from the compiler.
If result[i] is just a string, try something like:
myObject.Name = System.Convert.ToString(result[i]);
Now, this is fairly beginner in that there are other considerations to be made here. If result[i] is ever null then this will throw an exception, etc. But while you're learning this should get the data you're looking for.

How do I set arbitrary number of properties on generic object?

I want to be able to call a method that creates an object and sets properties of the object based on the parameters passed into the method. The number of parameters is arbitrary, but the catch is I don't want to use strings. I want to use the actual properties sort of like you do in lambda expressions.
I want to be able to call the method with something that might look like this:
controller.Create<Person>(f=>{f.Name = 'John', f.Age = 30})
or something along those lines where I use the actual property reference (f.Name) instead of a string representation of the property.
Another stipulation is that I don't want any work to be done before the method call. I'm writing this in a library, so I don't want the user to have to do anything except make the call and get back an object with the properties set to the values passed in.
You can do something like:
controller.Create<Person>(f => { f.Name = 'John'; f.Age = 30; })
The create method signature will be:
public T Create<T>(Action<T> propertySetter) where T : class {
T value = ...;
propertySetter(value);
return value;
}
where T : class is not strictly required here but if T is a value type, the modifications to its properties would be lost.

Categories

Resources