Entries delete from knockout ui, but not from db - entity-framework

I use WebApi in MVC 4 with EF, Ninject.
In client i use knockout.js end it's delete my entries from UI, but it's still in DB.
Add, update action works fine.
Client code:
self.removeUser = function (user) {
var conj = ko.toJS(user);
var json = JSON.stringify(conj);
var Id = user.Id();
$.ajax({
url: API_URL + Id,
cache: false,
type: 'DELETE',
contentType: 'application/json; charset=utf-8',
data: '',
success: function () {
self.Users.remove(user);
}
});
}
WebAPI
// DELETE api/user/5
public HttpResponseMessage Delete(int id)
{
_userRepository.Delete(id);
return Request.CreateResponse(HttpStatusCode.NoContent);
}
Repository
public void Delete(int userId)
{
var user = Get(userId);
_db.Users.Remove(user);
}
Where to start? Which way to go?

If you want to delete an entity is is not enough to remove it form its collection. You need to call DbContext.SaveChanges() in order to commit the transaction and persist your changes into the DB:
public void Delete(int userId)
{
var user = Get(userId);
_db.Users.Remove(user);
_db.SaveChanges();
}

Related

FirstOrDefaultAsync() Hangs MVC5

Someone please help me not kill my Server.. Here's my MVC controller action:
(Don't worry about names, I'm mid-refactoring)
public async Task<ActionResult> AllByLead(int leadId)
{
try
{
var lead = await _researchService.GetLeadWithContacts(leadId);
var contactViewModels = Mapper.Map<Lead, List<ContactViewModel>>(lead);
contactViewModels.Each(contact => PopulateContactOptions(contact));
var listViewModel = new ContactListViewModel {Results = contactViewModels};
return PartialView(listViewModel);
}
catch
{
return Json(string.Format(Resources.BasicErrorMessageFormat, "Error retrieving Lead Contacts"),
JsonRequestBehavior.AllowGet);
}
}
Service:
public async Task<Lead> GetLeadWithContacts(int leadId)
{
return await _repository.GetLeadWithContacts(leadId).ConfigureAwait(false);
}
Repo:
public async Task<Lead> GetLeadWithContacts(int leadId)
{
var leadEntity = await _context.Leads
.Where(lead => lead.LeadID == leadId)
//.Include(lead => lead.LeadContactMaps.Select(map => map.Contact.Addresses))
//.Include(lead => lead.LeadContactMaps.Select(map => map.Contact.PhoneNumbers))
//.Include(lead => lead.Organizations.Select(business => business.Addresses))
//.Include(lead => lead.Organizations.Select(business => business.PhoneNumbers))
.FirstOrDefaultAsync();
return leadEntity;
}
EDIT
DbContext Module
internal class DbContextModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register(ctx => new CRTechEntities()).InstancePerLifetimeScope();
}
}
JS Ajax Call:
function populateContactList() {
var leadId = $("#LeadId").val();
$.ajax({
url: url + "/Contact/AllByLead/",
type: "GET",
data: { 'leadId': leadId },
success: function(data) {
$("#contactContainer").html(data);
},
error: function(data) {
}
});
}
Bonus points on if you can school me on my includes, they may very well be terrible.. It's pretty slow just grabbing the lead right now. Hence the async change. I'd like to see if it will be easier on the system with more users. (I can do my own profiling/tests on whether explicit loading will be better here, just saying..)
Anyway, I hit this, the server is completely borked when the await FirstOrDefaultAsync() gets hit.
EDIT 2: I've updated the controller action to show exactly what I'm doing here. I only included the code that was being hit originally.
Um, are you returning anything in your controller? That would cause it to hang.
Try
public async Task<JsonResult> AllByLead(int leadId)
{
var lead = await _researchService.GetLeadWithContacts(leadId);
return Json(lead);
}

Debugging Ember-cli-mirage when routes are not being called

I have successfully created one route in ember-cli-mirage, but am having trouble loading the related data.
The API should be returning JSON API compliant data.
I'm not really sure if there are any good methods or not for debugging mirage's request interception. Here is my config.js
export default function() {
this.urlPrefix = 'https://myserver/';
this.namespace = 'api/v1';
this.get('/machines', function(db, request) {
return {
data: db.machines.map(attrs => (
{
type: 'machines',
id: attrs.id,
attributes: attrs
}
))
};
});
this.get('/machines/:id', function(db, request){
let id = request.params.id;
debugger;
return {
data: {
type: 'machines',
id: id,
attributes: db.machines.find(id),
relationships:{
"service-orders": db["service-orders"].where({machineId: id})
}
}
};
});
this.get('/machines/:machine_id/service-orders', function(db, request){
debugger; // this never gets caught
});
}
Most of this is working fine (I think). I can create machines and service orders in the factory and see the db object being updated. However, where my application would normally make a call to the api for service-orders: //myserver/machines/:machine_id/service-orders, the request is not caught and nothing goes out to the API
EDIT:
This is the route that my Ember app is using for /machines/:machine_id/service-orders:
export default Ember.Route.extend(MachineFunctionalRouteMixin, {
model: function() {
var machine = this.modelFor('machines.show');
var serviceOrders = machine.get('serviceOrders');
return serviceOrders;
},
setupController: function(controller, model) {
this._super(controller, model);
}
});
And the model for machines/show:
export default Ember.Route.extend({
model: function(params) {
var machine = this.store.find('machine', params.machine_id);
return machine;
},
setupController: function(controller, model) {
this._super(controller, model);
var machinesController = this.controllerFor('machines');
machinesController.set('attrs.currentMachine', model);
}
});
Intuitively, I would think that machine.get('serviceOrders'); would make a call to the API that would be intercepted and handled by Mirage. Which does not seem to be the case

Knockout and MVC2: sending model to controller

I'm having problem with sending json from knockout to mvc2 controller action.
Here is what I have in my View:
var ViewModel = {
FirstName: ko.observable("FirstName"),
LastName: ko.observable("LastName"),
Save: function () {
ko.utils.postJson(location.href, this);
}
}
ko.applyBindings(ViewModel);
I have an action in controller:
public virtual ActionResult SomeAction(MyModel model) {
//do smth
return View(registrationModel);
}
public class MyModel {
public string FirstName {get;set;}
public string LastName {get;set;}
}
The problem is that i'm getting string values quoted, like "\"FirstName\"", and I know that there is some way to avoid that(work with JSON.stringify in MVC3).
I've tried the following:
ko.utils.postJson(location.href, JSON.stringify({model: this});
also
var json = JSON.stringify({
FirstName: this.FirstName(),
LastName: this.LastName()
});
ko.utils.postJson(location.href, JSON.stringify({model: json});
or
ko.utils.postJson(location.href, json);
In all these 3 options I get model = null, or all the values null in Controller.
Maybe someone has done this before?
I've found that in order for the MVC object mapping to work you need to set the content type of the POST to be "application/json; charset=utf-8". I've never done this using ko.utils.postJson() before but here's a working example using jQuery:
$.ajax({
url: url,
type: "POST",
data: ko.toJSON(ViewModel),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (response) {
},
error: function (response, errorText) {
}
});
Note I'm using ko.toJSON to serialize the model as JSON.

Model binding issue with property name as "Id"

Actually in one request, i am getting the data from the ajax call and then posting the data back in another request back to the controller and here i am using model binding,
here i have the following issues,
1. The dictionary in the bound object is null
2. The Id property [value received at Ajax response] but not received at controller during modelbinding
since i am not storing any values in the hidden fields and am just caching the data and passing to other requests, how do i handle the id and dictionary issues in ASP.Net MVC2.
EDIT
*Model in C#:*
public class ViewObject
{
public string Id {get;set;}
public string Name {get;set;}
}
AJAX Code
function fillExistingViews() {
$.ajax({
url: "..",
data: {
ViewId: $("#View_Id").val()
},
type: "POST",
success: function (data) {
if (data !== undefined) {
var ViewObj = JSON.parse(data);
if (ViewObj.ViewObjects === undefined) {
return false;
}
//ViewObj.ViewObjects = dictionary<string,ViewObject
for (var vo in ViewObj.ViewObjects) {
// HERE I GET ViewObj.ViewObjects[vo].Id
$.ajax({
url: "..",
type: "POST",
contentType: "application/json",
data: JSON.stringify(ViewObj.ViewObjects[vo]),
// on posting the viewobject to the server, i find ViewObject.Id to be null
success: function (data) {
//..
}
});
}
}
}
});
}

Refresh a ListBox in ASP.NET MVC 2 with jQuery

I've looked around on SO to see if this has been asked before and couldn't find anything (so if it has indeed been asked before then I apologize.
Here's what I'm trying to do, a user can select from a list of skills for their profile, if a skill they want isn't in the list then they can add it to the database, I have that accomplished with WCF & jQuery AJAX. Here's the code for that:
$("#AddNewSkill").click(function () {
$("#AddNewSkill").attr("disabled", true);
$("#newSkill").attr("disabled", true);
var newSkill = $("#newSkill").val();
var data = { name: $("#newSkill").val(), description: "", type: "Skill" };
data = JSON.stringify(data)
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "../WeddingPhotographerService.svc/AddNew",
data: data,
dataType: "json",
success: function () {
successCall('#newSkill', '#AddNewSkill');
//$('#SkillListViewContainer').load('../Account/GetSkillControl');
},
error: function (msg) {
$("#AddSkillError").text(msg.d);
$("#AddSkill").attr("disabled", false);
$("#NewSkill").attr("disabled", false);
}
});
});
Here's the method in the AJAX-Enabled WCF service:
[OperationContract]
public bool AddNew(string name, string description, string type)
{
switch (type)
{
case "":
goto default;
case "skill":
IRepository<Skill> skillRepo = ObjectFactory.GetInstance<IRepository<Skill>>();
var skill = new Skill { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
skillRepo.Save(skill);
return true;
case "equipment":
IRepository<Equipment> eqRep = ObjectFactory.GetInstance<IRepository<Equipment>>();
var eq = new Equipment { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
eqRep.Save(eq);
return true;
case "occasion":
IRepository<Occassion> occRepo = ObjectFactory.GetInstance<IRepository<Occassion>>();
var oc = new Occassion { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
occRepo.Save(oc);
return true;
default:
IRepository<Skill> repo = ObjectFactory.GetInstance<IRepository<Skill>>();
var s = new Skill { Name = name, Description = (string.IsNullOrEmpty(description)) ? string.Empty : description };
repo.Save(s);
return true;
}
}
It's kind of ugly but I'll optimize it once I have this 2nd part working. Here's how the ListBox is being loaded in the view:
<%: Html.ListBox("Skills", Model.SkillList, new { #style = "width:157px; height:90px;background:#e2f0f1;", #size = "3", #class = "inputbox" })%>
Which comes from RegistrationModelView.cs, here's SkillList in my model view:
private MultiSelectList GetSkills(string[] selectedValues)
{
List<Skill> list = new List<Skill>();
IRepository<Skill> skills = ObjectFactory.GetInstance<IRepository<Skill>>();
foreach (Skill skill in skills.GetAll())
{
list.Add(new Skill()
{
Key = skill.Key,
Name = skill.Name,
Description = ""
});
}
return new MultiSelectList(list, "Key", "Name", selectedValues);
}
And the action in AccountController.cs that loads the view
[MoveFormsScript]
public ActionResult Index()
{
return View(new RegistrationModelView());
}
I'm pretty sure all the code I posted (other than how the new item is added with the WCF service and the jQuery for consuming said service is irrelevant but I thought I'd offer as much information as possible).
Like I said the new value is added to the database no problem, my issue is updating the ListBox to reflect the new values. Anyone got any ideas and can help with this?
Well I mucked around until I found something that does what I need it to do. It may not be the most efficient or elegant way to accomplish the task but it at least works (Maybe someone will come along with a different solution some day).
What I ended up doing was make another $,ajax() call in the success of the first call like this
$("#AddNewSkill").click(function () {
$("#AddNewSkill").attr("disabled", true);
$("#newSkill").attr("disabled", true);
var data = { name: $("#newSkill").val(), description: "", type: "skill" };
data = JSON.stringify(data)
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "../WeddingPhotographerService.svc/AddNew",
data: data,
dataType: "json",
success: function () {
$.ajax({
type:"POST",
datatype:"json",
url: "../Account/GetSkills",
success:updateSkillsListBox
});
},
error: function (msg) {
alert(msg.d);
}
});
});
function updateSkillsListBox(data, status) {
$("#Skills").html("");
for(var d in data) {
$("<option value=\"" + data[d].Value + "\">" + data[d].Name + "</option>").appendTo("#Skills");
}