I'm really struggling with this one. I need a generic list parameter for my Get method, but it needs to be optional. I just did this:
public dynamic Get(List <long> ManufacturerIDs = null)
Unfortunately on runtime i get the error:
Optional parameter 'ManufacturerIDs' is not supported by
'FormatterParameterBinding'.
How to get a generic list as an optional parameter here?
What's the point of using an optional parameter? List<T> is a reference type and if the client doesn't supply a value it will simply be null:
public HttpResponseMessage Get(List<long> manufacturerIDs)
{
...
}
Related
I have code that builds Urls in ASP.NET MVC3 using a RouteValueDictionary and UrlHelper. The problem that I am running into is that MVC calls ToString() on the types in the dictionary. For a particular type I am using, this is not the value that I want to be in the Uri. I cannot change the ToString implementation.
I understand how to create a ModelBinder to handle the deserialization from the Uri, but not the serialization part. How and what do I register in order to control how a type is converted to the Uri parameter?
Thanks,
Erick
For a particular type I am using, this is not the value that I want to be in the Uri
Then don't use this type. Pass the value that you want directly as string in the dictionary:
rvd["key"] = "the value you want";
instead of:
rvd["key"] = new SomeType { Foo = "foo", Bar = "bar" };
The conversion between your type and its string representation should be handled elsewhere.
I'm looking at a tutorial for asp.net mvc here on the asp site: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application
There is a method in the controller that has me confused:
//
// GET: /Student/Delete/5
public ActionResult Delete(int id, bool? saveChangesError)
{
if (saveChangesError.GetValueOrDefault())
{
ViewBag.ErrorMessage = "Unable to save changes. Try again, and if the problem persists contact your system administrator.";
}
return View(db.Students.Find(id));
}
I'm seeing that a bool is created called 'saveChangesError', but in the if statement, there is a method being called on the boolean called 'GetValueOrDefault()'
What exactly is going on in this scenario? I'm assuming that GetValueOrDefault() must be a method of all boolean types? I looked this up in the .NET documentation and found this definition:
The value of the Value property if the HasValue property is true;
otherwise, the default value of the current Nullable(Of T) object. The
type of the default value is the type argument of the current
Nullable(Of T) object, and the value of the default value consists
solely of binary zeroes.
I'm having trouble connecting this definition with what is going on the the .net mvc app.
Thanks.
GetValueOrDefault() isn't part of the bool, it's part of Nullable<T>. The key here is the syntax where the bool is declared in the function header:
public ActionResult Delete(int id, bool? saveChangesError)
The question mark is a C# language construct which indicates that this isn't really a bool, but is a Nullable<bool>. Value types, of which bool is one, can't be null. But sometimes it would be useful if they could. So the Nullable<T> struct exists to serve that purpose.
GetValueOrDefault() is a method on that struct which will return the value of the bool or the default value for a bool (which is false) if no value is specified.
Look at the definition of the parameter bool? saveChangesError The '?' means the bool type is nullable. It can be True | False | Null.
Because it now has three values, You can't simply check for true | false. You must check for null as well.
GetValueOrDefault() is added to nullable types that does exactly what the method describes. If the parameter has a value, it will return that, if it doesn't it returns the default value (in this case it is false).
So, to break the if statement out, would be something like
if (saveChangesError.HasValue && saveChangesError == true)
{
//...
}
Using the method just makes it more concise.
The documentation states that GetValueOrDefault() "Retrieves the value of the current Nullable(Of T) object, or the object's default value." Nullable(Of T) in this case is saveChangesError.
If there has been an error in saving changes to the database (in this case, deleting a student), then saveChangesError.GetValueOrDefault() will return true and the if statement will process its contents.
Nullable objects all implement an overloaded method called GetValueOrDefault:
Returns the value of the nullable object if it has been assigned one, or a default value.
bool? saveChangesError
is a nullable boolean datatype. It has three possible value:
1) true
2) false
3) null
The GetValueOrDefault() will return either true or false if the value is set, or null when its not set. In the mention scenario, if the value is true
if (saveChangesError.GetValueOrDefault())
An error has occured. Hope this helps
I have and action which takes a userId parameter:
~/Users/Show?userId=1234
Everything works fine except when the userId provided is not an int or is missing.
Then it throws this exception:
Message: The parameters dictionary contains a null entry for parameter 'userId' of
non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Show(Int32,
System.Nullable`1[System.Boolean], System.String)' in 'S4U.Web.Mvc.Controllers.ProfileController'. An optional parameter must be a reference type,
a nullable type, or be declared as an optional parameter.
Parameter name: parameters
..after which the user is redirected to the error page.
How do I configure the route so the action isn't hit at all and it throws a 404 instead?
Don't use a string as suggested somewhere below. Use:
public ActionResult (int userId = 0)
{
}
That's the best practise.
You can also do:
public ActionResult (int? userId)
{
if (userId.HasValue)
{
//...
}
}
As mentioned in my comment on Ufuk Hacıoğulları's answer you should handle validation either through adding a constraint to a route, through having a nullable type if the parameter can be empty.
For the former approach if you have an appropriate constraint this means your route will not be picked up - you will need a catch all route or other error handling. For the nullable type you can test in the action whether it has a value and act accordingly.
Keeping action paramters as strong types is a pattern to aim for.
I want to create an optional parameter for an ActionResult method.
I have the following:
public ActionResult ViewReq (int id, string Req = null)
When I tried to do the following:
http://localhost/RepMedia/Controller1/ViewReq?id=34343?Req="34233"
I tried the following but got an error:
An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters
I am not sure what I am doing wrong.
The problem is with 'id'. The id must be part of the base URI:
http://localhost/RepMedia/Controller1/ViewReq/34343?Req=34233
http://localhost/RepMedia/Controller1/ViewReq?id=34343&Req=34233
Use a question sign before the first parameter - all others should be split by ampersand.
public ActionResult ViewReq (int? id, string Req)
http://localhost/RepMedia/Controller1/ViewReq?id=34343&Req=34233
You don't need make a string parameter optional, as they are reference types whose values will be null anyway if they aren't passed in by MVC. That URL would end up with a non-null "Id", but null "Req".
following function return List of records
public IList<T> GetAll()
{
return db.TabMasters.ToList<T>();
}
Error:
'System.Data.Objects.ObjectSet' does not contain a definition for 'ToList' and the best extension method overload 'System.Linq.Enumerable.ToList(System.Collections.Generic.IEnumerable)' has some invalid arguments
I imagine TabMasters is a strongly typed collection and therefore cannot return a list of a generic type. Have you tried db.TabMasters.ToList() instead?
The correct syntax is:
db.TabMasters.Cast<T>().ToList()
Documentation:
IEnumerable<TResult> Enumerable.Cast<TResult>(this IEnumerable source)
List<TSource> Enumerable.ToList<TSource>(this IEnumerable<TSource> source)
If you don't want to use the LINQ extension, List<T> has a public constructor that accepts a single IEnumerable<T> argument
IList<T> is the Interface that is used by List<T> and several other similar containers. You can't return an Interface itself - you have to return an object that implements IList<T>. Though I don't know exactly what your situation is, the best choice is most likely List<T>.
Also, you have a problem with the generic Type T. If you want the method to be generic, then you have to cast all the values in db.TabMasters to Type T. This gets tricky because you'll have to limit the possible Types used for T to prevent Exceptions caused by an invalid cast (see here). If you only need to return one type, then you should define that as the return type instead of using T. For example, lets say that all the values in db.TabMasters are string. Then you'd use:
public IList<string> GetAll()
{
return db.TabMasters.ToList();
}
If you really need the method to be generic, then you have to cast the values in db.TabMasters to the type you want to return:
public IList<T> GetAll<T>()
{
return db.TabMasters.Cast<T>().ToList();
}
Note that if the object type stored in db.TabMasters can't be cast to T, the method will throw an InvalidCastException.
Happy Coding!
have you looked here http://msdn.microsoft.com/en-us/library/dd412719.aspx
there appears to be a couple of methods that may be of use AsEnumerable and GetList seem like possibilities