Good day
i'm trying to hard delete a soft deleted records, i have a Method Task PermanantlyDeleteDeal(GetDealInput input) When i call the method it does not go in.
Since boilerplate 0.9.6 is not hard deleting, i'm now using Database>DataContext.cs class to execute hard delete
Here is my DataContext class
public class DataContext : DbContext
{
public virtual DbSet<Deal> Deal{ get; set; }
public DataContext()
: base("Default")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}}
Here is the function on javaScript that u call the method
function DeleteLead(btnCaller) {
abp.message.confirm('Lead will be deleted.', 'Are you sure?', function (isConfirmed) {
if (isConfirmed) {
var button = $(btnCaller);
var proposalId = button.data('content');
var proposalObject = Object({
Id: proposalId
});
abp.ui.setBusy();
_leadService.permanantlyDeleteLead(proposalObject).done(function (result) {
abp.notify.success('Successfully deleted a proposal', 'Quotation deleted');
Refresh();
}).always(function () {
abp.ui.clearBusy();
});
}
});
}
Here is the PermanantlyDeleteComment
public async Task PermanantlyDeleteDeal(GetDealInput input)
{
UserFriendlyException ufex = null;
try
{
DataContext db = new DataContext();
using (Repository.Repository<Deal> repo = new Repository.Repository<Deal>(db))
{
using (Repository.Repository<DealComment> dealCommentRepo = new Repository.Repository<DealComment>(db))
{
using (Repository.Repository<Proposal> proposalRepo = new Repository.Repository<Proposal>(db))
{
using (Repository.Repository<Quotation> quotationRepo = new Repository.Repository<Quotation>(db))
{
Deal deal = repo.GetById(input.Id);
List<DealComment> listOfDealComments = dealCommentRepo.GetAll().Where(dc => dc.DealId == deal.Id).ToList();
List<Proposal> listOfProposals = proposalRepo.GetAll().Where(x => x.DealId == deal.Id).ToList();
List<Quotation> listOfQuotations = quotationRepo.GetAll().Where(x => x.DealId == deal.Id).ToList();
if (listOfProposals.Count > 0 || listOfQuotations.Count > 0)
{
string message = string.Empty;
message += listOfProposals.Count > 0 ? "Cannot delete deal, this deal is linked to:\nProposals\n" : "Cannot delete deal, this deal is linked to:\n";
foreach (var item in listOfProposals)
{
message += $"- {item.Application}\n";
}
message += listOfQuotations.Count > 0 ? "Quotations:\n" : "";
foreach (var item in listOfQuotations)
{
message += $"- {item.Description}\n";
}
ufex = new UserFriendlyException("Ooops! There is a problem.", $"{message}");
throw ufex;
}
else
{
foreach (var item in listOfDealComments)
{
dealCommentRepo.Delete(item);
dealCommentRepo.SaveChanges();
}
if (deal != null)
{
repo.Delete(deal);
repo.SaveChanges();
}
}
}
}
}
}
}
catch
{
if(ufex != null)
throw ufex;
else
throw new UserFriendlyException("Ooops! There is a problem.",$"Deal with Id[{input.Id}] could not be deleted.");
}
}
Abp.Boilerplate 0.9.6
Abp.EntityFramework 0.9.6
I have had the same problem in the past, to fix the issue i had to make sure that The version(s) of entity framework being referenced by the project(s) is the same version of entity framework for all projects in the solution.
And if required in The DataContext class make sure to enable
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
the key is to have the same names as what the ABP context is generating.
Related
Hi I am new to typescript. Blocked and couldn't move forward. Please help!
Below is my PartnerService.cs code to check for duplicates.
private bool CheckforDuplicateCrmIdOrName(string envCode, string crmId, string name)
{
bool partnerExists = false;
var allPartners = this.feeDataAccess.GetAllPartners(envCode).ToList();
var partnerByCrmId = allPartners.FirstOrDefault(p => !string.IsNullOrEmpty(p.CrmId) && p.CrmId.ToUpper() == crmId.ToUpper());
if (partnerByCrmId != null)
{
this.logService.Warn($"Cannot add the account {name} on environment {envCode}. An account with CRM Id {crmId} already exists.");
partnerExists = true;
}
var partnerByName = allPartners.FirstOrDefault(p => !string.IsNullOrEmpty(p.Name) && p.Name.ToUpper() == name.ToUpper());
if (partnerByName != null)
{
this.logService.Warn($"Cannot add the account {name} on environment {envCode}. An account with name {name} already exists.");
partnerExists = true;
}
return partnerExists;
}
Below is my typescript code (create-partner.ts), when I click on Save this method is called. And if there is any error - Error popup displays.
save() {
if (this.isLoading || !this.isValid()) {
return;
}
var dlg = this.modalService.confirm(`Partner ${this.newPartner.Name} will be created with a subscription containing ${this.nbOptionLicenseAdded + 1} license(s).`, 'Are you sure you would like to continue?');
dlg.then(() => {
this.isLoading = true;
this.partnerService.addPartner(this.newPartner, this.partnerLicenses, this.expirationDate)
.then((success: boolean) => {
if (success) {
this.modalService.notify(`Partner \"${this.newPartner.Name}\" has been created.`, `Succesful`);
this.cancel();
} else {
this.modalService.error(`An error has been occured in the creation of the partner \"${this.newPartner.Name}\". Please try later.`);
}
})
.catch(() => {
this.modalService.error(
`An error has been occured in the creation of the partner \"${this.newPartner.Name
}\". Please try later.`);
})
.finally(() => this.isLoading = false);
});
}
This is my PartnerService.ts where addPartner method is included.
addPartner(newPartner: Partner, subscriptionLicenses: FeLicense[], expirationDate: Date): angular.IPromise<boolean> {
var newSubscription = new FeSubscription();
newSubscription.Coupons = [];
subscriptionLicenses.forEach((license: FeLicense) => {
var newCoupon = new FeCoupon();
newCoupon.IsOption = license.IsOption;
newCoupon.LicenseCommercialRef = license.CommercialReference;
newCoupon.LicenseId = license.LicenseId;
if (expirationDate) {
var customDate = expirationDate.getFullYear() + '-' + (expirationDate.getMonth() + 1) + '-' + expirationDate.getDate();
newCoupon.ExpirationDate = customDate;
}
newSubscription.Coupons.push(newCoupon);
});
newPartner.Subscriptions = [];
newPartner.Subscriptions.push(newSubscription);
// Empty state is country is not US
if (newPartner.Address.CountryCode !== app.config.GlobalConstants.Default.usCountryCode) {
newPartner.Address.State = '';
}
return this.partnerWebService.addPartner(newPartner);
}
When I click on Save() button - I want to check for the existing CRMID and Name, If it already exists then it should return me a error message saying "CRMID already exists" or "Name already exists"
I am trying to upload file with a multiple objects e.g. I have a student who wants to upload multiple scanned/downloaded files. Everything must drag and drop, so when user drag and drops files I generate objects in react application and post via axois with _header["Content-Type"] = "multipart/form-data".
But I am not able to see the file in sent object. What am I missing?
public class CourseFile{
public Guid StudentId{get;set;}
public string FileName{get;set;}
public boolean IsPdf{get;set;}
public IFormFile File{get;set;}
}
StudentController
[Route("upload-files")]
[HttpPost]
public async Task<IActionResult> UploadFiles([FromForm] IList<CourseFile> models)
{
var _req = Request;
var files = Request.Form.Files; // I can see files here
var file = files.First();
var modelProperty = file.Name; // I can see model property here
foreach (var courseFile in models)
{
UploadFiles(courseFile.File) // Always null
}
}
React Code Only making of object
private getFormData(data: any, form: FormData, idx = -1, baseKey = "") {
if (Array.isArray(data))
data.forEach((item, idx) => this.getFormData(item, form, idx));
Object.keys(data).forEach((key) => {
if (!key) return;
let _key =
idx > -1
? baseKey
? key.indexOf("files") >= 0
? `${baseKey}[][${key}]`
: `${baseKey}[${idx}][${key}][]`
: `${key}[${idx}]`
: key;
let itemData = data[key];
if (Array.isArray(itemData)) {
itemData.forEach((item, idx) => this.getFormData(item, form, idx, key));
return form;
}
if (key.indexOf("files") >= 0) {
form.append(`${baseKey}[${idx}][File][]`, itemData);
} else if (itemData) {
form.append(_key, itemData);
} else {
form.append(_key, "");
}
});
return form;
}
Your problem might be here:
form.append(`${baseKey}[${idx}][File][]`, itemData);
The key/name seems to be quite finicky with files. I ended up having to change this to the following in order to work:
form.append(`${baseKey}[${idx}].File`, itemData);
I made a simplified version of your code (see below) to do my testing. I tried multiple combinations, such as you had [File][], and [File], and finally .File. The last was the only one that resulted in the file being correctly set.
*Edit: This only seems to apply to the IFormFile key. I was able to do either [StudentId] or .StudentId, and either of those would work.
fetch code:
const baseKey = 'models';
const data = new FormData();
for (let idx = 0; idx < 10; idx++) {
const b = new Blob(['This is my blob content ' + idx], { type: 'text/plain' });
data.append(`${baseKey}[${idx}].StudentId`, idx);
data.append(`${baseKey}[${idx}].File`, b);
}
fetch('/home/uploadfiles', { method: 'post', body: data });
controller method:
public class CourseFile
{
public int StudentId { get; set; }
public IFormFile File { get; set; }
}
public async Task<IActionResult> UploadFiles([FromForm] IList<CourseFile> models)
{
return Ok();
}
In the Asp.Net Project MVC with SignalR, I am trying to iterate over a object returned by Service in the Javascript Client. I get the below compile error for the foreach statement present in the below code
foreach statement cannot operate on variables of type 'System.Threading.Tasks.Task>' because 'System.Threading.Tasks.Task>' does not contain a public definition for 'GetEnumerator'
Can someone advise what changes should be done either in View/Service call ?
View Code
#model System.Threading.Tasks.Task<List<JobCurrentStatusDetails>>
<script type="text/javascript">
var connection = $.hubConnection();
var hub = connection.createHubProxy("JobDetailsHub");
hub.on('updateData',function(jSonRefreshData){
console.log(jSonRefreshData);
});
hub.invoke('NotifyUpdates').done(function(jSonRefreshData){
#Model = jSonRefreshData
#{int countTiles = 0;}
#foreach(item in Model)
{
if(item.color == "red")
{}
if(item.color == "green")
{}
}
});
</script>
Adding Server Side code
public async Task<List<JobCurrentStatusDetails>> NotifyUpdates()
{
var hubContext = lobalHost.ConnectionManager.GetHubContext<JobDetailsHub> ();
if (hubContext != null)
{
db = DataAccess.DataAccessModels.GetDashboardCounts();
return await hubContext.Clients.All.updateData(db);
}
else return null;
}
The Controller code is below :
public ActionResult Index()
{
DataAccess da = new DataAccess();
var jobDetailService = new JobDetailsService(da);
return View(jobDetailService.NotifyUpdates());
}
You are returning a Task as the Model. You could do this instead:
public List<JobCurrentStatusDetails> NotifyUpdates()
{
var hubContext = lobalHost.ConnectionManager.GetHubContext<JobDetailsHub>();
if (hubContext != null)
{
db = DataAccess.DataAccessModels.GetDashboardCounts();
return hubContext.Clients.All.updateData(db).Result;
}
else return null;
}
I have this code.
The objective of this js is through the dropwdown load the textbox UserMR
But it never finds the UserMR.
I call UserMr model inside Star instantiating a new object.
relationships:
Star contains idModel
Model does not contain IDStar
What is going on?
Model
[CustomValidation(typeof(StarValidation), "DateValidate")]
public partial class Star
{
public virtual string UserMR { get { return this.User.UserMR; } set { this.UserMR = value;} }
public Model User = new Model();
View inside "STAR"
#Html.EditorFor(i => i.IdModel, "StarModel", new { onchange = "updateUserMR($(this))" })
#Html.DisplayFor(i => i.UserMR)
<script type="text/javascript">
function updateUserMR(model) {
var user = model.brother("#Html.NameFor(x => x.UserMR)");
var idModel = model.val();
user.empty();
if (idModel != null && idModel != "")
user.loadOptions("#Url.Action("ListJsonUserMR", "Model")?idModel=" + idModel, true, true);
}
</script>
Controller
public JsonResult ListJsonUserMR(int idModel)
{
var model = this.service.GetUserMr(idModel).Select(x => new
{
Value = x.Id,
Description = x.UserMR
});
return this.Json(model, JsonRequestBehavior.AllowGet);
}
Service
public IEnumerable<Model> GetUser(int idModel)
{
return base.context.Models
.Where(x => x.Id == idModel);
}
Error
I'm developing a game on cordova that uses facebook integration. I have a facebook game canvas running on a secure site.
The friend request works fine on the web site version (returns more than 25 results, as I'm iterating the paging.next url that is also returned).
However, on the cordova build (android) it only ever returns the first result set of 25. It does still have the page.next url JSON field but it just returns a response object with a type=website.
Has anyone else come across this?
After quite a lot of digging I found an issue with the way requests are handled in the FacebookLib for Android. The current version of the com.phonegap.plugins.facebookconnect plugin uses Android FacebookSDK 3.21.1 so I'm not sure if this will still be an issue with v4.
A graph result with a paging url is used to request the next page however using the entire url, which includes the https://graph.facebook.com/ as well as the usual graphAction causes an incorrect result set to be returned. However I determined that if you remove the schema and host parts it will be correct.
I modified the ConnectPlugin.java to check that any schema and host is removed from the graphAction. Seems to work well now.
ConnectPlugin.java before:
private void makeGraphCall() {
Session session = Session.getActiveSession();
Request.Callback graphCallback = new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (graphContext != null) {
if (response.getError() != null) {
graphContext.error(getFacebookRequestErrorResponse(response.getError()));
} else {
GraphObject graphObject = response.getGraphObject();
JSONObject innerObject = graphObject.getInnerJSONObject();
graphContext.success(innerObject);
}
graphPath = null;
graphContext = null;
}
}
};
//If you're using the paging URLs they will be URLEncoded, let's decode them.
try {
graphPath = URLDecoder.decode(graphPath, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String[] urlParts = graphPath.split("\\?");
String graphAction = urlParts[0];
Request graphRequest = Request.newGraphPathRequest(null, graphAction, graphCallback);
Bundle params = graphRequest.getParameters();
if (urlParts.length > 1) {
String[] queries = urlParts[1].split("&");
for (String query : queries) {
int splitPoint = query.indexOf("=");
if (splitPoint > 0) {
String key = query.substring(0, splitPoint);
String value = query.substring(splitPoint + 1, query.length());
params.putString(key, value);
if (key.equals("access_token")) {
if (value.equals(session.getAccessToken())) {
Log.d(TAG, "access_token URL: " + value);
Log.d(TAG, "access_token SESSION: " + session.getAccessToken());
}
}
}
}
}
params.putString("access_token", session.getAccessToken());
graphRequest.setParameters(params);
graphRequest.executeAsync();
}
ConnectPlugin.java after:
private void makeGraphCall() {
Session session = Session.getActiveSession();
Request.Callback graphCallback = new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (graphContext != null) {
if (response.getError() != null) {
graphContext.error(getFacebookRequestErrorResponse(response.getError()));
} else {
GraphObject graphObject = response.getGraphObject();
JSONObject innerObject = graphObject.getInnerJSONObject();
graphContext.success(innerObject);
}
graphPath = null;
graphContext = null;
}
}
};
//If you're using the paging URLs they will be URLEncoded, let's decode them.
try {
graphPath = URLDecoder.decode(graphPath, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String[] urlParts = graphPath.split("\\?");
String graphAction = urlParts[0];
///////////////////////
// SECTION ADDED
///////////////////////
final String GRAPH_BASE_URL = "https://graph.facebook.com/";
if(graphAction.indexOf(GRAPH_BASE_URL)==0) {
URL graphUrl = null;
try {
graphUrl = new URL(graphAction);
} catch (MalformedURLException e) {
e.printStackTrace();
}
graphAction = graphUrl.getPath();
}
///////////////////////
// END SECTION ADDED
///////////////////////
Request graphRequest = Request.newGraphPathRequest(null, graphAction, graphCallback);
Bundle params = graphRequest.getParameters();
if (urlParts.length > 1) {
String[] queries = urlParts[1].split("&");
for (String query : queries) {
int splitPoint = query.indexOf("=");
if (splitPoint > 0) {
String key = query.substring(0, splitPoint);
String value = query.substring(splitPoint + 1, query.length());
params.putString(key, value);
if (key.equals("access_token")) {
if (value.equals(session.getAccessToken())) {
Log.d(TAG, "access_token URL: " + value);
Log.d(TAG, "access_token SESSION: " + session.getAccessToken());
}
}
}
}
}
params.putString("access_token", session.getAccessToken());
graphRequest.setParameters(params);
graphRequest.executeAsync();
}
There's no way to know that you call their api from cordova vs website, so it's some problem on your side, maybe you use some different implementation of the api on corodva and website, so that cordova sends a pagination request or send to other api version which does pagination.