Unable to receive file data in FormCollection object inside controller - c#

I have following markup:
<form id="did" enctype="multipart/form-data">
<textarea name="description">Text</textarea>
<input name="files" id="files" type="file" accept="doc,pdf" />
...
</form>
And in controller its like this:
public int Edit_Submit(FormCollection oForm)
{
var attachedFiles = oForm["files"];
var description= oForm["description"];
....
}
I am posting the form through jQuery which look like this:
var formInfo = $("#did").serialize();
$.post('../../data/SubmitEdit', formInfo, function (serverResult) {
...
I am receiving other data fine but always null in attachedFiles.
Is it not possible through this way? What am I doing wrong please help.

I don't think your uploaded file will be in your form collection.
Try something like this maybe:
<form id="did" action="../../data/SubmitEdit" enctype="multipart/form-data">
<textarea name="description">Text</textarea>
<input name="files" id="files" type="file" accept="doc,pdf" />
...
</form>
[HttpPost]
public ActionResult SubmitEdit(FormCollection oForm, HttpPostedFileBase files) {
...
Make sure HttpPostedFileBase name is the same as the id of your input[type="file"]

$.post() method is essentially an ajax call, or in more technical terms, use of XMLHttpRequest object.
And by XMLHttpRequest object you can't send file stream back to the server. There are some ways to imitate that though.
Also, at server-side, you should use HttpPostedFileBase class, to get the file stream back to the server.

Related

How do i send data to asp.net controller so that it can return a view?

What I want to do is so simple, I'm still trying to learn ASP.NET with c# and MVC application but I'm just having a lot of difficulty getting a simple example to go through, then I can grow from it, here's how it goes: I have a simple html5 form that's method is GET, the type is text and I basically want to submit a text into my mvc controller, once my controller get's it, I want it to output that string 'worked' through HTML5, how do I do this?
summary: string 'worked' --> html form --> c# controller --> html (view?)
here's what I got for my 'view' (Search.cshtml)
<form action="Home/Search" method="get">
<input type="text" name="q" />
<input type="submit" value="Search" />
ok, so far so good, if I input 'worked' nothing is going to happen unless I add more code, here's c# (HomeController.cs):
public ActionResult Search(string q)
{
return this.View(q?); // so what exactly is View(q)? what is view returning? }
okay so this is where I am confused, does my string go through and become stored in 'q'? and if so, how do I get this thing to use HTML5 to output something like
<p> q </p> <!-- q = 'worked' -->
In your controller, you are calling the View(...) method incorrectly. The View(...) method expects the string parameter you're passing to be the path to the razor view you're trying to render.
A quick and simple way to pass the q variable from your controller to a view to be rendered is using ViewBag.
If you have a razor view named /Views/Search.cshtml you would do:
public class MyController : Controller
{
public ActionResult Search(string q)
{
ViewBag.Query = q;
return View("~/Views/Search.cshtml");
}
}
Then in /Views/Search.cshtml use it like this:
<p>#ViewBag.Query</p>
If you are using asp.net mvc, then please follow mvc pattern like this ..
View
#using (#Html.BeginForm("Search","Home",FormMethod.Post))
{
<b>Name : </b>
#Html.TextBox("searchTerm", null, new { #id = "txtSearch" })
<input type="submit" value="Search" />
}
Controller
[HttpPost]
public ActionResult Search(string searchTerm)
{
return View(searchTerm);
}
}
Search.cshtml
<form action="/Home/Search" method="get">
<input type="text" name="q" />
<input type="submit" value="Search" />
</form>
<p class='current-query'>#Model</p>
HomeController.cs
public ActionResult Search(string q)
{
return View((object)q); // return the model to the view (a string)
}

How to keep my model data when do GET>POST>REDIRECT to upload a file?

I want to create a register form using MVC which include a profile photo. I don't want to add record for people before completing the form (including profile photo upload). Also I want my UploadImage view and controller to be re-usable for many forms (not just this form). I pass three variables to my upload form through ActionLink: RedirectAction (RA), RedirectController (RC), and dataname and the procedure goes like this:
I store RA, RC, dataname in ViewBag, then put them in hidden <input> tags to be submitted when POSTing the file
// GET: UploadImage/Upload
public ActionResult Upload(string RA, string RC, string dataname)
{
ViewBag.RedirectAction = RA;
ViewBag.RedirectController = RC;
ViewBag.DataName = dataname;
return View();
}
Put these lines in my Upload.cshtml (View):
#using (Html.BeginForm("Upload", "UploadImage", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="hidden" name="RA" value="#ViewBag.RedirectAction" />
<input type="hidden" name="RC" value="#ViewBag.RedirectController" />
<input type="hidden" name="dataname" value="#ViewBag.DataName" />
<input type="submit" name="Submit" id="Submit" value="Upload" />
}
Store the filename in TempData with dataname as the Key and redirect to /RC/RA:
// POST: UploadImage/Upload/
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file, string RA , string RC , string dataname)
{
var filepath = "C:/myfilename.jpg";
TempData.Add(dataname, filepath);
return RedirectToAction(RA,RC);
}
And get my filepath by utilizing TempData in my register form:
#if (TempData.Keys.Contains("MyData")) {
<div class="form-group">
<p>#TempData["MyData"].ToString()</p>
</div>}
The code works just fine, but the essential caveat is that I don't want other completed fields to get lost when redirected to the register form. How can I solve this problem ?
One option is to stick the data in the session. Another option would be to use a separate database table to hold in-progress registration data.

Read multipart form data without saving files to disk?

I have a form which looks, simplified, like this:
<form id="image-form" enctype="multipart/form-data">
<input type="text" name="imageEntryName" />
<input type="file" name="imageEntry" />
<input type="text" name="imageEntryAltText" />
<input type="submit" value="SEND INN" class="btn-ok" />
</form>
This is posted to this action:
[HttpPost]
[Route("~/api/Exhibition/SubmitImageEntry")]
public async Task<HttpResponseMessage> SubmitImageEntry()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
var provider = new MultipartFormDataStreamProvider("C:/test");
var data = await Request.Content.ReadAsMultipartAsync(provider);
return new HttpResponseMessage(HttpStatusCode.OK);
}
And this works. I get the posted data. But is this possible without the MultipartFormDataStreamProvider saving files to C:/test? I possible, I can just keep the data in memory until the action is completed.
EDIT: With MultipartFormDataStreamProvider I get the .FormData["key"] option, which is what I want.
Use the MultipartMemoryStreamProvider.

Post from IFRAME and Return to Partial View in Parent

My apologies if this is a dupe, but I haven't been able to find an exact solution to my problem.
Goal:
Upload a file, do work, return results. Easy right?
Problem:
I've been working on this for a few days without any luck. I've tried XmlHttpRequest, but due to the browser limits (can't get away with forcing end-users and clients to use IE10 or higher) that doesn't seem to be an option.
What I've spent most of my time on is uploading via iframe. I've gotten the upload piece working fine. What I need to happen is after doing work with the file, results should be returned back to the parent window and a partial view.
----------------------Index--------------------
Partial View Data Entry----Partial View Results
-----Upload iframe----------Results from file--
Here's what I have for code:
DataEntry.cshtml
<div>
...textboxes, radiobuttons, etc...
<iframe id="uploadFrame" class="seamless" frameborder="0" src='#Url.Action("UploadFile")'></iframe>
</div>
UploadFile.cshtml
<script type="text/javascript">
$(document).ready(function () {
$("#uploadFile").click(function () {
$("#field1").val(window.parent.document.getElementById("field1").value);
$("#field2").val(window.parent.document.getElementById("field2").value);
...other fields...
$("#fileForm").submit();
});
$("#file").change(function () {
if ($("#file").val() != "") {
$("#uploadFile").removeAttr("disabled");
}
else {
$("#uploadFile").attr("disabled", "disabled");
}
});
});
</script>
<form id="fileForm" action='#Url.Action("UploadFile")' method="post" enctype="multipart/form-data">
<div>
Please use this template (link) to upload a list of employees and dependents.
</div>
<div class="center">
<br />
<input type="hidden" id="field1" name="field1" />
<input type="hidden" id="field2" name="field2" />
<input type="file" id="file" name="file" /><br /><br />
<input type="button" disabled="disabled" id="uploadFile" name="uploadFile" value="Upload File" class="greenButton" />
</div>
</form>
HomeController.cs
public ActionResult UploadFile()
{
return View();
}
[HttpPost]
public ActionResult UploadFile(String field1, String field2, HttpPostedFileBase file)
{
...do work...
//return View("UploadFile", object);
//return View("Result", object);
//return ?
}
The return part is where I'm stuck. What can I do to return the object to the partial view, without having the partial view load within the iframe?
Any ideas or at least a point in the right direction would be appreciated. Even a link to a duplicate!
The Partial View would always be refreshed when it is returned. It is how things work. Unless you do the upload differently using AJAX.
Please refer to the link below:
Ajax.BeginForm in MVC to upload files
Alternatively by using the same logic described in your question, you could put some additional logic in your view, like for example using TempData as flag which is set in the action controller, to determine the partial view is for upload or showing result.
Then, in your partial view, using that flag to render the UI accordingly.
Hope it helps.
I ended up finding a solution based on the concepts from these questions:
Get JSON text from HTML iframe
How to display action result of iframe in parent window
Basically, I modified the HomeController > UploadFile action to return JSON text
JsonResult result = new JsonResult();
result.Data = listOfEmployeesWithRates.ToList();
result.ContentType = "text/plain";
return result;
Then in jQuery, I check to see if the iframe contains the JSON when it loads.
//uploadFrame
$("#uploadFrame").load(function(){
if ($("#uploadFrame").contents().find("pre").html() != null) {
//pass json via ajax call to Result partial view
//refresh iframe
$("#uploadFrame").attr('src', $("#uploadFrame").attr('src'));
}
});

MVC: Retrieving form values after submitting

I have a form on a dialog box like so:
<form action="../ControlerFunction">
<input type=text id="id1"/>
<input type=text id="id2"/>
<button type="submit"> OK </button>
<button type="button" class="close"> Cancel </button>
</form>
When the form is submitted it hits my controller function, but how can I retrieve the values of the two text boxes?
Also when I change the form action to:
<form action="JavaScriptFunction();">
or:
<form action="JavaScriptFunction();return false;">
and I have my JavaScript on the same page as:
function JavaScriptFunction()
{
alert("Hi!");
}
it does not hit the function. Am I missing something?
In your controller add another action method that accepts an HTTP POST and takes in the form collection.
Like:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ControllerFunction(FormCollection collection)
Kindness,
Dan
Correct html form tag syntax:
<form method="post" action="/controller/method/" onsubmit="yourJSFunction();">
...
This suits ALL server-side languages and technologies.
Try considering this first:
FORM Tag needs method(POST or GET);
Your INPUT tags don't have name
attributes which will be used for
accessing the values.
Additional code:
<form name="form1" method="POST" onSubmit="JavaScriptFunction(); return false;">
<input type=text id="id1" name="id1"/>
<input type=text id="id2" name="id2"/>
<button type="submit"> OK </button>
<button type="button" class="close"> Cancel </button>
</form>
javascript:
function JavaScriptFunction()
{
var id1Text = document.form1.elements["id1"].value; //get the value of id1
var id2Text = document.form1.elements["id2"].value; //get the value of id2
//do whatever you want here.
}
Further to #Daniel.
You can either use MyAction[FormCollection collection] and then pull your values from the collection object.
Or, if you have a model that you passed to the view you can use TryUpdateModel() to propergate your model with the values from the form.
If you need more then post a comment and I'll add code.
Going home now so there will be a delay as I fight the traffic. :)
Oh, and welcome to SO.
I want to answer your first question.
how can i retreive the values of the two text boxes?
One answer is given by Daniel Elliot.
After giving you input tags a name attribute with the same value of the id attribut, you can access the values as parameters to your action method.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ControllerFunction(String id1, String id2)
Your second question about java script is answerd by Sergei
<form name="form1" method="POST" onSubmit="JavaScriptFunction(); return false;">
<input type=text id="id1" name="id1"/>
<input type=text id="id2" name="id2"/>
<button type="submit"> OK </button>
<button type="button" class="close"> Cancel </button>
</form>
javascript:
function JavaScriptFunction()
{
var id1Text = document.form1.elements["id1"].value; //get the value of id1
var id2Text = document.form1.elements["id2"].value; //get the value of id2
//do whatever you want here.
}

Categories

Resources