Within my project I am trying to perform a save operation that updates my Breeze model as well as passes the updated object to my webAPI. In this project I am not using EF context as the project has been modeled to work with other interfaces. So within my webAPI class I have the following:
[BreezeController]
public class ReportLibraryApiController : ApiController
{
readonly long userid = 1;//testing
readonly IReportLibraryManager manager = new ReportLibraryManager();//interface
//method for share
[Route("reportlibrary/SetReportShare/")]
[HttpPost]
public DTOs.Report SetReportShare(JObject report )
{
//within here I plan to unwrap the JSobject and pull out the necessary
//fields that I need
DTOs.Report updatedreport=null;
//manager.ShareReport(updatedreport.ReportId);
//manager.UnShareReport(updatedreport.ReportId);
return updatedreport;
}
}
The Report Object looks like this
public class Report
{
public Int64 ReportId { get; set; }
public string ReportName { get; set; }
public string ReportDescription { get; set; }
public DateTime? ReportDateCreated { get; set; }
public string ReportOwner { get; set; }
public IEnumerable<ReportLabel> ReportLabels { get; set; }
public bool IsShared { get; set; }
public bool IsFavorite { get; set; }
}
From my angular service I am trying to call the save operation as:
app.factory('reportLibraryService', function(breeze, model){
var serviceName = "reportlibrary/";
var ds = new breeze.DataService({
serviceName: serviceName,
hasServerMetadata: false,
useJsonp: true,
});
var manager = new breeze.EntityManager({ dataService: ds });
model.initialize(manager.metadataStore);
function returnResults(data){ return data.results}
function setReportShare(report) {
var option = new breeze.SaveOptions({ resourceName: 'SetReportShare' })
return manager.saveChanges(null, option).then(returnResults)
};
}
I realize the return results may not be correct but at this point I am just trying to call the save operation in the API. When I run the code everything executes but the save/setting of the share does not fire. A secondary question is I'm still not clear on how the breeze model is updated? Am I supposed to issue a new query from the api and pass that back or is there a way to update the cached object. I'm new to breeze (obviously) and trying to figure out where to look.All the examples I have seen thus far use EF context to perform these actions. However in my case I don't have that option.
Should breeze be making the call or since I am not using EF should I be using $http
directive to push the object up. then return a new object to breeze for binding? (that seems a little heavy to me and now how it is designed to work).
I'd appreciate any guidance, or information or how to figure this out.
Edited for more information... Here is a little more detail based on some of the questions posted by Ward to my original question:
where is your metadata that you code says is not on the server?
The solution I am working on does not expose the EF context this far our. As a result interfaces have been created that handle the queries etc within the project. As a result I don't have the ability to use EF. Very similar to the Edmunds sample. I created a meta definition in the web project which references a report object I have defined. This class is much different from what is returned from the DB but it represents what the UI needs. I created two models
report.cs
public class Report {
public Int64 ReportId { get; set; }
public string ReportName { get; set; }
public string ReportDescription { get; set; }
public DateTime? ReportDateCreated { get; set; }
public string ReportOwner { get; set; }
public IEnumerable<ReportLabel> ReportLabels { get; set; }
public bool IsShared { get; set; }
public bool IsFavorite { get; set; }
}
model.js
app.factory('model', function () {
var DT = breeze.DataType;
return {
initialize: initialize
}
function initialize(metadataStore) {
metadataStore.addEntityType({
shortName: "Report",
namespace: "Inform.UI.DTOs",
dataProperties: {
reportId: { dataType: DT.Int64, isPartOfKey: true },
reportName: { dataType: DT.String },
reportDescription: { dataType: DT.String },
reportDateCreated: { dataType: DT.String },
reportOwner: { dataType: DT.String },
reportLabels: { dataType: DT.Undefined },
isShared: { dataType: DT.Bool },
isFavorite: { dataType: DT.Bool }
},
navigationProperties: {
labels: {
entityTypeName: "Label:#Inform.UI.DTOs", isScalar: false,
associationName: "Report_Labels"
}
}
});
metadataStore.addEntityType({
shortName: "ReportLabel",
namespace: "Inform.UI.DTOs",
dataProperties: {
labelId: { dataType: DT.Int64, isPartOfKey: true },
reportId: { dataType: DT.Int64 },
labelName: { dataType: DT.String },
isPublic: { dataType: DT.Bool },
reports: { dataType: DT.Undefined }
},
navigationProperties: {
labels: {
entityTypeName: "Report:#Inform.UI.DTOs", isScalar: false,
associationName: "Report_Labels", foreignKeyNames: ["reportId"]
}
}
});
}
})
why are you configuring useJsonp = true ... and then POSTing to the SetReportShare endpoint?
The dataservice was originally defined for GET requests for querying/returning results to the client. I reused the dataservice and tacked on the POST event. Based on your comment though I assume this is a no-no. In looking at the project I am working within the same domain (and always will be) so I don't really think I need jsonp as part of the dataservice definition. Am I wrong in thinking that? I gather from your question that I should have a separate dataservice for POST's and a separate one for GET's
why is it returning the DTOs.Report type when you can tell by looking at the standard Breeze SaveChanges method that it returns a SaveResult?
This was a typo on my part. The save Result was originally defined as just a JObject. My intent is to return (if necessary) an updated Report object. However I am unsure of the best practice here. If the client (breeze) is updating the cache object. Why do I need to return the report object. Would it not be better to just return a success fail result or boolean of some sort vs. returning an entire report object?
why is your client-side saveChanges callback treating the response as if it came from a query?
This is very simple as you stated, I have no idea what I am doing. I am certainly diving into the deep end as I don't have a choice right now... My question here is when you perform a CRUD operation are these not wrapped in a promise as when performing a query? Or is the promise only important for queries?
Thank you again-
-cheers