How do I save Entity with WCF - asp.net-mvc

What is the best practice for saving an entity in wcf. I am calling my service through asp.net mvc site.
I have declared my context in the .svc file, as I would with normal winforms development.
public ScoolEntities database = new ScoolEntities();
Then I am using the following to get the data by id.
public student GetStudentsById(int id)
{
var q = (from mystudent in database.students where mystudent.id == id select mystudent);
return q.ToList()[0];
}
Then Finally I have a public save method
public bool savechanges()
{
database.SaveChanges();
return true;
}
Then in my controller I have
public ActionResult Edit(int id=0)
{
return View(obj.GetStudentsById(id));
}
[HttpPost]
public ActionResult Edit(MvcApplication1.ServiceReference1.student student)
{
if (ModelState.IsValid)
obj.savechanges();
return RedirectToAction("Index");
}
return View();
}
But it does not appear to save the changes and also what do I need to place in the return view I would have thought I call the GetStudents again but it does not appear to work?.

You need to add the Entity to the Context and need to call SaveChanges method.
database.Students.Add(student);
database.SaveChanges();

Related

Pass data between controllers asp.net mvc 3

I need to know how to pass data between two controllers in asp.net mvc 3
i have two controllers
public class controller1:Controller
{
}
public class controller2:Controller
{
}
how to pass data from controller1 to controller2?
One way is to pass using TempData:
public class controller1Controller:Controller
{
public ActionResult Index()
{
TempData["SomeKey"] = "Some Value";
return RedirectToAction("Index","controller2");
}
}
public class controller2Controller:Controller
{
public ActionResult Index()
{
string value = TempData["SomeKey"] as String;
return View();
}
}
One thing to remember is TempData is single read, which means that once a value is read from TempData it will automatically be deleted, if the value is till needed after read and you want to persist it, you have to call TempData.Keep() and you can be more specific to persist specific key value by calling:
string value = TempData["SomeKey"] as String;
TempData.Keep("SomeKey");
Another way is to use RouteValue Dictionary:
public class controller1Controller:Controller
{
public ActionResult Index()
{
return RedirectToAction("Index","controller2",new { SomeKey = "SomeValue"});
}
}
public class controller2Controller:Controller
{
public ActionResult Index(string SomeKey)
{
return View();
}
}
I am using String in example, you can have a custom type like a model or view model object that is to be passed.
I would suggest you to read this MSDN article for more details and understanding of passing data in mvc application.
You should also read What is ViewData, ViewBag and TempData? – MVC options for passing data between current and subsequent request and When to use ViewBag, ViewData, or TempData in ASP.NET MVC 3 applications
You can use RouteValue Dictionary here as :-
public class controller1Controller:Controller
{
public ActionResult Index()
{
return RedirectToAction("Index","controller2",new { UserName= "Username"}); <----Just pass username value here
}
}
public class controller2Controller:Controller
{
public ActionResult Index(string UserName) <-----get username value here
{
return View();
}
}

How to share an object between functions of the same controller?

I work with asp MVC 4. I have a single controller and I want to share the same object between his functions. I thought about a data member but it doesn't work. Here is my code :
public class MyController : Controller
{
public MyObject obj;
public ActionResult Index()
{
obj = new MyObject();
this.obj.GetData(); // Fill my object
return View();
}
public ActionResult MyFunction()
{
Console.Write(this.obj); // Always null
return View();
}
}
Is it possible to keep this object between functions ? I used to create TempData ou ViewBags for sharing data but I'm not sure if it's the right way to manage big objects.
It is null because MVC framework create a new controller to handle different requests, hence the obj is also different.
If you make your Object singleton or simply make it static, it will work.
public static MyObject obj;
Try this:
public class MyController : Controller
{
public MyObject obj = new MyObject();
public ActionResult Index()
{
this.obj.GetData(); // Fill my object
return View();
}
public ActionResult MyFunction()
{
Console.Write(this.obj); // Always null
return View();
}
}
This will stop your null error.
If you want to save data between postbacks, you will need to look into persistent data storage such as a SQL based database.

Ambigious names for controller methods in ASP.NET MVC

Image the following controller method:
public ActionResult ShipmentDetails(Order order)
{
return View(new OrderViewModel { Order = order });
}
The incoming order parameter is filled from a custom model binder, that either creates a new order for this session and stores it in the session, or reuses an existing order from the current session. This order instace is now used to fill a shipment details form, where users can enter their address and so on.
When using #using(Html.BeginForm()) in the view. I cannot use the same signature for the post method again (because this would result in ambigious method names) and I found me adding a dummy parameter just to make this work.
[HttpPost]
public ActionResult ShipmentDetails(Order order, object dummy)
{
if (!ModelState.IsValid)
return RedirectToAction("ShipmentDetails");
return RedirectToAction("Initialize", order.PaymentProcessorTyped + "Checkout");
}
What are the best practices for this? Would you simply rename the method to something like PostShipmentDetails() and use one of the overloads of BeginForm? Or does the problem originate from the point, that the first method has the order parameter?
You could use the ActionName attribuite:
[HttpPost]
[ActionName("ShipmentDetails")]
public ActionResult UpdateShipmentDetails(Order order) { ... }
or a more classic pattern:
public ActionResult ShipmentDetails(int orderId)
{
var order = Repository.GetOrder(orderId);
return View(new OrderViewModel { Order = order });
}
[HttpPost]
public ActionResult ShipmentDetails(Order order)
{
if (!ModelState.IsValid)
return RedirectToAction("ShipmentDetails");
return RedirectToAction("Initialize", order.PaymentProcessorTyped + "Checkout");
}

Updating Linq2Sql object gives exception in MVC

net MVC Web Application. I have a database where i have made my model, i use Linq2SQL to build my Business Logic Layer. In my application i have a customer object, when i call my "editCystomer" page i pass in a Customer to populate the textBoxes:
[AcceptVerbs(HttpVerbs.Get)]
[Authorize]
public ViewResult EditCustomer(string id)
{
int customerId = Convert.ToInt32(id);
CustomerRepository repository = new CustomerRepository();
return View(repository.Load(customerId));
}
When the user has changed in the textboxes i save my changed customer like this:
AcceptVerbs(HttpVerbs.Post)]
[Authorize]
public ActionResult EditCustomer(Customer customer)
{
ValidateCustomer(customer);
if (ModelState.IsValid)
{
CustomerRepository repository = new CustomerRepository();
repository.Save(customer);
return RedirectToAction("CreateCustomerDone");
}
else
{
return View();
}
}
Nothing fancy or unexpected so far, however in my save method:
public void Save(Customer customer)
{
if (customer.Id > 0)
sdc.Refresh(System.Data.Linq.RefreshMode.KeepChanges, customer);
else
sdc.Customers.InsertOnSubmit(customer);
sdc.SubmitChanges();
}
...im getting an exception in my save (the update) that it cannot refresh the object (An object specified for refresh is not recognized. ). I have done this a million times before in other setups, how come its failing now? Any ideas?
The customer object you're sending to Save() is not part of the DataContext. You need to either get the object again, then call the Refresh().
Or you can do the following:
public void Save(Customer customer)
{
if (customer.Id > 0)
{
Customer orig = sdc.Customers.GetOriginalEntityState(customer);
if(orig == null)
sdc.Attach(customer);
sdc.Refresh(System.Data.Linq.RefreshMode.KeepChanges, customer);
}
else
sdc.Customers.InsertOnSubmit(customer);
sdc.SubmitChanges();
}

Stored procedures not called in Entity framework using asp.net MVC

I am trying to use the stored procedure mapping feature in Entity Framework to perform the insert update and delete functions.
For whatever reason the procedures are not being called. They are correctly mapped, and supposedly all I have to do is call SaveChanges(); in my controller for them to execute.
Using this tutorial as a reference, what would I change about the Edit portion of the controller to have it utilize the stored procedure?
Tutorial Code:
//
// GET: /Home/Edit/5
public ActionResult Edit(int id)
{
var contactToEdit = (from c in _entities.ContactSet
where c.Id == id
select c).FirstOrDefault();
return View(contactToEdit);
}
//
// POST: /Home/Edit/5
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Contact contactToEdit)
{
if (!ModelState.IsValid)
return View();
try
{
var originalContact = (from c in _entities.ContactSet
where c.Id == contactToEdit.Id
select c).FirstOrDefault();
_entities.ApplyPropertyChanges(originalContact.EntityKey.EntitySetName, contactToEdit);
_entities.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
}
I thought that just by calling SaveChanges(); the update sproc would update so I just removed the call to ApplyPropertyChanges(); like so:
//
// POST: /Home/Edit/5
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Contact contactToEdit)
{
if (!ModelState.IsValid)
return View();
try
{
_entities.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
}
The update stored procedure doesn't execute though, I have sql profiler running to make sure.
The Programming Entity Framework book tutorials are quoted as saying:
Now that the stored procedures have been mapped, it is not necessary to call them directly in code. Any time SaveChanges is called, Entity Framework will use your mapped stored procedures for any required inserts, updates and deletes.
So, I figure I'm missing something fairly obvious here.
Edit, here is the exact version I'm working with now, the names are different:
//
// GET: /Candidate/Edit/5
public ActionResult Edit(int id)
{
var candidateToEdit = (from c in Internship.CompleteCandidate
where c.UserID == id
select c).FirstOrDefault();
//ViewData["EducationID"] = new SelectList(Internship.education.ToList(), "ID", "Category", candidateToEdit.EducationID);
return View(candidateToEdit);
}
//
// POST: /Candidate/Edit/5
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(CompleteCandidate candidateToEdit)
{
if (!ModelState.IsValid)
return View();
try
{
var originalCandidate = (from c in Internship.CompleteCandidate
where c.UserID == candidateToEdit.UserID
select c).FirstOrDefault();
Internship.ApplyPropertyChanges(originalCandidate.EntityKey.EntitySetName, candidateToEdit);
Internship.SaveChanges();
return RedirectToAction("Index");
}
catch(Exception e)
{
Response.Write("Error: " + e);
//return View();
return null;
}
}
}
}
It looks almost identical to the tutorial code in structure but throws a NullReference exception at runtime.
The problem in your example is that the Contact entity received as the parameter isn't associated with the data context. Thus when SaveChanges is called, there is nothing to update. Typically on update, I use the id provided and obtain the original entity from the database and apply the changes to it. When you do that, SaveChanges should invoke your stored procedure on the entity with it's changes.
Put back in the code to retrieve the original entity and apply the changes to it.
It may be that the update stored procedure is not executing because there are no changes to persist.

Resources