url.action doesn't generate url in asp.net mvc - asp.net-mvc

I am trying to pass image url and id number to SaveImage() function in DataController with #Url.Action() but it is not working.
I debugged the program and it seems that after the url.action method, a method named Dispose is being activated.
I saw other answers to similar questions but they didn't help me because I already use this: ' ' and not this: " " and I didn't use Jquery or Ajax.
my js function:
<script language="JavaScript">
var obj = #Html.Raw(Json.Encode(Model));
var uri;
function take_snapshot() {
Webcam.snap(function (data_uri) {
document.getElementById('results').innerHTML =
'<img src="' +
data_uri +
'"/>';
//uri = data_uri;
var id = obj.id;
alert("debug 2");
var url = '#Url.Action("SaveImage","Data")';
window.location.href = url + '?im_url=' + data_uri + '&id=' + id;
});
}
</script>
SaveImage() method:
public ActionResult SaveImage(String im_url, String id)
{
int x = Int32.Parse(id);
string s = im_url;
return View();
}
the Dispose function that was created automatically:
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}

It seems that your url is not generating fine. Please use this code to generate your url.
var link = '#Url.Action("SaveImage","Data", new{ im_url="-1", id="-2"})'.replace("-1",data_uri).replace("-2",id);
window.location.href = link;
Hopefully it will resolve your problem.

I don't know what the problem was but I solved it, I moved the line that generates the url outside the webcam function.
from:
function take_snapshot() {
Webcam.snap(function (data_uri) {
document.getElementById('results').innerHTML =
'<img src="' +
data_uri +
'"/>';
//uri = data_uri;
var id = obj.id;
alert("debug 2");
var url = '#Url.Action("SaveImage","Data")';
window.location.href = url + '?im_url=' + data_uri + '&id=' + id;
});
}
to:
function take_snapshot() {
var url = '#Url.Action("SaveImage","Data")';
Webcam.snap(function (data_uri) {
document.getElementById('results').innerHTML =
'<img src="' +
data_uri +
'"/>';
//uri = data_uri;
var id = obj.id;
alert("debug 2");
window.location.href = url + '?im_url=' + data_uri + '&id=' + id;
});
}

Related

How to convert array to send as query string?

In my view, I have checkboxes and some data displayed and button on each row to approve or reject requests put up.
I want to send my integer array to my action method but this cannot be done by just sending it to action query parameters and it would be like the picture below:
public int[] Ids
{
get { return new int[] { 1, 2, 3 }; }
set {}
}
public ActionResult Approval([ModelBinder(typeof(IntArrayModelBinder))] int[] ids)
{
...
return View(...);
}
#Html.ActionLink("Approve", "Approval", new {id = item.Ids, approvalAction = "approve"})
How do I implement the checkboxes to be checked and hover of the approve/reject actionlink will show the url with ../ids=1&ids=2&ids=3 instead of System.Int32[]?
Option 1: Send your array as a comma-separated string and then split them in your action like this :
#Html.ActionLink("Approve", "Approval", new { id = string.Join("," , Ids), approvalAction = "approve" } )
your action :
public ActionResult YourAction(string id , string approvalAction)
{
var ids = id.Split(',');
//rest of your action method business
}
Option 2:
another way to achieve your exactly url is to create your URL like this :
var baseUrl = Url.Action("YourAction", "YourController", null, Request.Url.Scheme);
var uriBuilder = new UriBuilder(baseUrl);
uriBuilder.Query = string.Join("&", Ids.Select(x => "ids=" + x));
string url = uriBuilder.ToString();
url += "&approvalAction=approve"
and your action would be like this :
public ActionResult YourAction(int[] ids , string approvalAction)
{}
<script>
function multiSelect(selectedArray, action) {
if (selectedArray[0] === undefined) {
alert("You have not selected any employee");
}
//example url
//..?ids=1&ids=2&ids=3&aprovalAction=approve
else {
var param = "";
var currUrl = "";
var idUrl = "";
idUrl = "ids=" + selectedArray[0];
for (var i = 1; i < selectedArray.length; ++i) {
idUrl += "&ids=" + selectedArray[i];
}
switch (action) {
case "Approve":
param = "approve";
break;
case "Reject":
param = "reject";
break;
}
currUrl = "approvalAction=" + param;
window.location.href = "?" + idUrl + "&" + currUrl;
}
}
</script>
<script>
$('#MultiApproveBtn').click(function () {
var selected = $('input[type=checkbox]:checked').map(function (_, el) {
return $(el).val();
}).get();
var x = document.getElementById("MultiApproveBtn").value;
//alert(selected);
multiSelect(selected, x);
})
</script>
<script>
$('#MultiRejectBtn').click(function () {
var selected = $('input[type=checkbox]:checked').map(function (_, el) {
return $(el).val();
}).get();
var x = document.getElementById("MultiRejectBtn").value;
//alert(selected);
multiSelect(selected, x);
})
</script>

how to upload file with ng-file-upload in asp.mvc

how to upload file with ng-file-upload in asp.mvc ?
I'm using this code to upload file with ng-file-upload in asp.mvc :
public class HomeController : Controller, IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
bool result;
try
{
HttpPostedFile file = context.Request.Files[0];
if (file.ContentLength > 0)
{
string nameFile = Guid.NewGuid().ToString("N") + Path.GetExtension(file.FileName);
var path = Path.Combine(Server.MapPath(Url.Content("~/Temp/")), nameFile);
file.SaveAs(path);
}
result = true;
}
catch (Exception exception)
{
result = false;
}
context.Response.Write(result);
}
public bool IsReusable
{
get
{
return false;
}
}
}
script :
$scope.$watch('file', function (file) {
if (file&&!file.$error) {
$scope.upload($scope.file);
}
});
$scope.upload = function (file) {
Upload.upload({
url: getBaseUrl() + 'Home/ProcessRequest',
file: file
}).progress(function(evt) {
$scope.progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
console.log('progress: ' + $scope.progressPercentage + '% ' + evt.config.file.name);
}).success(function (data, status, headers, config) {
console.log('file ' + config.file.name + 'uploaded. Response: ' + data);
}).error(function (data, status, headers, config) {
console.log('error status: ' + status);
});
};
error :
POST http://localhost:1726/Home/ProcessRequest 500 (Internal Server Error)
No parameterless constructor defined for this object.
edit :
I'm using this code :
public class HomeController : Controller
{
[HttpPost]
[AllowUploadSpecialFilesOnly(".pdf,.doc,.docx,ppt,pptx,.mp3")]
public JsonResult Resume(HttpPostedFileBase file)
{
bool result;
try
{
if (file != null && file.ContentLength > 0 && file.FileName != null)
{
string nameFile = Guid.NewGuid().ToString("N") + Path.GetExtension(file.FileName);
var path = Path.Combine(Server.MapPath(Url.Content("~/Temp/")), nameFile);
file.SaveAs(path);
}
result = true;
}
catch (Exception exception)
{
result = false;
}
return Json(new
{
Result = result
}, JsonRequestBehavior.AllowGet);
}
}
html :
<form class="form-horizontal text-center" role="form" name="upload_form" >
<div class="form-group">
<div class="btn btn-primary" ngf-pattern="'.pdf,.doc,.docx,ppt,pptx,.mp3,.apk'" ngf-select ng-model="file">Send</div>
</div>
<span class="progress" ng-show="file.progress >= 0">
<div class="ng-binding" style="width:{{file.progress}}%" ng-bind="file.progress + '%'"></div>
</span>
</form>
scropt :
$scope.upload = function (file) {
Upload.upload({
url: getBaseUrl() + 'Home/Resume',
file: file
}).progress(function(evt) {
$scope.progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
console.log('progress: ' + $scope.progressPercentage + '% ' + evt.config.file.name);
}).success(function (data, status, headers, config) {
console.log('file ' + config.file.name + 'uploaded. Response: ' + data);
}).error(function (data, status, headers, config) {
console.log('error status: ' + status);
});
};
this is fine. But progressPercentage is always 100% but the file is being uploaded
here master https://github.com/danialfarid/ng-file-upload
and see tutorial http://jsfiddle.net/danialfarid/0mz6ff9o/135/
STEP 0 follow the tutorial step above
STEP 1
modif url parameter in index.cshtml
url: '#Url.Action("UploadDocument")',
file.upload = Upload.upload({
url: '#Url.Action("UploadDocument")',
data: {
File: file,
Description:'test'
}
});
STEP 2
in c# Controller create UploadDocument(UploadRq data)
public JsonResult UploadDocument(UploadRq data)
{
//your code
//string filename = Path.GetFileName(data.File.FileName);
//data.File.SaveAs(Server.MapPath("~/DocumentUploaded/") + filename);
return Json("Saved", JsonRequestBehavior.AllowGet);
}
STEP 3
create class UploadRq.cs
public class UploadRq
{
public HttpPostedFileBase File { get; set; }
public string Description { get; set; }
}

Image displaying error from database

After the recent changes in my application still i get this issue while displaying the image using the relative path in the database. Error: 404 NOT FOUND http://localhost:1256/Empdet/%22/Photos/jobs.jpg%22
Controller.js:
$scope.UploadFile = function () {
console.log('UploadFile');
console.log($scope.Empdet.PhotoFile);
var file = $scope.Empdet.PhotoFile;
console.log('file is ' + JSON.stringify(file));
var uploadUrl = "../Photos";
console.log('before file upload');
EmployeeFactory.UploadFile(file, uploadUrl).success(function (response) {
$scope.Empdet.PhotoText = response;
console.log('$scope.Empdet.PhotoText');
console.log(response);
}).error(function () {
console.log('error');
});
console.log('after file upload');
};
service.js:
service.UploadFile = function (file, uploadUrl) {
var fd = new FormData();
fd.append('file', file);
return $http.post('/Empdet/UploadFile', fd, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
});
}
EmpdetController.cs:
[HttpPost]
public ActionResult UploadFile()
{
var file = Request.Files[0];
var path = Path.Combine(Server.MapPath("~/Photos/"), file.FileName);
file.SaveAs(path);
// prepare a relative path to be stored in the database and used to display later on.
var filename = Url.Content("~/Photos/" + file.FileName);
// save to db
return Json(filename.ToString(), JsonRequestBehavior.AllowGet);
}
Remove the .toString() from your function, the FileName property already returns a string.
[HttpPost]
public ActionResult UploadFile()
{
var file = Request.Files[0];
var path = Path.Combine(Server.MapPath("~/Photos/") + file.FileName);
file.SaveAs(path);
// prepare a relative path to be stored in the database and used to display later on.
string filename = Url.Content("~/Photos/" + file.FileName);
// save to db
return Json(filename, JsonRequestBehavior.AllowGet);
}
Parse the return in your controller. This should get rid of the extra quotes(") in your URL.
controller.js:
$scope.UploadFile = function () {
console.log('UploadFile');
console.log($scope.Empdet.PhotoFile);
var file = $scope.Empdet.PhotoFile;
console.log('file is ' + JSON.stringify(file));
var uploadUrl = '/Empdet/UploadFile';
console.log('before file upload');
EmployeeFactory.UploadFile(file, uploadUrl).success(function (response) {
console.log(JSON.parse(response));
console.log('$scope.Empdet.PhotoText');
$scope.Empdet.PhotoText = JSON.parse(response);
}).error(function () {
console.log('error');
});
console.log('after file upload');
};
EmpdetController.cs:
[HttpPost]
public ActionResult UploadFile()
{
var file = Request.Files[0];
var path = Path.Combine(Server.MapPath("~/Photos/") + file.FileName);
file.SaveAs(path);
// prepare a relative path to be stored in the database and used to display later on.
string filename = Url.Content("~/Photos/" + file.FileName);
// save to db
return Json(filename, JsonRequestBehavior.AllowGet);
}

Downloading File in ASP mvc .net

I Put The Download Link in jqgrid, my Files are Stored on server not in database, files are of different types(extension)
i want user should download file when he clicks on download link
Code For Loading jqgrid is as Follws
public object GetJSONFormatProjectDetails(List<ProjectMasterDTO> listProjectDTO, int SkipCount)
{
var data = (listProjectDTO.Select(c => new
{
id = c.ProjectID,
cell = new[]
{
c.ProjectName,
c.OfficeName,
c.ProjectType,
c.ProjectNature,
c.EntrepreneurName,
c.Year + " Years " +c.Month + " Months " + c.Day + " Days" ,
c.ConcessionWEFdate,
c.ProjectStartDate,
c.ProjectEndDate,
c.isRoadApplicable,
(c.FilePath != "NA" ) ? "<a href='#' style='color:green' onclick='DownLoadFile(\""+URLEncrypt.EncryptParameters(new string[]{ "filepath =" +c.FilePath.Replace("/","$").Replace(" ","#").Trim()})+"\");return false;'>"+(c.FilePath != "NA" ? "DownLoad":"Not Available") + " </a>" : "<span style='color:Red' >Not Available</span>"
}
})).ToArray().Skip(SkipCount);
return data;
}
JS File Code is As Follows
function DownLoadFile(param) {
$.ajax({
url: "/Home/GetFile?parameter=" + param,
cache: false,
type: "POST",
async: false
});
}
Code in Controller as follows
public ActionResult GetFile(string parameter)
{
string queryStringParameters = Request.QueryString["parameter"];
if (queryStringParameters == null)
{
throw new Exception("Url is tampered");
}
string[] parameterArray = queryStringParameters.Split('/');
string param = null;
string hash = null;
string key = null;
if (parameterArray.Length == 3)
{
param = parameterArray[0];
hash = parameterArray[1];
key = parameterArray[2];
}
if (!(string.IsNullOrEmpty(parameter)))
{
Dictionary<string, string> parameters = URLEncrypt.DecryptParameters(new string[] { param, hash, key });
string FilePath =string.Empty ;
parameters.TryGetValue("filepath", out FilePath);
FilePath = FilePath.Replace('$','\\');
// DownloadFile(FilePath);
string name = Path.GetFileName(FilePath);
string ext = Path.GetExtension(FilePath);
string type = "";
// set known types based on file extension
if (ext != null)
{
switch (ext.ToLower())
{
case ".pdf":
type = "Application/pdf";
break;
case ".doc":
case ".docx":
type = "Application/msword";
break;
case ".jpg":
case ".bmp":
case ".tiff":
case ".png":
case ".gif":
case ".jpeg":
type = "Application/Image";
break;
default:
type = "Application";
break;
}
}
Response.AppendHeader("content-disposition", "attachment; filename=" + name);
if (type != "")
{
Response.ContentType = type;
}
String FullFilePath = #"F:\MHTOLL\ContractUploadDetails\" + name;
//return File(new FileStream(path + fileName, FileMode.Open), "text/plain", fileName);
// return File(new FileStream(FullFilePath, FileMode.Open), type, name);
return File(FullFilePath, type,name);
}
return null;
}
Dont mind now about return null and exception handling
also suggest for displaying .gif animation for downloading file.
I don't think you can use an AJAX call to download a file.
I think this answer will get you what you want. Be sure to read the comments about the download prompt and MIME types. Download File Using Javascript/jQuery
I recently encountered the same issue and realized that AJAX will not work to download a file. Try an ActionLink instead:
#Html.ActionLink("ButtonName", "controllerFunctionName", "controllerName", new { functionParamName = paramValue })
And you would include your function in the controller:
public ActionResult controllerFunctionName(type functionParamName){
// do your download here
}

How to improve the solution

This solution works, but I think it can much better be done
JQuery:
$('#addMessage').click(function () {
var textMessage = $('#ticketMessage').val();
var isInternal = $('#isInternal')[0].checked;
var ticketID = $('#TicketID').val();
$.ajax({
url: '/Ticket/AddMessage',
type: 'POST',
data: { textMessage: textMessage, isInternal: isInternal, ticketID: ticketID },
success: function (data) {
var tbody = $('#allMessages').children()[0];
tbody.innerHTML = tbody.innerHTML + data;
$('#ticketMessage').val("");
$('#isInternal')[0].checked = false;
}
});
});
controller
public string AddMessage(string textMessage, bool isInternal, int ticketID)
{
Message message = new Message();
message.IsInternal = isInternal;
message.TicketMessage = textMessage;
message.TicketID = ticketID;
DateTime created=DateTime.Now;
message.CreatedDateTime = created;
message.PersonID = AppSecurity.Security.GetPersonID(Session);
var personRepository = new PersonRepository(_context);
MessageRepository messageRepository = new MessageRepository(_context);
messageRepository.Add(message);
_context.SaveChanges();
string relSrc = (personRepository.GetById((int)message.PersonID) as Employee).Image;
string source = "";
string isInternalStr = "";
if (message.IsInternal)
isInternalStr = "Internal";
if (message.Person is Employee) { source = relSrc != null ? "../../Images/TicketFiles" + relSrc.Replace('\\', '/') : "../../Images/TicketFiles/Employees/no-profile.png"; }
String response = "<tr><td style=\"width: 25%\" valign=\"top\"><table><tr>"
+ "<td><img src=\""+source+"\" alt=\"\" style=\"height: 60px\"/></td>"
+ "</tr><tr><td>"
+ AppSecurity.Security.GetUserFullName(Session)
+ "</td></tr><tr><td>"
+ created.ToString("dd.MM.yyyy") + " - " + created.ToString("HH:mm:ss")
+ "</td></tr></table></td><td style=\"width: 75%; padding:0px;\" valign=\"top\"><table style=\"width: 100%; height: 130px\" cellspacing=\"0\" cellpadding=\"0\">"
+ "<tr><td style=\"height: 20px; padding: 0px\">" + isInternalStr + "</td></tr><tr><td valign=\"top\">" + message.TicketMessage + "</td><tr></table></td></tr>";
return response;
}
Instead of generating the markup in the controller why not do it client side in the JavaScript? Your controller should not be concerned with markup
It seems to me you can benefit a lot by using jquery templates
Your controller should be of type ActionResult and as mr.nicksta said, should be made in a view.
public ActionResult AddMessage(string textMessage, bool isInternal, int ticketID)
{
...
return View(message);
}
and then create a view with the same as the controller, strongly-typed with Message.
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Message>" %>
Where you create the display. You could even do this as a partial view to it can be included in other pages more easily.

Resources