Update image from www/Upload/DP/image.png asp.net core 2 - asp.net-core-2.0

I have a code for image upload and that working as expected, in my way image is DP display picture of user.
Create.cshtml
<div class="form-group">
<label asp-for="DP" class="control-label">Profile Image</label>
<input type="file" name="DP" asp-for="DP" class="form-control" />
<span asp-validation-for="DP" class="text-danger"></span>
</div>
Controller Action
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Profile profile, IFormFile DP)
{
if (ModelState.IsValid)
{
var id = _userManager.GetUserName(HttpContext.User);
var fileName = Path.Combine(_environment.WebRootPath +"/Upload/DP/", Path.GetFileName(id+".png"));
DP.CopyTo(new FileStream(fileName,FileMode.Create));
//profile.DP = fileName;
ViewBag.fileName = fileName;
var create = new Profile {
userName = profile.userName,
uId = profile.uId,
rId = profile.rId,
Mobile = profile.Mobile,
Job = profile.Job,
City = profile.City,
Address = profile.Address,
dof = profile.dof,
DP = profile.DP = Path.GetFileName(id+".png"),
CreatedOn = profile.CreatedOn,
Status = profile.Status
};
_context.Add(profile);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["rId"] = new SelectList(_context.Set<CharityRole>(), "rId", "Name", profile.rId);
return View(profile);
}
Question: How I can delete existing image and add a new one with same name bcz its display on user profile like:
<img src="#Url.Content("~/Upload/DP/"+ _userManager.GetUserName(User)+".png")">

There are two issues in your post.
You need to use Using for FileStream, otherwise, the filestream will be not disposed.
using (var fileStream = new FileStream(fileName, FileMode.Create))
{
await DP.CopyToAsync(fileStream);
}
You need to pass create instead of profile to _context.Add.
Here is the complete demo code:
public async Task<IActionResult> Create(Profile profile, IFormFile DP)
{
if (ModelState.IsValid)
{
var id = _userManager.GetUserName(HttpContext.User);
var fileName = Path.Combine(_environment.WebRootPath + "/Upload/DP/", Path.GetFileName(id + ".png"));
using (var fileStream = new FileStream(fileName, FileMode.Create))
{
await DP.CopyToAsync(fileStream);
}
var create = new Profile
{
UserName = profile.UserName,
DP = Path.GetFileName(id + ".png")
};
_context.Add(create);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(profile);
}

Related

display data dynamically on a razor page

There's a console app that uses async method for web site scraping.
using Microsoft.AspNetCore.Authentication;
using HtmlAgilityPack;
using System.Net;
class Program
{
static void Main(string[] args)
{
submainAsync();
Console.ReadKey();
}
private static async Task<bool> submainAsync()
{
ADManager adManager = new ADManager();
List<Person> people;
people = adManager.GetPeopleByPath("ls.local");
string cookie = "0123456789";
if (cookie == String.Empty)
{
Console.WriteLine("check your password");
return false;
}
var peopleAS = getPIDsAsync(people, cookie);
int total = people.Count;
await foreach (Person prs in peopleAS)
{
Console.WriteLine("next is {0} countdown {1}", prs.samAccountName, total--);
}
return true;
}
static private async IAsyncEnumerable<Person> getPIDsAsync(List<Person> people, string inCookie)
{
foreach (Person prs in people)
{
var baseAddress = new Uri("http://192.168.1.100");
using (var handler = new HttpClientHandler { UseCookies = false })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
string request = "/doc/admin/directories.asp?act=test&id=META&login=" + prs.samAccountName + "&s=DEFAULT";
var message = new HttpRequestMessage(HttpMethod.Get, request);
message.Headers.Add("Cookie", "t%5FDEFAULT%5Fadmin="+ inCookie);
var result = await client.SendAsync(message);
var resultString = await result.Content.ReadAsStringAsync();
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(resultString);
var node = doc.DocumentNode.SelectSingleNode("//*[#id=\"value\"]");
var val = node.InnerText;
prs.PID = node.InnerText;
}
yield return prs;
}
}
}
[ yield return, await foreach ] writelines out data nicely as soon as the next piece of data is ready. Now, I moved the code from a console app to a razor page app, so submainAsync() is called from OnPost. The question is - how can I display scraped data in a table on a razor page? My goal is to display the data dynamically, as soon as the next piece is ready, just like it happens in the Console.
Would someone please point me in the right direction?

Azure Table Storage not saving all object properties

I have a problem with the Azure Table Storage. What I'm trying to achieve is saving the ChangeToken of the SharePoint list in order to use the webhooks properly.
Here is the code:
public class TablesHelper
{
private static readonly string TokenTableName = "TokenTable";
public static async Task<ListChangeToken> GetChangeTokenForListAsync(string listId)
{
var retrieveOperation = TableOperation.Retrieve<ListChangeToken>("Lists", listId, new List<string>() { "ChangeToken" });
var tableReference = await GetTableReferenceAsync(TokenTableName);
var tableResult = await tableReference.ExecuteAsync(retrieveOperation);
if(tableResult.Result != null)
{
return tableResult.Result as ListChangeToken;
}
return null;
}
public static async Task SaveChangeTokenForListAsync(ListChangeToken changeToken)
{
var insertOperation = TableOperation.Insert(changeToken);
var tableReference = await GetTableReferenceAsync(TokenTableName);
var result = await tableReference.ExecuteAsync(insertOperation);
}
private static async Task<CloudTable> GetTableReferenceAsync(string tableName)
{
var storageAccount = CloudStorageAccount.Parse(ConfigurationHelper.CloudStorage);
var tableClient = storageAccount.CreateCloudTableClient();
var reference = tableClient.GetTableReference(tableName);
await reference.CreateIfNotExistsAsync();
return reference;
}
}
The ListChangeToken class:
public class ListChangeToken : TableEntity
{
public ListChangeToken(string listId, string changeToken)
{
this.PartitionKey = "Lists";
this.RowKey = listId;
this.ChangeToken = changeToken;
}
public ListChangeToken() { }
public string ChangeToken { get; set;}
}
As per request, the function calling TablesHelper:
[FunctionName("EventHandler")]
public static async Task Run([QueueTrigger("events", Connection = "CloudStorage")]string myQueueItem, TraceWriter log)
{
var notificationGroup = Newtonsoft.Json.JsonConvert.DeserializeObject<NotificationGroup>(myQueueItem);
var contextHelper = new ContextHelper();
foreach (var notification in notificationGroup.Value)
{
UriBuilder uriBuilder = new UriBuilder();
uriBuilder.Scheme = "https";
uriBuilder.Host = ConfigurationHelper.TenantDomain;
uriBuilder.Path = notification.SiteUrl;
using (var ctx = contextHelper.GetAppOnlyContext(uriBuilder.ToString()))
{
//Read change token
var currentChangeToken = await TablesHelper.GetChangeTokenForListAsync(notification.Resource);
if(currentChangeToken == null)
{
log.Error($"No change token found for list {notification.Resource}. This is a NO GO. Please use the '/api/Setup' function.");
}
var listId = Guid.Parse(notification.Resource);
var changes = await CSOMHelper.GetListItemChangesAsync(ctx, listId, currentChangeToken.ChangeToken);
if(changes.Count > 0)
{
var lastChange = changes[changes.Count - 1];
//Save the last change token
var changeTokenValue = lastChange.ChangeToken.StringValue;
await TablesHelper.SaveChangeTokenForListAsync(new ListChangeToken(
notification.Resource,
changeTokenValue
));
await HandleChanges(ctx, changes);
}
}
}
log.Info($"C# Queue trigger function processed: {myQueueItem}");
}
The problem is that always, when using the "GetChangeTokenForListAsync" the Entity is received properly, but the .ChangeToken property is always null. It is also not visible when browsing with the Azure Storage Explorer. What am I doing wrong here?
The issue is related to the Azure Storage Emulator (V. 5.7.0.0). The same code works perfectly when working with the "live" Azure.

Xamarin.iOS Cannot display photo in Push Notification

I have a Notification Service Extension and an AppGroup. I save a photo from camera in the PCL project and copy it to the App Group Container (shared folder).
In the Notification Service Extension I try to download the photo from the App Group container and attach it to the notification but it just does not display in the notification.
I also cannot debug the Service Extension to see what is going. As far as I know that is not possible currently still in Xamarin unless someone can correct me on that please.
Here is the code:
1.in my PCL I save the photo to the AppGroup when a save button is pressed:
private void ButtonSavePhoto_Clicked(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(photoFilePath))
{
Preferences.Set(AppConstants.CUSTOM_PICTURE_FILE_PATH, photoFilePath);
Preferences.Set(AppConstants.CUSTOM_PHOTO_SET_KEY, true);
if (Device.RuntimePlatform == Device.iOS)
{
bool copiedSuccessfully = DependencyService.Get<IPhotoService>().CopiedFileToAppGroupContainer(photoFilePath);
if (copiedSuccessfully)
{
var customPhotoDestPath = DependencyService.Get<IPhotoService>().GetAppContainerCustomPhotoFilePath();
// save the path of the custom photo in the AppGroup container to pass to Notif Extension Service
DependencyService.Get<IGroupUserPrefs>().SetStringValueForKey("imageAbsoluteString", customPhotoDestPath);
// condition whether to use custom photo in push notification
DependencyService.Get<IGroupUserPrefs>().SetBoolValueForKey("isCustomPhotoSet", true);
}
}
buttonSavePhoto.IsEnabled = false;
}
}
2.in my iOS project, Dependency injection calls this method when pressing save button:
public bool CopiedFileToAppGroupContainer(string filePath)
{
bool success = false;
string suiteName = "group.com.company.appName";
var appGroupContainerUrl = NSFileManager.DefaultManager.GetContainerUrl(suiteName);
var appGroupContainerPath = appGroupContainerUrl.Path;
var directoryNameInAppGroupContainer = Path.Combine(appGroupContainerPath, "Pictures");
var filenameDestPath = Path.Combine(directoryNameInAppGroupContainer, AppConstants.CUSTOM_PHOTO_FILENAME);
try
{
Directory.CreateDirectory(directoryNameInAppGroupContainer);
if (File.Exists(filenameDestPath))
{
File.Delete(filenameDestPath);
}
File.Copy(filePath, filenameDestPath);
success = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return success;
}
Now the path for the photo in the App Group container is:
/private/var/mobile/Containers/Shared/AppGroup/12F209B9-05E9-470C-9C9F-AA959D940302/Pictures/customphoto.jpg
3.Finally in the Notification Service Extension I try to attach the photo to the push notification:
public override void DidReceiveNotificationRequest(UNNotificationRequest request, Action<UNNotificationContent> contentHandler)
{
ContentHandler = contentHandler;
BestAttemptContent = (UNMutableNotificationContent)request.Content.MutableCopy();
string imgPath;
NSUrl imgUrl;
string notificationBody = BestAttemptContent.Body;
string notifBodyInfo = "unknown";
string suiteName = "group.com.company.appname";
NSUserDefaults groupUserDefaults = new NSUserDefaults(suiteName, NSUserDefaultsType.SuiteName);
string pref1_value = groupUserDefaults.StringForKey("user_preference1");
string[] notificationBodySplitAtDelimiterArray = notificationBody.Split(',');
userPrefRegion = notificationBodySplitAtDelimiterArray[0];
bool isCustomAlertSet = groupUserDefaults.BoolForKey("isCustomAlert");
bool isCustomPhotoSet = groupUserDefaults.BoolForKey("isCustomPhotoSet");
string alarmPath = isCustomAlertSet == true ? "customalert.wav" : "default_alert.m4a";
if (isCustomPhotoSet)
{
// this is the App Group url of the custom photo saved in PCL
imgPath = groupUserDefaults.StringForKey("imageAbsoluteString");
}
else
{
imgPath = null;
}
if (imgPath != null )
{
imgUrl = NSUrl.FromString(imgPath);
}
else
{
imgUrl = null;
}
if (!string.IsNullOrEmpty(pref1_value))
{
if (BestAttemptContent.Body.Contains(pref1_value))
{
if (imgUrl != null)
{
// download the image from the AppGroup Container
var task = NSUrlSession.SharedSession.CreateDownloadTask(imgUrl, (tempFile, response, error) =>
{
if (error != null)
{
ContentHandler(BestAttemptContent);
return;
}
if (tempFile == null)
{
ContentHandler(BestAttemptContent);
return;
}
var cache = NSSearchPath.GetDirectories(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomain.User, true);
var cachesFolder = cache[0];
var guid = NSProcessInfo.ProcessInfo.GloballyUniqueString;
var fileName = guid + "customphoto.jpg";
var cacheFile = cachesFolder + fileName;
var attachmentUrl = NSUrl.CreateFileUrl(cacheFile, false, null);
NSError err = null;
NSFileManager.DefaultManager.Copy(tempFile, attachmentUrl, out err);
if (err != null)
{
ContentHandler(BestAttemptContent);
return;
}
UNNotificationAttachmentOptions options = null;
var attachment = UNNotificationAttachment.FromIdentifier("image", attachmentUrl, options, out err);
if (attachment != null)
{
BestAttemptContent.Attachments = new UNNotificationAttachment[] { attachment };
}
});
task.Resume();
}
BestAttemptContent.Title = "My Custom Title";
BestAttemptContent.Subtitle = "My Custom Subtitle";
BestAttemptContent.Body = "Notification Body";
BestAttemptContent.Sound = UNNotificationSound.GetSound(alarmPath);
}
}
else
{
pref1_value = "error getting extracting user pref";
}
// finally display customized notification
ContentHandler(BestAttemptContent);
}
/private/var/mobile/Containers/Shared/AppGroup/12F209B9-05E9-470C-9C9F-AA959D940302/Pictures/customphoto.jpg
From shared code, when image getting from AppGroup .You can check the file path whether work in this project.
imgPath = groupUserDefaults.StringForKey("imageAbsoluteString");
If not getting file from this path. You can get Url from AppGroup directly.Here is a sample as follow:
var FileManager = new NSFileManager();
var appGroupContainer = FileManager.GetContainerUrl("group.com.company.appName");
NSUrl fileURL = appGroupContainer.Append("customphoto.jpg", false);
And if fileURL can not be directly used, also can convert to NSData and save to local file system. This also can be a try.
Here is a sample below that grabs from local file system:
public static void Sendlocalnotification()
{
var localURL = "...";
NSUrl url = NSUrl.FromString(localURL) ;
var attachmentID = "image";
var options = new UNNotificationAttachmentOptions();
NSError error;
var attachment = UNNotificationAttachment.FromIdentifier(attachmentID, url, options,out error);
var content = new UNMutableNotificationContent();
content.Attachments = new UNNotificationAttachment[] { attachment };
content.Title = "Good Morning ~";
content.Subtitle = "Pull this notification ";
content.Body = "reply some message-BY Ann";
content.CategoryIdentifier = "message";
var trigger1 = UNTimeIntervalNotificationTrigger.CreateTrigger(0.1, false);
var requestID = "messageRequest";
var request = UNNotificationRequest.FromIdentifier(requestID, content, trigger1);
UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
{
if (err != null)
{
Console.Write("Notification Error");
}
});
}

How to save Rotativa PDF on server

I am using Rotativa to generate PDF in my "MVC" application. How can I save Rotativa PDF? I need to save the document on a server after all the process is completed.
Code below:
public ActionResult PRVRequestPdf(string refnum,string emid)
{
var prv = functions.getprvrequest(refnum, emid);
return View(prv);
}
public ActionResult PDFPRVRequest()
{
var prv = Session["PRV"] as PRVRequestModel;
byte[] pdfByteArray = Rotativa.WkhtmltopdfDriver.ConvertHtml("Rotativa", "Approver", "PRVRequestPdf");
return new Rotativa.ViewAsPdf("PRVRequestPdf", new { refnum = prv.rheader.request.Referenceno });
}
You can give this a try
var actionResult = new ActionAsPdf("PRVRequestPdf", new { refnum = prv.rheader.request.Referenceno, emid = "Whatever this is" });
var byteArray = actionResult.BuildPdf(ControllerContext);
var fileStream = new FileStream(fullPath, FileMode.Create, FileAccess.Write);
fileStream.Write(byteArray, 0, byteArray.Length);
fileStream.Close();
If that doesn't do the trick then, you can follow the answers here
Just make sure if you do it this way not to have PRVRequestPdf return as a PDF View, rather a normal View like you have above (only mention as managed to fall foul of that myself causing lots of fun).
Another useful answer:
I found the solution here
var actionPDF = new Rotativa.ActionAsPdf("YOUR_ACTION_Method", new { id = ID, lang = strLang } //some route values)
{
//FileName = "TestView.pdf",
PageSize = Size.A4,
PageOrientation = Rotativa.Options.Orientation.Landscape,
PageMargins = { Left = 1, Right = 1 }
};
byte[] applicationPDFData = actionPDF.BuildPdf(ControllerContext);
This is the original thread
You can achieve this with ViewAsPdf.
[HttpGet]
public ActionResult SaveAsPdf(string refnum, string emid)
{
try
{
var prv = functions.getprvrequest(refnum, emid);
ViewAsPdf pdf = new Rotativa.ViewAsPdf("PRVRequestPdf", prv)
{
FileName = "Test.pdf",
CustomSwitches = "--page-offset 0 --footer-center [page] --footer-font-size 8"
};
byte[] pdfData = pdf.BuildFile(ControllerContext);
string fullPath = #"\\server\network\path\pdfs\" + pdf.FileName;
using (var fileStream = new FileStream(fullPath, FileMode.Create, FileAccess.Write))
{
fileStream.Write(pdfData, 0, pdfData.Length);
}
return Json(new { isSuccessful = true }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
//TODO: ADD LOGGING
return Json(new { isSuccessful = false, error = "Uh oh!" }, JsonRequestBehavior.AllowGet);
//throw;
}
}
You can simply try this:
var fileName = string.Format("my_file_{0}.pdf", id);
var path = Server.MapPath("~/App_Data/" + fileName);
System.IO.File.WriteAllBytes(path, pdfByteArray );

Is there are more elegant way of getting arbitrary javascript objects by id, when checkboxes are marked?

Wannt to give the user the possibility to select people via checkboxes in a list.
This sample works, but I would like to know, if you would do it the same way.
The main problem is, that javascript arbitrary objects cannot be compared against easily. So there must be a mapping.
Is this ok so? I don't want to create a custom-binding for this, where I could defined an Id field in the binding.
function Person(id, name, age) {
this.id = id;
this.name = name;
this.age = age;
}
function Party(id, name, persons) {
var self = this;
this.id = id;
this.name = name;
this.persons = ko.observableArray(persons);
this.persons_checked = ko.observableArray(); //<--- for the checkboxes
this.persons_checked.subscribe(function(newValue) {
var mapped = [];
mapped = $.map(newValue, function(id) {
return $.grep(listOfPeople, function(n) { return n.id == id; }); });
self.persons(mapped);
});
}
Complete Sample here: http://jsbin.com/ukipek/6/edit
Thank you
The simplest solution is to use knockoutjs 3.x and not 2.x, and it is magically done !
I've taken your example and modified it:
The HTML part:
<h1 data-bind="text: party.name"></h1>
<ul data-bind="foreach: people">
<li>
<input type="checkbox" data-bind="checkedValue: $data, checked: $root.party.persons_checked, attr: {value: id}">
<span data-bind="text:name"></span>
</li>
</ul>
And the JS part:
function Person(id, name, age) {
var self = this;
self.id = id;
self.name = name;
self.age = age;
}
function Party(id, name, persons) {
var self = this;
self.id = id;
self.name = name;
self.persons = ko.observableArray(persons);
self.persons_checked = ko.observableArray();
}
var listOfPeople = [
new Person(1, 'Fred', 25),
new Person(2, 'Joe', 60),
new Person(3, 'Sally', 43)];
var viewModel = function() {
var self = this;
this.party = new Party(1, "Weihnachtsfeier1", []);
this.people = ko.observableArray(listOfPeople);
};
ko.applyBindings(new viewModel());
No more mappings, knockoutjs handles everything alone :-)
You can have a look at this jsbin if you want : http://jsbin.com/sasuvuwabu/1/edit
Hope that helps !

Resources