ASP.NET Cloudinary getting response - asp.net

I have little problem with using Cloudinary, I can upload the images it works fine but I guess i cant get any response from Cloudinary. Suggestion? about required parameters
Handler
public async Task<Photo> Handle(Command request, CancellationToken cancellationToken)
{
var photoUploadResult = _photoAccessor.AddPhoto(request.File);
var photo = new Photo
{
Url = photoUploadResult.Url,
Id = photoUploadResult.PublicId
};
var success = await _context.SaveChangesAsync() > 0;
if (success) return photo;
throw new Exception("Problem saving changes");
}
Accessor
public PhotoUploadResult AddPhoto(IFormFile file)
{
var uploadResult = new ImageUploadResult();
if (file.Length > 0)
{
using (var stream = file.OpenReadStream())
{
var uploadParams = new ImageUploadParams
{
File = new FileDescription(file.FileName, stream)
};
uploadResult = _cloudinary.Upload(uploadParams);
}
}
if (uploadResult.Error != null)
throw new Exception(uploadResult.Error.Message);
return new PhotoUploadResult
{
PublicId = uploadResult.PublicId,
Url = uploadResult.SecureUri.AbsoluteUri
};
}

What do you get in response? Can you try:
string cloud_name = "<Cloud Name>";
string ApiKey = "<Api-Key>";
string ApiSecret = "<Api-Secret>";
Account account = new Account(cloud_name,ApiKey,ApiSecret);
Cloudinary cloudinary = new Cloudinary(account);
cloudinary.Api.Timeout = int.MaxValue;
var ImguploadParams = new ImageUploadParams()
{
File = new FileDescription(#"http://res.cloudinary.com/demo/image/upload/couple.jpg"),
PublicId = "sample",
Invalidate = true,
Overwrite = true
};
var ImguploadResult = cloudinary.Upload(ImguploadParams);
Console.WriteLine(ImguploadResult.SecureUri);

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"
};
}
}

How can I make proper request for the Identity Server Token Endpoint?

I tried to send an api call to the identity server via .net 6 console application.
Here is the request:
public static async Task<WorkflowResponse> PostRequestToIdentityAsync()
{
var url = "http://didentity/connect/token";
IdentityRequestDataVM identityRequestDataVM = new IdentityRequestDataVM();
identityRequestDataVM.username = "csm";
identityRequestDataVM.password = "MjAyMjox";
identityRequestDataVM.grant_type = "password";
identityRequestDataVM.scope = "m_gln m_msd";
string jsonString = JsonConvert.SerializeObject(identityRequestDataVM);
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(url),
Content = new StringContent(jsonString),
Headers =
{
{"X-Login","override"}
}
};
var user = "gclt";
var password = "glsrt";
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes($"{user}:{password}")));
HttpResponseMessage message = await httpClient.SendAsync(request);
if (message.StatusCode == System.Net.HttpStatusCode.OK)
{
var contents = await message.Content.ReadAsStringAsync();
WorkflowResponse workflowResponse = JsonConvert.DeserializeObject<WorkflowResponse>(contents);
return workflowResponse;
}
else
{
throw new Exception(await message.Content.ReadAsStringAsync());
}
}
}
But, it returned 400 err code (Bad request), is there any mistake in the code snippet ?
It is working fine with postman.

Xamarin Http Request Timeout Issue

I have a mobile application based on Xamarin and a Web API based on .Net Core. Mobile app consumes methods of Web API via HttpClient. The code below is my base method to call any Web API method and the point is I want to set a timeout but could not achieved to set the exact timeout value whatever I have implemented. Tried Timespan.FromSeconds() or TimeSpan.FromMilliseconds() etc. When client makes a request to Web API, a loader is displayed to lock UI and removed after API response. Some clients gave me a feedback that the loader is displayed forever and request never ends. Maybe, the server is unreachable in this particular time or internet connection is broken for client etc. All I want to set a timeout and break the request and display an alert message to client. Of course, I googled and tried too much as mentioned but no result. If anyone can help me, will be appreciated.
public async Task<BaseResponseModel> Post(BasePostModel postModel)
{
var responseModel = new BaseResponseModel();
var json = postModel.ToString();
var jsonParam = new StringContent(json, Encoding.UTF8, "application/json");
var isPosted = true;
var clientHandler = new HttpClientHandler()
{
AllowAutoRedirect = true,
};
var url = GetURL(postModel.UrlKey);
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
ContractResolver = new DefaultContractResolver(),
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
var client = new HttpClient(clientHandler);
//client.Timeout = TimeSpan.FromSeconds(10);
//var cancellationTokenSource = new CancellationTokenSource();
//cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(10));
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("X-Env", "MOBILE_API");
AttachToken(ref client, responseModel.Id);
try
{
if (Preferences.ContainsKey("UserJwtExprieDate"))
{
var expiryDate = Preferences.Get("UserJwtExprieDate", null);
if (DateTime.Now > DateTime.Parse(expiryDate))
{
Preferences.Remove("UserJwtExprieDate");
Preferences.Remove("HomePageInformation");
int index = Xamarin.Forms.Application.Current.MainPage.Navigation.NavigationStack.Count - 1;
Page currPage = Xamarin.Forms.Application.Current.MainPage.Navigation.NavigationStack[index];
if (currPage as SigninForFactorOne != null)
{}
else
{
App.LogoutUser();
}
}
else
{
var response = await client.PostAsync(url, jsonParam);
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
var resultModel = JsonConvert.DeserializeObject<BaseResponseModel>(result, settings);
if (resultModel.ErrorType == APIErrorTypes.NULL)
{
if (resultModel.IsSucceed)
{
responseModel.Data = resultModel.Data;
}
else
{
responseModel.Error = resultModel.Error;
}
responseModel.Message = resultModel.Message;
}
else
{
responseModel.Error = "Token Expried Date.";
Preferences.Remove("UserJwtExprieDate");
Preferences.Remove("HomePageInformation");
App.LogoutUser();
}
}
else
{
new AppException(new Exception("HTTP Client response is not succeed!"), responseModel.Id);
isPosted = false;
}
}
}
else
{
var response = await client.PostAsync(url, jsonParam);
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
var resultModel = JsonConvert.DeserializeObject<BaseResponseModel>(result, settings);
if (resultModel.ErrorType == APIErrorTypes.NULL)
{
if (resultModel.IsSucceed)
{
responseModel.Data = resultModel.Data;
}
else
{
responseModel.Error = resultModel.Error;
}
responseModel.Message = resultModel.Message;
}
else
{
responseModel.Error = "Token Expried Date.";
Preferences.Remove("UserJwtExprieDate");
Preferences.Remove("HomePageInformation");
App.LogoutUser();
}
}
else
{
new AppException(new Exception("HTTP Client response is not succeed!"), responseModel.Id);
isPosted = false;
}
}
}
catch (Exception ex)
{
new AppException(ex, responseModel.Id, 500, "anonymous.user", "Unable to post data to API!");
isPosted = false;
}
finally
{
if (!isPosted)
{
responseModel.Error = AppConfiguration.GetSystemMessage(contactYourSystemAdministratorMessage);
responseModel.Message = AppConfiguration.GetSystemMessage(contactYourSystemAdministratorMessage);
}
}
return responseModel;
}
I've used the solution below to manually set a time-out which works fine.
internal class TimeOutHandler : DelegatingHandler
{
private readonly TimeSpan TimeOut;
public TimeOutHandler(TimeSpan timeOut) => TimeOut = timeOut;
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage req, CancellationToken ct)
{
using (var ctTimeOut = CancellationTokenSource.CreateLinkedTokenSource(ct))
{
ctTimeOut.CancelAfter(TimeOut);
try
{
return await base.SendAsync(req, ctTimeOut.Token);
}
catch (OperationCanceledException) when (!ct.IsCancellationRequested)
{
throw new TimeoutException();
}
}
}
}
How to use
var interval = TimeSpan.FromSeconds(10);
var handler = new TimeOutHandler(interval)
{
InnerHandler = new HttpClientHandler()
};
var client = new HttpClient(handler);
For more information, check out: https://thomaslevesque.com/2018/02/25/better-timeout-handling-with-httpclient/

How to POST file upload using axios to ASP.NET Controller?

I render image uploader in html using this function.
which correctly display image in page. How should I post this FileReader to controller?
showCoverImage(e) {
var file = e.target.files[0];
var imageType = /image.*/;
if (!file.type.match(imageType)) {
return;
}
var img = document.getElementById("thumbnail");
img.file = file;
const fileName = document.querySelector('#cover-image .file-name');
fileName.textContent = file.name;
var reader = new FileReader();
reader.onload = (function (aImg) {
return function (e) {
aImg.src = e.target.result;
};
})(img);
reader.readAsDataURL(file);
}
I have controller method for upload using IFromFIle. It receives IFromFIle as parameter.
[HttpPost("/upload/coverImage")]
public async Task<IActionResult> uploadEditorImage(IFormFile upload)
{
var fileName = upload.FileName;
var path = Path.Combine(_mainDirectory, "images");
var pathPath = Path.Combine(path, fileName);
int isUpload = 1;
string errorMsg = string.Empty;
try
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
var stream = new FileStream(pathPath, FileMode.Create);
await upload.CopyToAsync(stream);
await stream.FlushAsync();
return new JsonResult(new {uploaded:1});
}
Upload call using axios. It posts to controller IFromFile as null.
onCoverImageUpload() {
this.loading = true;
const formData = new FormData();
formData.append("file", this.selectedCoverImage);
let config = {
headers: {
"Content-Type": "multipart/form-data"
}
};
axios.post('/upload/coverImage', formData, config)
.then(res => {
console.log(res);
});
}
First, ensure you could get the file by this.selectedCoverImage.
Second, the name is inconsistent. Change the name file in the formData to upload
formData.append("upload", this.selectedCoverImage);
Finally I changed my controller implementation. Now working.
[HttpPost("/upload/coverImage")]
public async Task<IActionResult> uploadEditorImage()
{
var upload = Request.Form.Files[0];
var fileName = upload.FileName;
var path = Path.Combine(_mainDirectory, "images");
var pathPath = Path.Combine(path, fileName);
string errorMsg = string.Empty;
try {
if (!Directory.Exists(path)) {
Directory.CreateDirectory(path);
}
var stream = new FileStream(pathPath, FileMode.Create);
await upload.CopyToAsync(stream);
await stream.FlushAsync();
return new JsonResult(new {uploaded:1});
}

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.

Resources