ViewBag content not shown when page reload - html

I am doing my project in mvc
i have controller to upload file in to a folder
public ActionResult UploadFile(HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
if (file == null) { ModelState.AddModelError("File", "Please Upload Your file"); }
else if (file.ContentLength > 0)
{
.................
else
{ //Excel file copied temporarily to temp folder
var filename = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/Uploads/"), filename);
file.SaveAs(path);
ModelState.Clear();
ViewBag.Message = "File uploaded successfully";
}
}
}
return RedirectToAction("UploadSTR", "Upload");
}
and my view is
#using (Html.BeginForm("UploadFile", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
File Path put type="file" name="file" id="file" />
<input type="submit" name="submit" value="Upload" id="btn" />
}
<p> Message:#ViewBag.Message</p>
my problem is that after submit, file is uploaded and the return to the same page .But ViewBag.Message = "File uploaded successfully" is no shown in my view

If you use a view model, you can add the message as a hidden form value using the Html.HiddenFor() helper in your view. This way the value would get posted back into the model on form submission. You're probably not going to get the functionality you need using the ViewBag.
The ViewBag has certain uses where it is advantageous to use it, like for setting the page title in a layout. But in general the ViewBag is a beginner level item that you should probably look towards abandoning in favour of view models, to make use of MVC's powerful automatic view model binding features.
Maybe have a run through the MVC Music Store example or Google for other examples of using view models in ASP.NET MVC.

You can not pass data via ViewBag (and ViewData) during redirection, you need to avoid redirection or to use TempData. About TempData you can read here ViewBag, ViewData and TempData .

ViewBag will not survive redirect. Use TempData instead.

Related

Unable to upload and retreive file from the database

I am trying to upload files for each course published by the Server section of the sofware Application and Firebase been used as database for this application.
After choosing files from the device Storage and giving relevant deails to the text field and clicking on publish button, course gets published and chosen file converted into link and stored in database
when trying to retrieve uploaded file from the training section for the intended course, it shows as sanitizing unsafe URL link and unable to see the file
I have attached code for the above implementation, Kindly provide your suggestion to proceed further for the same
Server.component.html
<label for="user_data">Upload file</label>
<input type="file" multiple formControlName="file" class="form-control" id="file" (change)=uploadFile($event) accept=".pdf,.docx" required>
Server.component.ts
uploadFile(event) {
let Sport_files = event.target.files;
if (Sport_files > 0) {
console.log(this.sports_videoForm.value.file); // You will see the file link
this.dataService.uploadFile(this.sports_videoForm.value.file);
}
SportsData.service.ts (Service Component implementation)
uploadFile(file) {
let formData: FormData = new FormData();
formData.append('file', file, file.name);
this.http.post("http://localhost:/4200/", formData)
}
retrieving file in training section for the intended course, sports_training.component.html
uploaded file
You need to make angular trust the url by using bypassSecurityTrustUrl method of DomSanitizer
You can create a common method in a service to be used across whole application as you might require this in multiple components in your application.
common.service.ts :
import { DomSanitizer } from '#angular/platform-browser';
...
constructor(private domSanitizer: DomSanitizer) {}
sanitize(url: string){
return this.sanitizer.bypassSecurityTrustUrl(url);
}
sports_training.component.html:
<a [href]="commonService.sanitize(item.file)" target="_blank" class="col-sm-4" style="padding-bottom: 10px">uploaded file</a>
You can create sanitize method in your sports_training component too but I recommend using a common service

Umbraco 7 route to custom Controller for rest API

i want to map a Route to an ApiController, to post data to it.
I'm not using a Surface contoller, since i want a clean url like /api/test/{action}, without the umbraco/surface part in url.
I'm trying to use
RouteTable.Routes.MapHttpRoute(
"ApiTest",
"Api/Test/{action}",
new
{
controller = "Api_Test",
action = "Search"
});
But i'm getting an error since MapHttpRoute need a 4th string[] parameter.
How can i Map that route?
Then i will post a json or xml and return the response (json or xml).
Use RouteTable.Routes.MapRoute instead. I've used that previously in Umbraco sites and it works fine, e.g.
RouteTable.Routes.MapRoute(
name: "cookie-api-location",
url: "cookie-api/setregioncheckcookie/",
defaults: new
{
controller = "Cookie",
action = "SetRegionCheckCookie"
}
);

Having trouble returning a file from the server

I am trying to create a link so that users can download a file that is already on the server.
In my controller I have:
public ActionResult downloadFile(int id)
{
DataAccess da = new DataAccess();
PersonFile displayFile = new PersonFile();
displayFile = da.getPersonFileByID(id);
string mimeType = "application/pdf";
return File(displayFile.FileData, mimeType, displayFile.FileName);
}
Then in my view I have:
<th class="editAddLabel">
#Html.LabelFor(model => Model.PersonFile.FileName, "FileName")
*#Html.ActionLink("Download file", "downloadFile", "PersonController", Model.id, null )*
</th>
It's my first time doing something like this, but I feel like when the person clicks on the link, it should send the id of the model into the downloadFile method and then return the contents of the file. But when I click on the link, I get nothing. And when I set breakpoints on the downloadFile method, nothing happens either leading me to believe that the method is not even called. What could I be doing wrong?
Edit: I've also tried the following:
<input type="button" title="File" value="File" onclick="location.href='#Url.Action("downloadFile", "PersonController", new { id = Model.id })'; }" />
</th>
My error:
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /PersonController/downloadFile
Your ActionLink is malformed and not sending the ID with the request. Try this instead:
#Html.ActionLink("Download file", "downloadFile", "PersonController", new { id = Model.id }, null )
Looking at your error, it seems the URL you are requesting is /PersonController/downloadFile. This to me seems wrong, you're not passing an ID that relates to a person, and also that MVC routing should be /person/downloadfile not personcontroller.
Try Url.Action("downloadFile", "Person", new { #id = Model.Id }
Just a guess, but you could set the return type to "FileResult" like:
public FileResult downloadFile(int id)
{
DataAccess da = new DataAccess();
PersonFile displayFile = new PersonFile();
displayFile = da.getPersonFileByID(id);
string mimeType = "application/pdf";
return File(displayFile.FileData, mimeType, displayFile.FileName);
}
Further details:
Download file of any type in Asp.Net MVC using FileResult?

Grails render template or JSON?

I have a controller that uploads and processes a file. Afterwards, I wish to render the processing result in a modal div. I wanted to know what the best way is to get the results from the controller to the modal div on the gsp. I thought about a template but I didn't know how to specify what the target div for the template should be because this template wouldn't be rendered by a button click where a target for template render is set as an attribute, it would be done on a timed basis (i.e. when the file is done uploading). The other way is to send JSON back from the controller but I don't know how to intercept this JSON at the right time because I still don't quite understand the timings of the information flow between the GSP and the Controller. I know how to send the JSON but how to alert the GSP that "hey, some JSON is now ready for your modal that's about to go up." Here is some pseoducode of basically what I am trying to get done.
Controller:
upload() {
// process file and store results in three integers
// int1 = result1
// int2 = result2
// int3 = result3
// send the three numbers to the gsp
}
Now what is the best way to get these three numbers to the GSP so that they are displayed on a modal dialog which is about to go up like this:
<div id="fileUploadResultsModal">
Results:
${int1}, ${int2}, ${int3}
</div>
Here is the JS associated with my ajax upload function:
$("#chseFile").upload("${createLink(controller: 'customer', action: 'upload',)}",
{dataTypegrp: parseInt(getCheckedValue(document.getElementsByName('dataTypegrp'))),
fileTypegrp: parseInt(getCheckedValue(document.getElementsByName('fileTypegrp')))},
function(success) {
$("#cancel1").trigger("click");
setTimeout(function(){
$("#summary").trigger("click");
}, 250);
displaySuccess(data);
},
function(prog, value) {
console.log(value);
$("#prog").val(value);
if (value == 100) {
$("#prog").hide();
$("#progressbar").html("Uploading and processing. Please wait...");
}
});
but right now JS complains that 'data' is not defined. 'data' is meant to be the JSON coming back from the controller.
Thanks
you can render them as JSON:
render( [ int1:111, int2:222, int3:333 ] as JSON )
or as a HTML-string
render "<div id=\"fileUploadResultsModal\">Results:${int1}, ${int2}, ${int3}</div>"
or use a template
render template:'/yourController/templateName', model:[ int1:111, int2:222, int3:333 ]
or a TagLib
render g.yourResultTag( int1:111, int2:222, int3:333 )
For this tiny bit of information, the performance is not of concern. It's rather a matter of taste, or what is more appropriate for your client.
If the later is JSON-biased, use JSON-rendering. If it has a mix of JSON and HTML, use others.
inside controller at the enf of controller action you can use
render [data:['name':'firstname','surname':'secondName'] as JSON]
this will render the data to GSP

Browser wants to download Json as a file when returning Json from the controller

$("#frmCompose").submit(function () {
$(this).ajaxSubmit({
success: function (response) {
alert('success');
}
});
});
Controller code:
[HttpPost]
public ActionResult SendEmail(EmailMessageModel emailMessage)
{
try
{
// do something with the data
return Json(new StatusModel { error = false });
}
catch (Exception)
{
return Json(new StatusModel { error = true, message = "Could not send email" });
}
}
View Code:
<form id="frmCompose" method="post" action="SendEmail">
<button id="compose" class="btn-pencil">
Send</button>
<div class="fields-inline">
<div class="editor-label">
#Html.Label("To:")
</div>
#Html.TextBox("txtTo")
</div>
<div class="fields-inline">
<div class="editor-label">
#Html.Label("Subject:")
</div>
#Html.TextBox("txtSubject")
</div>
<div class="fields-inline">
<div class="editor-label">
#Html.Label("Body:")
</div>
#Html.TextArea("txtBody")
</div>
</form>
In my controller I return a JSon result with a text message.
Why does the view in FireFox want to download the json as a file download?
All I want to do is ensure I get a response within the success callback
Solution is to return false within the submit() call function for the form.
That way, the json result is consumed within the submit function and not passed to the browser for handling.
$("#frmCompose").submit(function () {
// submit data to server here....
return false;
});
According to the documentation:
Since it is not possible to upload
files using the browser's
XMLHttpRequest object, the Form Plugin
uses a hidden iframe element to help
with the task. This is a common
technique, but it has inherent
limitations. The iframe element is
used as the target of the form's
submit operation which means that the
server response is written to the
iframe. This is fine if the response
type is HTML or XML, but doesn't work
as well if the response type is script
or JSON, both of which often contain
characters that need to be repesented
using entity references when found in
HTML markup.
To account for the challenges of
script and JSON responses, the Form
Plugin allows these responses to be
embedded in a textarea element and it
is recommended that you do so for
these response types when used in
conjuction with file uploads.
This basically means that if you want to upload files using the jquery form plugin and your form contains file input fields the server needs to wrap the returned JSON into <textarea> tags.