SaveChangesAsync() getting stuck - asp.net

I have problem and i think its a deadlock and i cant resolve the problem. I know there simular problem discuse but i need help. When i try to saveChange on productReposotory it stuck and dont execute the other code.
Here is my controller:
public IActionResult All(string type)
{
var viewModel = new AllFireplaceViewModel
{
Fireplaces =
this.fireplaceService.GetAllFireplaceAsync<IndexFireplaceViewModel>(type).Where(x => x.TypeOfChamber == type),
};
return this.View(viewModel);
}
My IFireplaceService:
using System.Collections.Generic;
using System.Threading.Tasks;
using KaminiCenter.Web.ViewModels.Fireplace;
public interface IFireplaceService
{
Task AddFireplaceAsync(FireplaceInputModel fireplaceInputModel);
IEnumerable<T> GetAllFireplaceAsync<T>(string type);
T GetByName<T>(string name);
}
And this is my implementation of the interface:
public async Task AddFireplaceAsync(FireplaceInputModel model)
{
var typeOfChamber = Enum.Parse<TypeOfChamber>(model.TypeOfChamber);
if (model.Power == null ||
model.Size == null ||
model.Chimney == null)
{
throw new ArgumentNullException("Cannot safe null or whitespace values!");
}
await this.productService.AddProductAsync(model.Name, model.Group);
var productId = this.productService.GetIdByNameAndGroup(model.Name, model.Group);
var groupId = this.groupService.FindByGroupName(model.Group).Id;
var fireplace = new Fireplace_chamber
{
Id = Guid.NewGuid().ToString(),
Power = model.Power,
Size = model.Size,
Chimney = model.Chimney,
Price = model.Price,
Description = model.Description,
ImagePath = model.ImagePath.ToString(),
TypeOfChamber = typeOfChamber,
ProductId = productId,
GroupId = groupId,
CreatedOn = DateTime.UtcNow,
ModifiedOn = DateTime.UtcNow,
};
await this.fireplaceRepository.AddAsync(fireplace);
await this.fireplaceRepository.SaveChangesAsync();
}
This is the productService.AddProductAsync:
public async Task AddProductAsync(string name, string groupName)
{
var group = this.groupService.FindByGroupName(groupName);
if (group == null)
{
await this.groupService.CreateAsync(groupName);
}
var product = new Product
{
// TO Check for Id Initializesion
Id = Guid.NewGuid().ToString(),
Name = name,
GroupId = group.Id,
CreatedOn = DateTime.UtcNow,
ModifiedOn = DateTime.UtcNow,
};
await this.productRepository.AddAsync(product);
await this.productRepository.SaveChangesAsync();
}
And my Add Action
public IActionResult Add()
{
var createFireplaceInputModel = new FireplaceInputModel();
return this.View(createFireplaceInputModel);
}

Related

Why Restsharp request object won't be renewed in every call

This is my RestClientService :
public class RestClientService : IRestClientService
{
protected readonly RestClient _restClient;
protected readonly RestRequest _restRequest;
public RestClientService()
{
_restClient = new RestClient();
_restRequest = new RestRequest();
}
public async Task<MessageDTO> SendComment(Websites website, Comment comment, int postId)
{
if (await IsPostExist(postId,website))
{
_restClient.Options.BaseUrl = new Uri($"{website.Url}/wp-json/wp/v2/comments/");
_restRequest.Method = Method.Post;
_restRequest.RequestFormat = DataFormat.Json;
_restRequest.AddJsonBody(new
{
post = postId,
author_name = comment.Author,
content = comment.Body
});
var result = await _restClient.ExecuteAsync(_restRequest);
return new MessageDTO
{
Message = result.Content,
Status = result.StatusCode.ToString()
};
}
return new MessageDTO
{
Message = "Post Not Found",
Status = "404"
};
}
}
I have a list of comments and list of products that I iterate over them and call SendComment method from RestClientService class. The problem is in first time SendComment method called _restRequest object will be get JsonBody and everything is okay but next time this method calls in loop _restRequest object has old data and won't be renewed.
In DI Container I added (Transient) RestClientService
builder.Services.AddTransient<IRestClientService,RestClientService>();
Here is where I used SendComment method in another service.
public async Task<MessageDTO> CreateSendCommentJob(SendCommentConfiguration config)
{
var updatedConfig = await _sendCommentConfigurationRepository.Get(config.Id);
var ConfigDetails = JsonConvert.DeserializeObject<SendCommentConfigurationDetailsDTO>(updatedConfig.Configuration);
var mappedWebsite = _mapper.Map<Websites>(ConfigDetails.WebsiteInfo);
if (ConfigDetails.CommentType == "blog")
{
var comments = await _uCommentService.GetCommentsByGroupId(ConfigDetails.CommentGroupId);
var commentCount = 0;
for (int postCount = 0; postCount < ConfigDetails.ProductPerSendCount; postCount++)
{
var postId = ConfigDetails.Ids[postCount];
while (commentCount < ConfigDetails.CommentsPerProductCount)
{
var random = new Random();
var index = random.Next(comments.Count);
var result = await _restClientService.SendComment(mappedWebsite, comments[index], postId);
if (result.Status == "Created")
{
Console.WriteLine($"Comment Index ({index}) at Id ({postId}) submited successfuly...");
commentCount++;
}
else
{
Console.WriteLine($"{postId} - {result.Status} - {result.Message}");
}
}
ConfigDetails.Ids.Remove(postId);
commentCount = 0;
}
}
var newConfig = new SendCommentConfiguration
{
Id = config.Id,
Configuration = JsonConvert.SerializeObject(ConfigDetails)
};
await _sendCommentConfigurationRepository.Edit(newConfig);
return new MessageDTO
{
Status = "200",
Message = "Comments Successfuly Sent "
};
}
_restClientService.SendComment is called in a loop on the same service instance. As the request instance is a field of the service instance, the same request instance is reused for each call.
As each apple performs a distinct request, each request must use a distinct instance of RestRequest, like :
public class RestClientService : IRestClientService
{
public async Task<MessageDTO> SendComment(Websites website, Comment comment, int postId)
{
if (await IsPostExist(postId,website))
{
//Each call, new instances
var restClient = new RestClient();
var restRequest = new RestRequest();
restClient.Options.BaseUrl = new Uri($"{website.Url}/wp-json/wp/v2/comments/");
restRequest.Method = Method.Post;
restRequest.RequestFormat = DataFormat.Json;
restRequest.AddJsonBody(new
{
post = postId,
author_name = comment.Author,
content = comment.Body
});
var result = await restClient.ExecuteAsync(_restRequest);
return new MessageDTO
{
Message = result.Content,
Status = result.StatusCode.ToString()
};
}
return new MessageDTO
{
Message = "Post Not Found",
Status = "404"
};
}
}

dont show help page in web api

I want to create help pages for ASP.NET Web API.
I created a new ASP.NET Web application project and select the Web API project template. It added Areas/HelpPage.
When I run the application, the home page contains a link to the API help page. From the home page, the relative path is /Help. It shows ValuesController action, but when I add another controller, the help page doesn't show that controller and any of its actions.
public class CalendarController : ApiController
{
private readonly string siteUrl = ConfigurationManager.AppSettings["SiteUrl"];
private readonly CalendarService calendarService;
public CalendarController()
{
calendarService = new CalendarService();
}
[HttpPost]
public async Task<ResponseModel<List<ApiCalendarViewModel>>> Paging(JObject param)
{
try
{
var startIndex = Convert.ToInt32(param["StartIndex"]);
var pageSize = Convert.ToInt32(param["PageSize"]);
var CalendarList = await calendarService.SelectAllAsync(startIndex, pageSize);
var list = CalendarList.Select(m => new ApiCalendarViewModel()
{
Author = m.Author,
Date = PersianDateTime.ToLongDateWithDayString(m.CreatedDate),
Excerpt = m.Excerpt,
Id = m.Id,
MainImage = siteUrl + m.Image,
Title = m.Title,
StartYear = m.StartYear,
EndYear = m.EndYear,
Semester = m.Semester.GetDisplayName()
}).ToList();
return new ResponseModel<List<ApiCalendarViewModel>>()
{
IsSuccess = true,
Data = list
};
}
catch (Exception e)
{
return new ResponseModel<List<ApiCalendarViewModel>>()
{
IsSuccess = false,
Message = e.Message
};
}
}
[HttpGet]
public async Task<ResponseModel<List<ApiCalendarViewModel>>> GetAll()
{
try
{
var CalendarList = await calendarService.SelectAllAsync();
var list = CalendarList.Select(m => new ApiCalendarViewModel()
{
Author = m.Author,
Date = PersianDateTime.ToLongDateWithDayString(m.CreatedDate),
Excerpt = m.Excerpt,
Id = m.Id,
MainImage = siteUrl + m.Image,
Title = m.Title,
StartYear = m.StartYear,
EndYear = m.EndYear,
Semester = m.Semester.GetDisplayName()
}).ToList();
return new ResponseModel<List<ApiCalendarViewModel>>()
{
IsSuccess = true,
Data = list
};
}
catch (Exception e)
{
return new ResponseModel<List<ApiCalendarViewModel>>()
{
IsSuccess = false,
Message = e.Message
};
}
}
}

Insert data in Value Object Table

Inserting Data By POSTMAN, but some error occurred.
My Code is given below:
public async Task<BusinessProfile> Save(string ID,bool Status,string Logo,string TaxNumber,string StateRegisterNumber,string StreetName,string Number
,string Complement,string PostalCode,string Neighborhood,string City,string State,string AreaCode,string Department
,string PhoneNo,string Type,string Website,string EDepartment,string EmailAddress)
{
try
{
int EnumPhoneNumber = 0;
string[] values = Enum.GetNames(typeof(PhoneNumberEnum.PhoneNumber));
if (values[0] == Type)
{
EnumPhoneNumber = (int)PhoneNumber.FixedPhone;
}
else if (values[1] == Type)
{
EnumPhoneNumber = (int)PhoneNumber.MobilePhone;
}
var businessProfile = new BusinessProfile() { ID = ID, Status = Status, Logo = Logo, TaxNumber = TaxNumber, StateRegisterNumber = StateRegisterNumber, Website = Website };
businessProfile.AssignAddress(new Address(StreetName, Number, Complement, PostalCode, Neighborhood, City, State));
businessProfile.AssignPhones(new Phones(Convert.ToString(EnumPhoneNumber), AreaCode, PhoneNo, Department));
businessProfile.AssignEmail(new Emails(EmailAddress, EDepartment));
//_db.Add(businessProfile);
Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<BusinessProfile> x = await _db.AddAsync(businessProfile);
// _db.SaveChanges();
//await _db.BusinessProfiles.AddAsync(businessProfile);
await _db.SaveChangesAsync();
return businessProfile;
}
catch(Exception ex)
{
throw ex;
}
}
Output (Error:):
An unhandled exception occurred while processing the request.
InvalidOperationException: The entity of type BusinessProfile is sharing the table BusinessProfiles with entities of type Address, but there is no entity of this type with the same key value that has been marked as Added. Consider using DbContextOptionsBuilder.EnableSensitiveDataLogging to see the key values.
public async Task Save(BusinessProfile bp)
{
try
{
int EnumPhoneNumber = 0;
string[] values = Enum.GetNames(typeof(PhoneNumberEnum.PhoneNumber));
if (values[0] == bp.Phones.Type)
{
EnumPhoneNumber = (int)PhoneNumber.FixedPhone;
}
else if (values[1] == bp.Phones.Type)
{
EnumPhoneNumber = (int)PhoneNumber.MobilePhone;
}
var businessProfile = new BusinessProfile() { ID = bp.ID, IsActive = bp.IsActive, Logo = bp.Logo, TaxNumber = bp.TaxNumber, StateRegisterNumber = bp.StateRegisterNumber, Website = bp.Website };
businessProfile.Address = new Address(bp.Address.StreetName, bp.Address.Number, bp.Address.Complement, bp.Address.PostalCode, bp.Address.Neighborhood, bp.Address.City, bp.Address.State);
businessProfile.Phones = new Phones(Convert.ToString(EnumPhoneNumber), bp.Phones.AreaCode, bp.Phones.PhoneNumber, bp.Phones.Department);
businessProfile.Emails = new Emails(bp.Emails.EmailAddress, bp.Emails.Department);
Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<BusinessProfile> x = await _db.AddAsync(businessProfile);
await _db.SaveChangesAsync();
return businessProfile;
}
catch (Exception ex)
{
throw ex;
}
}

Use stored procedure for search method

I started with ASP.Net Core 2.0, I'm trying to rewrite a method GetAll by search use stored procedure. Here is method search:
public async Task<List<DepartmentTypeDto>> SearchDepartmentType()
{
EnsureConnectionOpen();
using (var command = CreateCommand("CM_DEPT_GROUP_Search", CommandType.StoredProcedure))
{
using (var dataReader = await command.ExecuteReaderAsync())
{
List<DepartmentTypeDto> result = new List<DepartmentTypeDto>();
while (dataReader.Read())
{
DepartmentTypeDto departmentTypeDto = new DepartmentTypeDto
{
GROUP_ID = dataReader["GROUP_ID"].ToString(),
GROUP_CODE = dataReader["GROUP_CODE"].ToString(),
GROUP_NAME = dataReader["GROUP_NAME"].ToString(),
NOTES = dataReader["NOTES"].ToString(),
RECORD_STATUS = dataReader["RECORD_STATUS"].ToString(),
MAKER_ID = dataReader["MAKER_ID"].ToString(),
CREATE_DT = Convert.ToDateTime(dataReader["CREATE_DT"]),
AUTH_STATUS = dataReader["AUTH_STATUS"].ToString(),
CHECKER_ID = dataReader["CHECKER_ID"].ToString(),
APPROVE_DT = Convert.ToDateTime(dataReader["APPROVE_DT"]),
AUTH_STATUS_NAME = dataReader["AUTH_STATUS_NAME"].ToString(),
RECORD_STATUS_NAME = dataReader["RECORD_STATUS_NAME"].ToString()
};
}
return result;
}
}
}
Here is the service:
public async Task<PagedResultDto<GetDepartmentTypeForView>> GetAll(GetAllDepartmentTypesInput input)
{
var filteredDepartmentTypes = _departmentTypeRepository.SearchDepartmentType();
var query = (from o in filteredDepartmentTypes
select new GetDepartmentTypeForView() { DepartmentType = ObjectMapper.Map<DepartmentTypeDto>(o) });
var totalCount = await query.CountAsync();
var departmentTypes = await query
.OrderBy(input.Sorting ?? "departmentType.id asc")
.PageBy(input)
.ToListAsync();
return new PagedResultDto<GetDepartmentTypeForView>(totalCount, departmentTypes);
}
But I get an error:
Task<List<DepartmentTypeDto>> does not contain a definition for Select
Does anyone know what I should do? I work on Asp.Net Zero.
I changed my search method
public IQueryable<DepartmentTypeView> SearchDepartmentType(GetAllDepartmentTypesInput input, int top)
{
try
{
var GROUP_FILTER = input.Filter;
var GROUP_CODE = input.GROUP_CODEFilter;
var GROUP_NAME = input.GROUP_NAMEFilter;
var AUTH_STATUS = input.AUTH_STATUSFilter;
var result = Context.Query<DepartmentTypeView>().FromSql($"EXEC CM_DEPT_GROUP_Search #p_GROUP_FILTER = {GROUP_FILTER}, #p_GROUP_CODE={GROUP_CODE}, #p_GROUP_NAME={GROUP_NAME}, #p_AUTH_STATUS={AUTH_STATUS}, #p_TOP={top}");
return result;
}
catch
{
return null;
}
}
and in the service, I call that function
var filteredDepartmentTypes = _departmentTypeRepository.SearchDepartmentType(input,100);
I also create new class to keep the result and don't forget to map that class with DTO class
configuration.CreateMap<DepartmentTypeView, DepartmentTypeDto>();
It works for me.

Pass a value from controller to view

I have a problem in passing a value from controller to view
In controller, In the edit method
public ActionResult Edit( FormCollection form)
{
var id = Int32.Parse(form["CustomerServiceMappingID"]);
var datacontext = new ServicesDataContext();
var serviceToUpdate = datacontext.Mapings.First(m => m.CustomerServiceMappingID == id);
TryUpdateModel(serviceToUpdate, new string[] { "CustomerID", "ServiceID", "Status" }, form.ToValueProvider());
if (ModelState.IsValid)
{
try
{
var qw = (from m in datacontext.Mapings
where id == m.CustomerServiceMappingID
select m.CustomerID).First();
ViewData["CustomerID"] = qw;
datacontext.SubmitChanges();
//return Redirect("/Customerservice/Index/qw");
return RedirectToAction("Index", new { id = qw });
}
catch{
}
}
return View(serviceToUpdate);
}
Now in edit's view , I used this
#Html.Encode(ViewData["CustomerID"])
This is my Index method
public ActionResult Index(int id)
{
var dc = new ServicesDataContext();
var query = (from m in dc.Mapings
where m.CustomerID == id
select m);
// var a = dc.Customers.First(m => m.CustomerId == id);
// ViewData.Model = a;
// return View();
return View(query);
}
But the customerID on the page turns to be null.. Can u let me know if this procedure is correct?
You don't need to requery the id. Just use the id directly:
if (ModelState.IsValid)
{
datacontext.SubmitChanges();
//return Redirect("/Customerservice/Index/qw");
return RedirectToAction("Index", new { id = id});
}
Since you are redirecting the ViewData["CustomerID"] will be lost.
However the id in your Index method should be valid.
If your Index View requires the ViewData["CustomerID"] set it in your Index action:
public ActionResult Index(int id)
{
ViewData["CustomerID"] = id;
//....
I'm a bit confused as to which view does not have access to ViewData["CustomerId"]. If it's the Index view, you should set ViewData["CustomerId"] = id there.

Resources