Wrong PUT method gets triggered in Akka Http using scala - scala

In my APIendpoint class, I have 2 PUT methods lets say updateA and UpdateB but when I'm trying to hit UpdateB using swagger it resolves to a UpdateA everytime. I dunno what I'm doing wrong because the code seems ok to me. Any help is appreciated.
#Api(value = "/connectroutes", produces = "application/json", consumes = "application/json",
authorizations = Array(new Authorization(value = "")))
#Produces(Array(MediaType.APPLICATION_JSON))
def routes: Route = {
pathPrefix("sampleroute") {
authenticateBasic(realm = "sample realm", authenticator) { authenticationResult =>
updateA ~
updateB
}
}
#PUT
#Path("{name}")
#Produces(Array(MediaType.APPLICATION_JSON))
#Operation(summary = "sample", description = "UPDATE A",
parameters = Array(new Parameter(name = "name", in = ParameterIn.PATH, description = "updateA name", required = true)),
requestBody = new RequestBody(content = Array(new Content(schema = new Schema(implementation = classOf[A]), mediaType = MediaType.APPLICATION_JSON))),
)
def updateA: Route = {
path(Segment) { name =>
put {
entity(as[A]) { a: A => {
complete(updateAMethod(name, a))
}
}
}
}
}
#PUT
#Path("updateb")
#Produces(Array(MediaType.APPLICATION_JSON))
#Authorization("basicAuth")
#Operation(summary = "Sample", description = "Update B",
requestBody = new RequestBody(content = Array(new Content(schema = new Schema(implementation = classOf[String]), mediaType = MediaType.APPLICATION_JSON))),
)
def updateB: Route = {
path("updateb" / Segment) { namespace =>
put {
entity(as[String]) { updatedval: String => {
complete(updatedVal))
}
}
}
}
}

Related

Flow invariant is violated

Resources:::
ViewModel -->
#ExperimentalCoroutinesApi
#HiltViewModel
class TestimonialViewModel
#Inject constructor(
private val testimonialRepo: TestimonialRepo,
private val authRepo: AuthRepo,
val networkHelper: NetworkHelper,
private val savedStateHandle: SavedStateHandle,
) : ViewModel() {
var title by mutableStateOf(UiString.Resource(R.string.testimonial_title_create))
private set
var data by mutableStateOf(TestimonialData())
private set
private var curInx = 0
private val _areInputsValid = MutableStateFlow(false)
val areInputsValid = _areInputsValid.asStateFlow()
private val _mutableState = MutableStateFlow<TestimonialGetState>(TestimonialGetState.Loading)
val state = _mutableState.asStateFlow()
private val _stateChannel = Channel<TestimonialSubmitState>()
val stateChannel = _stateChannel.receiveAsFlow()
init {
onLoad()
}
fun onLoad() {
if (networkHelper.isConnected()) {
authRepo.getUser()?.let {
loadTestimonial(userId = it.uid)
}
} else {
_mutableState.value = TestimonialGetState.NoInternet
}
}
private fun loadTestimonial(userId: String) {
viewModelScope.launch {
testimonialRepo.getTestimonial(userId).catch { ex ->
//_mutableState.value = TestimonialGetState.Error(ex)
_mutableState.value = TestimonialGetState.Empty
}.collect {
if (it.id.isNotBlank())
title = UiString.Resource(R.string.testimonial_title_edit)
data = TestimonialData(
id = it.id,
type = it.type,
title = it.title,
testimonial = it.testimonial,
role = it.user.role,
org = it.user.org
)
when (it.type) {
TestimonialType.TEXT -> {
}
TestimonialType.IMAGE -> {
data.imgMedia = it.media.toMutableStateList()
}
TestimonialType.VIDEO -> {
data.vdoMedia = it.media.toMutableStateList()
}
}
_mutableState.value = TestimonialGetState.Success(it)
}
}
}
private fun updateTestimonial(netTestimonial: Testimonial) {
viewModelScope.launch {
testimonialRepo.updateTestimonial(netTestimonial)
.catch { ex ->
_stateChannel.send(TestimonialSubmitState.Error(ex))
}.collect {
clearErrors()
_stateChannel.send(TestimonialSubmitState.Success(it))
}
}
}
fun onEvent(event: TestimonialEvent) {
when (event) {
is TestimonialEvent.OnTypeChange -> {
data = data.copy(type = event.type)
_areInputsValid.value = validateTestimonial(event.type)
}
is TestimonialEvent.OnTitleChange -> {
data = data.copy(title = event.title)
data.titleError = onValidateText(event.title, 4, 64)
_areInputsValid.value = validateTestimonial(data.type)
}
is TestimonialEvent.OnTestimonialChange -> {
data = data.copy(testimonial = event.testimonial)
data.testimonialError = onValidateText(event.testimonial, 32, 256)
_areInputsValid.value = validateTestimonial(data.type)
}
is TestimonialEvent.OnOrgChange -> {
data = data.copy(org = event.org)
data.orgError = onValidateText(event.org, 4, 32)
_areInputsValid.value = validateTestimonial(data.type)
}
is TestimonialEvent.OnRoleChange -> {
data = data.copy(role = event.role)
data.roleError = onValidateText(event.role, 2, 32)
_areInputsValid.value = validateTestimonial(data.type)
}
is TestimonialEvent.OnMediaIndex -> {
curInx = event.inx
}
is TestimonialEvent.OnImageSelect -> {
if (event.url != null) {
data.imgMedia[curInx] = data.imgMedia[curInx].copy(localUrl = event.url)
}
data.imgError = onValidateMedia(data.imgMedia)
_areInputsValid.value = validateTestimonial(data.type)
}
is TestimonialEvent.OnImageClear -> {
data.imgMedia[event.inx] = data.imgMedia[event.inx].copy(localUrl = null, url = "")
data.imgError = UiString.Resource(R.string.the_media_can_not_be_blank)
_areInputsValid.value = validateTestimonial(data.type)
}
is TestimonialEvent.OnVideoSelect -> {
if (event.url != null) {
data.vdoMedia[curInx] = data.vdoMedia[curInx].copy(localUrl = event.url)
}
data.vdoError = onValidateMedia(data.vdoMedia)
_areInputsValid.value = validateTestimonial(data.type)
}
is TestimonialEvent.OnVideoClear -> {
data.vdoMedia[event.inx] = data.vdoMedia[event.inx].copy(localUrl = null, url = "")
data.vdoError = UiString.Resource(R.string.the_media_can_not_be_blank)
_areInputsValid.value = validateTestimonial(data.type)
}
is TestimonialEvent.OnSubmit -> {
submit()
}
}
}
private fun submit() {
authRepo.getUser()?.let {
updateTestimonial(
Testimonial(
id = data.id,
type = data.type,
title = data.title.trim(),
testimonial = data.testimonial.trim(),
userId = it.uid,
user = TestimonialUser(
name = it.name!!,
role = data.role.trim(),
org = data.org.trim(),
url = it.photoUrl.toString()
),
media = when (data.type) {
TestimonialType.TEXT -> listOf()
TestimonialType.IMAGE -> data.imgMedia
TestimonialType.VIDEO -> data.vdoMedia
}
)
)
}
}
private fun clearErrors() {
data.titleError = UiString.Empty
data.testimonialError = UiString.Empty
data.roleError = UiString.Empty
data.orgError = UiString.Empty
data.imgError = UiString.Empty
data.vdoError = UiString.Empty
}
private fun onValidateText(value: String, min: Int, max: Int): UiString {
return when {
value.isBlank() -> UiString.Resource(R.string.the_field_can_not_be_blank)
value.length > max -> UiString.Resource(R.string.data_length_more, max)
value.length in 1 until min -> UiString.Resource(R.string.data_length_less, min)
else -> UiString.Empty
}
}
private fun onValidateMedia(mediaList: List<Media>): UiString {
return if (validateMedia(mediaList)) UiString.Empty
else UiString.Resource(R.string.the_media_can_not_be_blank)
}
private fun validateMedia(mediaList: List<Media>): Boolean {
return mediaList.find { it.localUrl == null && it.url.isBlank() } == null
}
private fun validateTestimonial(type: TestimonialType): Boolean {
return when (type) {
TestimonialType.TEXT -> validateData(
data.testimonial.isNotBlank() && data.testimonialError is UiString.Empty
)
TestimonialType.IMAGE -> validateData(
validateMedia(data.imgMedia) && data.imgError is UiString.Empty
)
TestimonialType.VIDEO -> validateData(
validateMedia(data.vdoMedia) && data.vdoError is UiString.Empty
)
}
}
private fun validateData(typeValidation: Boolean): Boolean {
return (typeValidation && data.title.isNotBlank() && data.titleError is UiString.Empty
&& data.org.isNotBlank() && data.orgError is UiString.Empty
&& data.role.isNotBlank() && data.roleError is UiString.Empty
)
}
}
TestimonialsSubmitState ->
sealed class TestimonialSubmitState {
object Loading : TestimonialSubmitState()
class Error(val error: Throwable) : TestimonialSubmitState()
class Success(val status: Status) : TestimonialSubmitState()
}
UI Component ->
#OptIn(ExperimentalCoroutinesApi::class)
#Composable
fun TestimonialForm(
editViewModel: TestimonialViewModel = hiltViewModel(),
paddingValues: PaddingValues,
onNavigateTstHome: () -> Unit,
) {
val focusRequester = remember { FocusRequester() }
val radioButtonList = listOf(
TestimonialType.TEXT, TestimonialType.IMAGE, TestimonialType.VIDEO
)
var showCustomDialogWithResult by remember { mutableStateOf(false) }
val selectedOption = radioButtonList.find {
it == editViewModel.data.type
} ?: radioButtonList[0]
val focusManager = LocalFocusManager.current
val scrollState = rememberScrollState()
val areInputsValid by editViewModel.areInputsValid.collectAsStateWithLifecycle()
val events = editViewModel.stateChannel.collectAsState(initial = TestimonialSubmitState.Loading)
val event = events.value
Column(
modifier = Modifier
.fillMaxWidth()
.padding(
top = paddingValues.calculateTopPadding(),
start = spacing.medium,
end = spacing.medium
)
.verticalScroll(scrollState), verticalArrangement = Arrangement.Center
) {
Spacer(modifier = Modifier.height(spacing.medium))
TestimonialsRadioButton(selectionTypeText = "Testimonial Type",
radioButtonList = radioButtonList,
selectedOption = selectedOption,
content = {
ValidatedTextField(
value = editViewModel.data.testimonial,
onValueChange = {
editViewModel.onEvent(
TestimonialEvent.OnTestimonialChange(
it
)
)
},
label = "Testimonial",
showError = editViewModel.data.testimonialError !is UiString.Empty,
errorMessage = editViewModel.data.testimonialError,
keyboardOptions = if (editViewModel.data.testimonial.length < 512) {
KeyboardOptions(
keyboardType = KeyboardType.Text, imeAction = ImeAction.Default
)
} else {
KeyboardOptions(
keyboardType = KeyboardType.Text, imeAction = ImeAction.Next
)
},
keyboardActions = KeyboardActions(onNext = {
focusManager.clearFocus()
}),
modifier = Modifier.height(boxSize.extraMedium)
)
},
titleTestimonial = {
ValidatedTextField(
value = editViewModel.data.title,
onValueChange = { editViewModel.onEvent(TestimonialEvent.OnTitleChange(it)) },
label = "Title",
showError = editViewModel.data.titleError !is UiString.Empty,
errorMessage = editViewModel.data.titleError,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text, imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(onNext = {
focusManager.moveFocus(FocusDirection.Down)
})
)
},
onOptionSelected = {
editViewModel.onEvent(TestimonialEvent.OnTypeChange(it))
})
Spacer(modifier = Modifier.height(spacing.medium))
ValidatedTextField(
value = editViewModel.data.org,
onValueChange = { editViewModel.onEvent(TestimonialEvent.OnOrgChange(it)) },
label = "Organisation",
showError = editViewModel.data.orgError !is UiString.Empty,
errorMessage = editViewModel.data.orgError,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text, imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(onNext = {
focusManager.moveFocus(FocusDirection.Down)
})
)
Spacer(modifier = Modifier.height(spacing.medium))
ValidatedTextField(
value = editViewModel.data.role,
onValueChange = { editViewModel.onEvent(TestimonialEvent.OnRoleChange(it)) },
label = "Role",
showError = editViewModel.data.roleError !is UiString.Empty,
errorMessage = editViewModel.data.roleError,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text, imeAction = ImeAction.Done
),
modifier = Modifier.focusRequester(focusRequester = focusRequester),
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() })
)
if (selectedOption == radioButtonList[1]) {
Spacer(modifier = Modifier.height(spacing.medium))
TestGetImage()
} else if (selectedOption == radioButtonList[2]) {
Spacer(modifier = Modifier.height(spacing.medium))
TestGetVideo()
}
androidx.compose.material.Button(
onClick = {
editViewModel.onEvent(TestimonialEvent.OnSubmit)
showCustomDialogWithResult = !showCustomDialogWithResult
},
modifier = Modifier
.fillMaxWidth(1f)
.padding(spacing.medium),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.Blue, contentColor = Color.White
),
enabled = areInputsValid
) {
Text(text = "Submit", style = MaterialTheme.typography.labelLarge)
}
if (showCustomDialogWithResult) {
when (event) {
is TestimonialSubmitState.Error -> {
Log.d("validate", "Error -> ${event.error.message} and ${event.error.cause}")
}
TestimonialSubmitState.Loading -> {
LoadingAnimation()
}
is TestimonialSubmitState.Success -> {
OnSuccessfulSubmit(onDismiss = {
showCustomDialogWithResult = !showCustomDialogWithResult
}, onNavigateTstHome = onNavigateTstHome, onPositiveClick = {
editViewModel.onEvent(TestimonialEvent.OnSubmit)
onNavigateTstHome()
})
}
}
}
}
}
SuccessfulSubmit Dialog ->
Here, LaunchedEffect block is just for testing purpose.
#Composable
fun OnSuccessfulSubmit(
onDismiss: () -> Unit,
onNavigateTstHome: () -> Unit,
onPositiveClick: () -> Unit,
) {
var underReview by remember {
mutableStateOf(true)
}
LaunchedEffect(key1 = Unit, block = {
delay(2000)
underReview = false
delay(3000)
onNavigateTstHome()
})
Dialog(
onDismissRequest = onDismiss, properties = DialogProperties(dismissOnClickOutside = false)
) {
SuccessfulCard(onClick = onPositiveClick, underReview = underReview)
}
}
Error --->
When I click on Submit Button --->
Log --->
Question -->
What is this error in Log... Code part related to it --->
_stateChannel, stateChannel, updateTestimonial(), submit() ---> inherited in Testimonial form ----> last 2nd Button Component and below it event calling is DONE.
Sorry for bad structuring of the question.
Thank you.
Things I tried ---> events variable in TestimonialForm, I tried to make collectAsState( initial = null )
Also tried LaunchedEffect for when case as suggested in other similar question on Stackoverflow, but got Composable invocation error.

How to mock ExecuteReaderAsync in .NET Framework c#

I need to mock the ExecuteReaderAsync for my project.
Actually in my project I am dealing all the db related query using procedure so that I have created generic repo to handle the db query using the below code.
Below one is the repository to make the db connection and execute the stored procedure .
public async Task<DbDataReader> ExecGetWithStoreProcedure(string storeProcedureName, params object[] parameters)
{
try
{
var command = _dbContext.Database.Connection.CreateCommand();
command.Connection.Open();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = storeProcedureName;
foreach (var item in parameters)
{
command.Parameters.Add(item);
}
return await command.ExecuteReaderAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
throw ex;
}
}
Now when I am writing the test case so noticed that DB is not getting mock it's returning the actual data from database. I have tried to mock the DbCommand , DbDataReader but still not able to mock it successfully. Here is the below code
Below one is the service class.
public async Task<HttpResponseModel<FormulationReviewCommentsResults>> GetDashboardFormulationReviewComments(int PageSize, int PageNumber, string userName)
{
List<Tbl_FormulationReviewComments> list = new List<Tbl_FormulationReviewComments>();
var result = new FormulationReviewCommentsResults();
try
{
using (_unitOfWork = new UnitOfWorkRMM(new PlutoContextRMM(DBConstants.connectionName)))
{
var reader = await _unitOfWork.DashboardRepos.ExecGetWithStoreProcedure(DBConstants.USP_MST_GET_DashboardReviewComments,
new SqlParameter(DBConstants.PageSize, SqlDbType.Int) { SqlValue = PageSize },
new SqlParameter(DBConstants.PageNumber, SqlDbType.Int) { SqlValue = PageNumber },
new SqlParameter(DBConstants.userName, SqlDbType.NVarChar) { SqlValue = userName }).ConfigureAwait(false);
while (reader.Read())
{
var comments = new Tbl_FormulationReviewComments();
comments.Id = int.Parse(reader.GetValue(0).ToString());
comments.Name = reader.GetValue(1).ToString();
comments.FormulationDetailId = int.Parse(reader.GetValue(2).ToString());
comments.Comment = reader.GetValue(3).ToString();
comments.FormulationDetailId = int.Parse(reader.GetValue(4).ToString());
comments.FormulationReferenceNo = reader.GetValue(5).ToString();
comments.VersionNo =reader.GetValue(6).ToString();
comments.TotalRecords = int.Parse(reader.GetValue(7).ToString());
list.Add(comments);
}
result.FormulationReviewComments = list;
result.TotalRecords = list.Count > 0 ? list[0].TotalRecords : 0;
return _httpResponse.HandleReturnResponse(result, MessagesConstants.CommonErrorMessage, false);
}
}
catch (Exception ex)
{
_logger.Error(ex, strLoggerName);
return _httpResponse.HandleReturnResponse(result, MessagesConstants.CommonErrorMessage, false);
}
}
Mocking the DataReader and all realted things using the below code.
public static void GetDashBoard3()
{
string[] fieldNames = { "Id", "Name", "FormulationDetailId", "Comment", "FormulationDetailId", "FormulationReferenceNo", "VersionNo", "TotalRecords" };
List<FormulationReviewCommentsResults> resultModel = new List<FormulationReviewCommentsResults>();
List<Tbl_FormulationReviewComments> items = new List<Tbl_FormulationReviewComments>();
items.Add(new Tbl_FormulationReviewComments
{
TotalRecords = 1,
Comment = "",
CommentAssignedTo = "",
CommentClosedBy = "",
CommentClosedDate = DateTime.Now,
CommentCreatedBy = "",
CommentCreatedDate = DateTime.Now,
CommentDueDate = DateTime.Now,
CommentRepliedBy = "",
CommentRepliedDate = DateTime.Now,
CommentsReplied = "",
CommentUpdatedBy = "",
CommentUpdatedDate = DateTime.Now,
CreatedBy = "",
CreatedDate = DateTime.Now,
FormulationDetailId = 12313,
FormulationRawMaterialId = 123,
FormulationRawMaterialSubComponentId = 12321,
FormulationReferenceNo = "",
Id = 1,
isClosed = false,
IsDeleted = false,
isReplied = false,
ManufacturerId = 123,
ManufacturerName = "",
MarketId = 123,
MarketName = "",
Name = "",
RawMaterialId = 123,
RawMaterialName = "",
RegulationId = 123,
ReviewComments = "sdfsadf",
ReviewedBy = "",
ReviewedDate = DateTime.Now,
StatusCode = "202",
StatusId = 1,
StatusName = "",
SubComponentName = "",
SupplierId = 1,
SupplierName = "",
SupplierRawMaterialSubComponentDetailId = 123,
TradeName = "",
});
resultModel.Add(new FormulationReviewCommentsResults
{
FormulationReviewComments = items,
TotalRecords = 1
});
Mock<DbProviderFactory> mockedDataReader = new Mock<DbProviderFactory>();
var commandMock = new Mock<IDbCommand>();
var readerMock = new Mock<IDataReader>();
commandMock.Setup(m => m.ExecuteReader()).Returns(readerMock.Object).Verifiable();
var parameterMock = new Mock<IDbDataParameter>();
commandMock.Setup(m => m.CreateParameter()).Returns(parameterMock.Object);
commandMock.Setup(m => m.Parameters.Add(It.IsAny<IDbDataParameter>())).Verifiable();
commandMock.Setup(m => m.Parameters.Add(It.IsAny<IDbDataParameter>())).Verifiable();
commandMock.Setup(m => m.Parameters.Add(It.IsAny<IDbDataParameter>())).Verifiable();
var connectionMock = new Mock<IDbConnection>();
connectionMock.Setup(m => m.CreateCommand()).Returns(commandMock.Object);
//-----------------------------------------------------
readerMock.Setup(x => x.Read()).Returns(() => true);
readerMock.Setup(x => x.FieldCount).Returns(8);
readerMock.Setup(m => m.GetName(0)).Returns("id"); // the first column name
readerMock.Setup(m => m.GetName(1)).Returns("Name");
readerMock.Setup(m => m.GetName(2)).Returns("FormulationDetailId");
readerMock.Setup(m => m.GetName(3)).Returns("Comment");
readerMock.Setup(m => m.GetName(4)).Returns("FormulationDetailId");
readerMock.Setup(m => m.GetName(5)).Returns("FormulationReferenceNo");
readerMock.Setup(m => m.GetName(6)).Returns("VersionNo");
readerMock.Setup(m => m.GetName(7)).Returns("TotalRecords");
readerMock.Setup(x => x.GetValue(0)).Returns((int id) => resultModel[0].FormulationReviewComments[0].Id);
readerMock.Setup(x => x.GetValue(1)).Returns((string Name) => resultModel[0].FormulationReviewComments[0].Name);
readerMock.Setup(x => x.GetValue(2)).Returns((int FormulationDetailId) => resultModel[0].FormulationReviewComments[0].FormulationDetailId);
readerMock.Setup(x => x.GetValue(3)).Returns((string Comment) => resultModel[0].FormulationReviewComments[0].Comment);
readerMock.Setup(x => x.GetValue(4)).Returns((int FormulationDetailId) => resultModel[0].FormulationReviewComments[0].FormulationDetailId);
readerMock.Setup(x => x.GetValue(5)).Returns((string FormulationReferenceNo) => resultModel[0].FormulationReviewComments[0].FormulationReferenceNo);
readerMock.Setup(x => x.GetValue(6)).Returns((string VersionNo) => resultModel[0].FormulationReviewComments[0].VersionNo);
readerMock.Setup(x => x.GetValue(7)).Returns((int TotalRecords) => resultModel[0].FormulationReviewComments[0].TotalRecords);
readerMock.SetupSequence(m => m.Read()).Returns(true).Returns(false);
}
Here is the final unit test cases for the above
[Theory]
[InlineData(1, 1, "asdf")]
public async Task GetDashboardFormulationReviewComments1New(int a, int b, string c)
{
//var dd = (DbDataReader)dataReader;
DashboardReposReturns.GetDashBoard3();
var context2 = _unitOfWork.Setup(dd => dd.DashboardRepos.ExecGetWithStoreProcedure(It.IsAny<string>()));
// Act
var result = await _dashboardRepos.GetDashboardFormulationReviewComments(a, b, c);
//Assert
Assert.NotNull(result);
Assert.NotNull(result.Data);
Assert.True(result.Data.TotalRecords == 0);
}

Play Framework - Respond with JSON after uploading a file (multipartFormData)

I am using this code to upload an image on server , that i get from this link play upload
def upload = Action(parse.multipartFormData) { request =>
request.body
.file("picture")
.map { picture =>
val dataParts = request.body.dataParts;
val filename = Paths.get(picture.filename).getFileName
val fileSize = picture.fileSize
val contentType = picture.contentType
val picturePaths =
picture.ref.copyTo(
Paths.get(
s"/opt/docker/images/$filename"
),
replace = true
)
if (dataParts.get("firstPoint") == None) {
val pointlocation = new Point_LocationModel(
dataParts.get("step").get(0),
dataParts.get("backgroundTargetName").get(0),
dataParts.get("x").get(0),
dataParts.get("y").get(0),
dataParts.get("z").get(0),
dataParts.get("rotation").get(0),
dataParts.get("note").get(0),
dataParts.get("tag").get(0),
dataParts.get("work_session_id").get(0),
(picturePaths).toString
)
point_LocationRepository.create(pointlocation).map { data =>
Created(Json.toJson(data._2))
}
} else {
val jValuefirstPoint =
Json.parse(dataParts.get("firstPoint").get(0)).as[PointModel]
val jValuesecondPoint =
Json.parse(dataParts.get("secondPoint").get(0)).as[PointModel]
val pointlocation = new Point_LocationModel(
dataParts.get("step").get(0),
dataParts.get("backgroundTargetName").get(0),
Some(jValuefirstPoint),
Some(jValuesecondPoint),
dataParts.get("rotation").get(0),
dataParts.get("note").get(0),
dataParts.get("tag").get(0),
dataParts.get("work_session_id").get(0),
(picturePaths).toString
)
point_LocationRepository.create(pointlocation).map { data =>
logger.info(s"repoResponse: ${data}");
Created(Json.toJson(data._2))
}
}
Ok(s"picturePaths ${picturePaths}")
}
.getOrElse(Ok("Invalid Format"))
}
This code works very well, but on the response I want to get the response from the repository. How can i await for the response of the repository to return this?
Can you give me any idea how can i do it?
Thanks in advance.
If we simplify your code to the essential bits, you have:
def upload = Action(parse.multipartFormData) { request =>
request.body
.file("picture")
.map { picture =>
if (someConditionA) {
someBusinessLogicA().map { data =>
Created(Json.toJson(data._2))
}
} else {
someBusinessLogicB().map { data =>
Created(Json.toJson(data._2))
}
}
Ok(s"picturePaths ${picturePaths}")
}
.getOrElse(Ok("Invalid Format"))
}
There are 2 problems:
the return of your if/else is swallowed by the Ok(s"picturePaths ${picturePaths}")
assuming your business logic returns Future[_] you need to "propagate" the Future everywhere
Something like this should work:
def upload = Action.async(parse.multipartFormData) { request =>
request.body
.file("picture")
.map { picture =>
if (someConditionA) {
someBusinessLogicA().map { data =>
Created(Json.toJson(data._2))
}
} else {
someBusinessLogicB().map { data =>
Created(Json.toJson(data._2))
}
}
}
.getOrElse(Future.successful(Ok("Invalid Format")))
}
Notice the Action.async and the Future in the getOrElse.

Insert/Update 50 records from JSON file to SQL Table taking too much in ASP.NET MVC EF core

I am doing insert/update records from JSON file to SQL table in the single action method. I am inserting only 50 records but it takes too much time. I am new to ASP.NET Core. Don't know whether my too much for each loop creates the issue or my database logic. Please can anybody help me to correct this issue?
I am reading json and based on custom mapping, I am doing insert or update to table column from json object values.
Please look into my below code
[HttpPost]
public IActionResult InsertProductDetails()
{
int getcountProductName = (from gcPN in _context.K360MappingMasters
where gcPN.K360Catalog == "Name" && gcPN.ApiContent == baseurl
select gcPN).Count();
if (getcountProductName == 0)
{
return Json(new { Status = "error", Message = "Required ProductName catalog not yet mapped , unable to insert productdetails" });
}
else if (getcountProductName == 1)
{
try
{
using WebClient wc = new WebClient();
string contentString = wc.DownloadString(baseurl);
List<Dictionary<string, string>> ListJsonProductContent = new List<Dictionary<string, string>>();
List<string> ListProductsCheck = new List<string>();
var token = JToken.Parse(contentString);
if (token.Type == JTokenType.Array) // "["
{
ListJsonProductContent = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(contentString);
}
else if (token.Type == JTokenType.Object) // "{"
{
var ObjectResponse = JsonConvert.DeserializeObject<Dictionary<string, object>>(contentString);
foreach (var x in ObjectResponse)
{
string key = x.Key.ToString();
string val = x.Value.ToString();
foreach (var dicItemML in JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(val))
{
ListJsonProductContent.Add(dicItemML);
}
}
}
List<K360MappingMaster> ListMappedDataDb = new List<K360MappingMaster>();
var VLinqQuery = from KMM in _context.K360MappingMasters
where KMM.ApiContent != null && KMM.ApiContent == baseurl
select KMM;
ListMappedDataDb = VLinqQuery.ToList();
foreach (var dicItemML in ListJsonProductContent)
{
Dictionary<string, string> updItem = new Dictionary<string, string>();
foreach (var itemMl in dicItemML)
{
var catalogProductsCheck = _context.CatalogProducts.ToList();
var result = catalogProductsCheck.Select(s => s.Name).ToList().Contains(itemMl.Value);
if (result == true)
ListProductsCheck.Add(itemMl.Value.ToString());
if (ListMappedDataDb.Select(s => s.ApiCatalog).ToList().Contains(itemMl.Key))
{
foreach (K360MappingMaster data in ListMappedDataDb.Where(s => s.ApiCatalog == itemMl.Key))
{
if (updItem.ContainsKey(data.K360Catalog))
{
if (data.K360Catalog == "Specification")
{
updItem[data.K360Catalog] += "<p>" + itemMl.Key + " :" + itemMl.Value + "<p>";
}
else
{
updItem[data.K360Catalog] += " " + itemMl.Value;
}
}
else
{
if (data.K360Catalog == "Specification")
{
updItem.Add(data.K360Catalog, "<p>" + itemMl.Key + " :" + itemMl.Value + "<p>");
}
else
{
updItem.Add(data.K360Catalog, itemMl.Value);
}
}
}
}
dicItemML.Remove(itemMl.Key);
}
foreach (var itemM2 in updItem)
{
dicItemML.Add(itemM2.Key, itemM2.Value);
}
}
List<CatalogProduct> ListKp = new List<CatalogProduct>();
foreach (var dicItem in ListJsonProductContent)
{
CatalogProduct Ctgkp = new CatalogProduct
{
Name = dicItem.ContainsKey("Name") ? dicItem["Name"] : "No Product",
Slug = dicItem.ContainsKey("Name") ? string.Concat(dicItem["Name"].Where(c => !char.IsWhiteSpace(c))).ToLower(CultureInfo.CurrentCulture) : "No Slug",
Price = dicItem.ContainsKey("Price") ? decimal.Parse(dicItem["Price"], CultureInfo.InvariantCulture) : default,
ShortDescription = dicItem.ContainsKey("ShortDescription") ? dicItem["ShortDescription"] : null,
Description = dicItem.ContainsKey("Description") ? dicItem["Description"] : null,
Specification = dicItem.ContainsKey("Specification") ? dicItem["Specification"] : null,
RatingAverage = dicItem.ContainsKey("RatingAverage") ? double.Parse(dicItem["RatingAverage"], CultureInfo.InvariantCulture) : null,
MetaTitle = dicItem.ContainsKey("MetaTitle") ? dicItem["MetaTitle"] : null,
MetaKeywords = dicItem.ContainsKey("MetaKeywords") ? dicItem["MetaKeywords"] : null,
MetaDescription = dicItem.ContainsKey("MetaDescription") ? dicItem["MetaDescription"] : null,
Sku = dicItem.ContainsKey("Sku") ? dicItem["Sku"] : null,
Gtin = dicItem.ContainsKey("Gtin") ? dicItem["Gtin"] : null,
NormalizedName = dicItem.ContainsKey("NormalizedName") ? dicItem["NormalizedName"] : null,
StockQuantity = dicItem.ContainsKey("StockQuantity") ? int.Parse(dicItem["StockQuantity"], CultureInfo.InvariantCulture) : 50,
ReviewsCount = dicItem.ContainsKey("ReviewsCount") ? int.Parse(dicItem["ReviewsCount"], CultureInfo.InvariantCulture) : default,
DisplayOrder = dicItem.ContainsKey("DisplayOrder") ? int.Parse(dicItem["DisplayOrder"], CultureInfo.InvariantCulture) : 1,
OldPrice = dicItem.ContainsKey("OldPrice") ? decimal.Parse(dicItem["OldPrice"], CultureInfo.InvariantCulture) : null,
SpecialPrice = dicItem.ContainsKey("SpecialPrice") ? decimal.Parse(dicItem["SpecialPrice"], CultureInfo.InvariantCulture) : null,
SpecialPriceStart = dicItem.ContainsKey("SpecialPriceStart") ? DateTimeOffset.Parse(dicItem["SpecialPriceStart"], CultureInfo.InvariantCulture) : null,
SpecialPriceEnd = dicItem.ContainsKey("SpecialPriceEnd") ? DateTimeOffset.Parse(dicItem["SpecialPriceEnd"], CultureInfo.InvariantCulture) : null,
IsPublished = true,
PublishedOn = DateTimeOffset.Now,
CreatedById = 10,
IsDeleted = false,
CreatedOn = DateTimeOffset.UtcNow,
LatestUpdatedOn = DateTimeOffset.UtcNow,
LatestUpdatedById = 10,
HasOptions = false,
IsVisibleIndividually = true,
IsFeatured = true,
IsCallForPricing = false,
IsAllowToOrder = true,
StockTrackingIsEnabled = true
};
ListKp.Add(Ctgkp);
}
using (var transaction = _context.Database.BeginTransaction())
{
try
{
int numCpTotal = 0;
var catalogProducts = _context.CatalogProducts.ToList();
var config = new MapperConfiguration(cfg => cfg.CreateMap<CatalogProduct, CatalogProduct>()
.ForMember(c => c.Id, opt => opt.Ignore()));
var mapper = config.CreateMapper();
_context.ChangeTracker.AutoDetectChangesEnabled = false;
foreach (var kp in ListKp)
{
var existingRootProduct = _context.CatalogProducts.SingleOrDefault(x => x.Name == kp.Name);
if (existingRootProduct == null)
{
if (ListProductsCheck.Count > 0)
{
var firstItem = ListProductsCheck.ToList();
foreach (var item in firstItem)
{
_context.CatalogProducts.RemoveRange(_context.CatalogProducts.Where(c => c.Name == item));
_context.CoreEntities.RemoveRange(_context.CoreEntities.Where(c => c.Name == item));
_context.SaveChanges();
}
}
_context.CatalogProducts.Add(kp);
_context.SaveChanges();
CoreEntity ce = new CoreEntity
{
Name = kp.Name,
Slug = string.Concat(kp.Name.Where(c => !char.IsWhiteSpace(c))).ToLower(CultureInfo.CurrentCulture),
EntityId = kp.Id,
EntityTypeId = "Product",
};
_context.CoreEntities.Add(ce);
}
else
{
mapper.Map<CatalogProduct, CatalogProduct>(kp, existingRootProduct);
}
}
(from q in _context.K360MappingMasters
where q.ApiContent == baseurl
select q).ToList().ForEach(x => x.InsertStatusFlag = true);
_context.ChangeTracker.DetectChanges();
numCpTotal = _context.SaveChanges();
_context.ChangeTracker.AutoDetectChangesEnabled = true;
transaction.Commit();
return Json(new { Status = "success", Message = "No conflicts. " + numCpTotal + " product details saved." });
}
catch (Exception ex)
{
transaction.Rollback();
return Json(new { Status = "warning", Message = ex.Message });
throw new Exception();
}
}
}
catch (Exception ex)
{
return Json(new { Status = "warning", Message = ex.Message });
throw new Exception();
}
}
else
{
return RedirectToAction("Index");
}
}

How to get new uploaded file name in controller?

1.Can anyone suggest me how to get new uploaded file name in controller action? I'm using validation rule like..
'validators' => [
[
'name' => '\User\Validator\ImageValidator',
'options' => [
'minSize' => '1',
'maxSize' => '1024',
'newFileName' => time() . 'newFileName2',
'uploadPath' => getcwd() . '/public/uploads/platform/'
],
],
],
and it's working properly but I have no idea to how to get file name or error in controller action.
How to overwrite the minSize and maxSize error message? My validator file code is:
namespace User\Validator;
use Zend\Validator\File\Extension;
use Zend\File\Transfer\Adapter\Http;
use Zend\Validator\File\FilesSize;
use Zend\Filter\File\Rename;
use Zend\Validator\File\MimeType;
use Zend\Validator\AbstractValidator;
class ImageValidator extends AbstractValidator
{
const FILE_EXTENSION_ERROR = 'invalidFileExtention';
const FILE_NAME_ERROR = 'invalidFileName';
const FILE_INVALID = 'invalidFile';
const FALSE_EXTENSION = 'fileExtensionFalse';
const NOT_FOUND = 'fileExtensionNotFound';
const TOO_BIG = 'fileFilesSizeTooBig';
const TOO_SMALL = 'fileFilesSizeTooSmall';
const NOT_READABLE = 'fileFilesSizeNotReadable';
public $minSize = 64; //KB
public $maxSize = 1024; //KB
public $overwrite = true;
public $newFileName = null;
public $uploadPath = './data/';
public $extensions = array('jpg', 'png', 'gif', 'jpeg');
public $mimeTypes = array(
'image/gif',
'image/jpg',
'image/png',
);
protected $messageTemplates = array(
self::FILE_EXTENSION_ERROR => "File extension is not correct",
self::FILE_NAME_ERROR => "File name is not correct",
self::FILE_INVALID => "File is not valid",
self::FALSE_EXTENSION => "File has an incorrect extension",
self::NOT_FOUND => "File is not readable or does not exist",
self::TOO_BIG => "// want to overwrite these message",
self::TOO_SMALL => "// want to overwrite these message",
self::NOT_READABLE => "One or more files can not be read",
);
protected $fileAdapter;
protected $validators;
protected $filters;
public function __construct($options)
{
$this->fileAdapter = new Http();
parent::__construct($options);
}
public function isValid($fileInput)
{
$options = $this->getOptions();
$extensions = $this->extensions;
$minSize = $this->minSize;
$maxSize = $this->maxSize;
$newFileName = $this->newFileName;
$uploadPath = $this->uploadPath;
$overwrite = $this->overwrite;
if (array_key_exists('extensions', $options)) {
$extensions = $options['extensions'];
}
if (array_key_exists('minSize', $options)) {
$minSize = $options['minSize'];
}
if (array_key_exists('maxSize', $options)) {
$maxSize = $options['maxSize'];
}
if (array_key_exists('newFileName', $options)) {
$newFileName = $options['newFileName'];
}
if (array_key_exists('uploadPath', $options)) {
$uploadPath = $options['uploadPath'];
}
if (array_key_exists('overwrite', $options)) {
$overwrite = $options['overwrite'];
}
$fileName = $fileInput['name'];
$fileSizeOptions = null;
if ($minSize) {
$fileSizeOptions['min'] = $minSize*1024 ;
}
if ($maxSize) {
$fileSizeOptions['max'] = $maxSize*1024 ;
}
if ($fileSizeOptions) {
$this->validators[] = new FilesSize($fileSizeOptions);
}
$this->validators[] = new Extension(array('extension' => $extensions));
if (! preg_match('/^[a-z0-9-_]+[a-z0-9-_\.]+$/i', $fileName)) {
$this->error(self::FILE_NAME_ERROR);
return false;
}
$extension = pathinfo($fileName, PATHINFO_EXTENSION);
if (! in_array($extension, $extensions)) {
$this->error(self::FILE_EXTENSION_ERROR);
return false;
}
if ($newFileName) {
$destination = $newFileName.".$extension";
if (! preg_match('/^[a-z0-9-_]+[a-z0-9-_\.]+$/i', $destination)) {
$this->error(self::FILE_NAME_ERROR);
return false;
}
} else {
$destination = $fileName;
}
$renameOptions['target'] = $uploadPath.$destination;
$renameOptions['overwrite'] = $overwrite;
$this->filters[] = new Rename($renameOptions);
$this->fileAdapter->setFilters($this->filters);
$this->fileAdapter->setValidators($this->validators);
if ($this->fileAdapter->isValid()) {
$this->fileAdapter->receive();
return true;
} else {
$messages = $this->fileAdapter->getMessages();
if ($messages) {
$this->setMessages($messages);
foreach ($messages as $key => $value) {
$this->error($key);
}
} else {
$this->error(self::FILE_INVALID);
}
return false;
}
}
}
I'm new to Zend framework so unable to understand how this validator code is working.
Thank you