Question about use of new { } - c#

I am currently working my way through the Apress ASP.NET MVC2 book, and I am a little bit confused as to the user of new { returnUrl } in the following code:
public RedirectToRouteResult RemoveFromCart(Cart cart, int productID, string returnUrl)
{
Product product = productsRepository.Products.FirstOrDefault(p => p.ProductID == productID);
cart.RemoveLine(product);
return RedirectToAction("Index", new { returnUrl });
}
Is it something to do with creating a new string, rather than simply passing a reference to the parameter passed in?

It's creating an anonymous type with a property returnUrl which also has the value of returnUrl. So it's like this:
var anon = new { returnUrl = returnUrl };
return RedirectToAction("Index", anon);
Using a name from the expression to determine the name of the property in an anonymous type is called a projection initializer.
Does that help to explain it to you at all? If not, you may want to revise anonymous types in general. They were introduced in C# 3, mostly for LINQ.

This is an anonymous type: http://msdn.microsoft.com/en-us/library/bb397696.aspx

That is an anonymous object. The property in the case above would create a new object with the string property 'returnUrl'.
In this context, it is specifying a url for the ActionResult to redirect the browser to.

That syntax creates an anonymous type. They're created on the fly as needed. In your example it creates a new object with one property and then passes it to the action as a parameter.

Related

Use a custom name for a request parameter

After changing job I'm learning C# and Entity Framework; previously I worked with Java + Spring.
The question is: Is there an equivalent way to write this Java code into C# code?
public ModelAndView showUser(#RequestParam("k") String userName)
With Spring and the annotation RequestParam I could convert a request parameter named k into a more friendly and readable parameter named userName; so now, I expect a C# code like this:
public ActionResult showUser([RequestParam("k")] string userName)
Is this possible in some way?
I am not sure if you can do the same as in Java+spring but in C# MVC you can use Modal to transfer data from and to.
There you don't have to get the each and every request value separately you just have to mention your Modal Name in the parameter parentheses.
Answering your question, if tried to assign the value from the parameter it will throw
Default parameter for name must be a compile-time constant
public ActionResult Contact(string name = Request.Form["param1"])
{
return View();
}
Above code throws an error.
So to work with that used
public ActionResult Contact()
{
string name = Request.Form["param1"];
return View();
}
This will work.
I recommend you to use Modal and data annotations concept for the passing of data.
You can use that:
[HttpGet()]
public IActionResult showUser([FromQuery(Name = "k")] string userName)
{...}

How do I create a new object using dependency injection

At the moment I have a form where users create a new object. This is then passed to the controller as JSON.
How can I create a new object from this JSON to insert into the DB that I have, without doing
var x = new CustomObject {
ExampleField = JSONProperty,
ExampleField2 = JSONProperty2
};
repo.Create(x);
In general, you need something like this:
[HttPost]
public ActionResult CreateCustomer(string json)
{
var customer = JsonConvert.DeserializeObject<Customer>(json);
repo.Create(customer);
return View(customer);
}
An action method that takes as a parameter your json.
Use the JsonConvert.DeserializeObject method (I have supposed that you use
the Newtonsoft.Json library, the most used JSON framework for .NET.
The customer hew is an hypothetical object. You can follow the same approach for any custom object.
Last but not least this method return a View. This is optional, you can define another return type and return whatever you want.

kinda curious with dynamic type in mvc view

Cracking my head with MVC here.
I've written my model as:
public class AboutModel
{
public string AboutText { get; set; }
}
and my controller as:
public ActionResult About()
{
var model = new AboutModel { AboutText = "We build better software."};
return View(model);
}
and changed the new line to:
AboutModel model = new AboutModel { AboutText = "We build better software."}
and finally to:
dynamic model = new AboutModel { AboutText = "We build better software."}
seems all works perfectly well with my View:
#model MvcApp.Models.AboutModel
<p>#if (Model != null)
{
#Model.AboutText
}</p>
Any difference on my 3 model Initializations?
var model = new AboutModel is an implicitly typed variable, in that you don't have to specify in advance what type your variable is, the compiler can infer it by what comes after the =. (in this case AboutModel)
If you use an implicityly typed variable, you have to give it a value, for example:
var model = new AboutModel;
will compile, but
var model;
won't.
AboutModel model = new AboutModel is specifying the type in the variable declaration, which you don't really need to do if you're giving it a value in the same line. If you give it a type on declaration, you don't need to give it a value. For example:
AboutModel model;
will compile.
The dynamic keyword means it won't be type-checked at compile time, which won't make any difference in this case either.
No, the runtime type in all three cases is MvcApp.Models.AboutModel.
In the first two cases you are passing the type as is and in the last case, passing it as dynamic, which will be attempted to be cast to the type for the view as defined by the #model directive.
I would stick to one of strong type initializations for clarity, unless you need "dynamicity" (in which case you would want to set the #model type to dynamic too).

Action method expected parameter named Id and nothing otherwise

The Error
The parameters dictionary contains a null entry for parameter 'UserId'
of non-nullable type 'System.Int64' for method
'System.Web.Mvc.ActionResult Predict(Int64)' in
'sportingbiz.Controllers.PredictionController'. An optional parameter
must be a reference type, a nullable type, or be declared as an
optional parameter. Parameter name: parameters
This does not work. Throws the error mentioned above
http://mysite/User/Profile/15
This works
http://mysite/User/Profile/?UserID=15
The Controller Action
public ActionResult Profile(long UserID)
{
}
When I changed the parameter name to Id it works. I think it's because Id was specified in the route collection (Global.asax). Is it possible to tell MVC that UserId should map to Id without changing it in the Global.asax
The only way to accomplish this (without getting into custom ModelBinders, which gets really hairy) is to:
make the parameter nullable
use the RouteData collection to set the property after-the-fact.
public ActionResult Profile(long? UserID)
{
UserID = UserID ?? long.Parse((string)RouteData.Values["id"]);
}
I would always make the id param on a controller something generic like Id, then you dont have to create lots of routes to match the different id types.
If you aren't using a string which is nullable for your id, you can provide a default value such as long id = 0 and handle the zero value as being the default starting sequence.
For example, in a paging method, you can set it to zero so you dont need any params on the first page, but passing it thereafter will request that page number etc etc
Si
I think the code already posted should work so I tested my version and it worked:
public ActionResult Profile(long? UserID)
{
if (UserID.HasValue)
{
}
else if (this.RouteData.Values["id"] != null)
{
long tempValue = 0;
if (long.TryParse(this.RouteData.Values["id"].ToString(), out tempValue))
{
UserID = tempValue;
}
}
return View();
}
Hope it helps.

ASP.NET MVC posted entity not mapping to LINQ model

I have a page which is strongly typed to my "User" class. When it is loaded, I load it by Id from the database and pass it to the view.
When the edit form is posted, the object gets posted to the controller method fine, with some other parameters. The object has its properties filled from the form, but it's ID (which obviously isnt on the form) doesnt get posted.
Even when I manually set it to an ID in code and try and save my context, nothing happens on the database.
Here is a rough view of the code with stuff taken out for brevity.
public ActionResult MyProfile()
{
ViewData["Countries"] = new SelectList(userService.GetCountries(), "id", "name");
return View(userService.GetById(CurrentUser.id));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyProfile(MSD_AIDS_Images_Data.LINQRepositories.User user, string password2)
{
user.id = CurrentUser.id; //user id isn't posted, so need to reassign it
userService.SaveChanges();
}
I have written code like this a dozen times and it has worked, what is going wrong?
EDIT
When I debug the user object, it's PropertyChanged and PropertyChanging properties are set to NULL
The User object coming into the MyProfile method is not associated with a LINQ context. You need to use explicit binding using UpdateModel, e.g.:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyProfile(int id, string password2)
{
MSD_AIDS_Images_Data.LINQRepositories.User user = <LINQ query to load user by id>;
UpdateModel(user); // updates the model with form values
userService.SaveChanges();
}
Note you can implement a custom model binder that does this before calling your controller method so you can accept User as a parameter, but I'm assuming you haven't done this.
I fixed the Model binding issues by using an Update Model overload which allows you to specifiy which properties in the model you wish to update:
string[] includeProperties = {"password", "firstname", "lastname", "email", "affiliation", "countryId"};
UpdateModel(user, includeProperties);

Categories

Resources