MVC post with file not working - asp.net-mvc-3

I have a program that is developed in MVC 3 Razor Syntax but whenever I am posting to the controller with a file it doesn't work but if I just post to the controller without a file it works. What could be the problem ? Here's my Code:
#using (Html.BeginForm("UpdateFile", "AdministerFiles", FormMethod.Post,
new {enctype = "multipart/form-data"}))
{
string title = null;
string description = null;
string filename = null;
int dataid = 0;
int filesize = 0;
string filepath = null;
foreach (var fileDetails in ((RefDataLinks_mst[])#Model[1]))
{
title = fileDetails.DataTitle;
description = fileDetails.Description;
filename = fileDetails.DataFileName;
dataid = fileDetails.DataID;
filesize = fileDetails.FileSize;
filepath = fileDetails.DataFilePath;
}
<div id="updateLeftTopPart">
<label class="addFileLabel"for="title">Title : </label><textarea rows="3" cols="50" name="title" required>#title</textarea> <br /> <br />
</div>
<div id="updateRightTopPart">
<label for="description">Description : </label><textarea rows="2" cols="50" name="description" required>#description</textarea>
</div>
<div id="updateLeftPart">
<label>Existing File : </label><label>#filename</label>
</div>
<div id="updateUploadFile">
<label for="file">Upload New File Here :</label><input type="file" name="file" id="file"/>
</div>
<input type="hidden" value="#catid" name="catid"/>
<input type="hidden" value="#filename" name="existingFile"/>
<input type="hidden" value="#dataid" name="dataid"/>
<input type="hidden" value="#filesize" name="filesize"/>
<div id="updateActions">
<input type="submit" value="Update File" />
<input type="reset" value="Reset" />
</div>
}
These are the parameters of my Controller:
public ActionResult UpdateFile(HttpPostedFileBase file, int catid, int dataid, string title, string existingFile, string description, int filesize)
Whenever I post, The browser is saying that The connection to the server was reset while the page was loading. What could be the problem ?

Whenever I post, The browser is saying that The connection to the
server was reset while the page was loading. What could be the problem ?
The default 4MB limit that you could increase in your web.config using the <httpRuntime> element.
<!-- Allow files up to 100MB to be uploaded -->
<!-- Also increase the execution timeout as uploading
100 MB files could take some time and ASP.NET won't wait that long -->
<httpRuntime maxRequestLength="102400" executionTimeout="3600" />
By the way if you host your application in IIS 7+ you also need to adjust the requestLimits to the same value (in bytes this time):
<system.webServer>
<security>
<requestFiltering>
<!-- Limit file uploads to 100MB -->
<requestLimits maxAllowedContentLength="104857600" />
</requestFiltering>
</security>
</system.webServer>

Related

CKEditor text value is lost on post in BLAZOR

I have a Textarea control in a Blazor applicaiton that is a CKEditor 5 WYSIWYG editor.
<div class="form-group">
<label for="image">Content</label>
<textarea id="editor" class="form-control" #bind="#PostObject.Content" />
<ValidationMessage For="#(() => PostObject.Content)" />
</div>
When the form gets submitted the value of PostObject.Content is always null. If I remove the CKEditor element the posted value is correct.
The CKEditor is initialised by calling a Javascript function called RTF on a button click (launches the form in a modal popup) -
await jsRuntime.InvokeAsync<string>("RTF", "editor");
The function is located in index.html
function RTF(editorId) {
ClassicEditor.create(document.querySelector('#' + editorId));
}
For me works with the function CKEDITOR.editor.getData.
https://ckeditor.com/docs/ckeditor4/latest/guide/dev_savedata.html
Your code can be changed to below
<EditForm Model="#postObject" OnValidSubmit="SaveObject">
<div class="form-group">
<DataAnnotationsValidator />
<ValidationSummary />
<InputTextArea id="editor" #bind-Value="#PostObject.Content" Class="form-control" />
</div>
<button type="submit" class="btn btn-primary">Save</button>
</EditForm>
#code {
PostObject postObject= new PostObject();
string contentFromEditor = string.Empty;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
await jsRuntime.InvokeAsync<string>("RTF", "editor");
await base.OnAfterRenderAsync(firstRender);
}
private async Task SaveObject()
{
contentFromEditor = await JSRuntime.InvokeAsync<string>("CKEDITOR.instances.editor.getData");
}
}

Access Get or Post parameters in MVC Web Api Authorization filter

I want to achieve the same as Accessing post or get parameters in custom authorization MVC4 Web Api ,but it only works in the case of a GET request.
So I have written the follwoing action filter for a web api:
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var request = actionContext.Request;
var headers = request.Headers;
HttpContext ctx = default(HttpContext);
ctx = HttpContext.Current;
if (ctx != null)
{
var apiKey = (string)actionContext.ActionArguments["apiKey"];
}
}
The form that posts looks like:
<form name="form1" method="post" enctype="multipart/form-data" action="#localPostUrl">
<fieldset>
<legend>File Upload Example</legend>
<div>
<label for="caption">Image Caption</label>
<input name="caption" type="text" />
</div>
<div>
<label for="image1">Image File</label>
<input name="image1" type="file" />
</div>
<div>
<input type="text" name="apiKey" id="apiKey" value="b2b54e7b-ca0b-4adf-a369-efe839e55120" />
<input type="submit" value="Submit" />
</div>
</fieldset>
So I'm trying to post an image and a string to the Web Api but the actionContext.ActionArguments in the ActionFilter is empty when doing a POST request but is working when doing a GET request.
When compared to the solution provided on top of my question I notice that the action where that posts has an attribute FormUri added to a parameter, but I can't send the ApiKey in the querystring.
Is there a solution to getting the Post paramteres in order to do some form on validation?

GRAILS- Image corrupt or truncated

im getting this error "image corrupt or truncated" on FF console when I try to display an image stored in my database. I´m using Grails and Hibernate.
I just want to display a user´s profile picture in my gsp page.
My domain class User has an attribute photo defined as byte[]
public class User {
private String userId;
private byte[] photo;
.
.
.
The user.hbm.xml mapping is :
< property name="photo" type="binary" column="PHOTO" not-null="false" />
This collumn is a BLOB on DB.
My gsp:
< div id="user-view-thumbnail-container">
<fieldset>
<legend>Photo Upload</legend>
<g:form action="uploadPhoto" method="post" enctype="multipart/form-data">
<label for="photo">Photo</label>
<input type="file" name="photo" id="photo" />
<input type="submit" class="buttons" value="Upload" />
</g:form>
</fieldset>
<g:if test="${user.photo}">
<img alt="User Photo" src="${createLink(controller:'profile', action:'profile_image', id:user.userId)}" />
</g:if>
</div>
ProfileController:
def uploadPhoto = {
def user = userService.getUser(authenticateService.principal())
def f = request.getFile('photo')
user.setPhoto(f.getBytes())
if (!user.save()) {
//doesn´t matter now
return;
}
redirect(action: 'index', model:[user: user])
}
def profile_image = {
def user = userService.getUser(params.id)
if (!user) {
response.sendError(404)
return;
}
response.setContentType(user.photo.contentType())//'image/png', 'image/jpeg', 'image/gif'
response.setContentLength(user.photo.size())
OutputStream out = response.getOutputStream();
out.write(user.photo);
out.close();
}
FYI: The picture is saved on DB correctly, I can see it, but I can´t show it on my gsp.
Any idea?
Thanks a lot guys,
Use blob type in the mapping :).

mvc3 file upload using ajax form - Request.Files empty

Im using mvc3, and am trying to create a series of ajax forms that each upload a file, within a single page. Here's the view for the page:
#{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
#Html.Partial("_UploadItem")
#Html.Partial("_UploadItem")
#Html.Partial("_UploadItem")
<script type="text/javascript">
function Go() {
// loop through form tags
for (var n = 0; n < document.forms.length; n++) {
var f = document.forms[n];
// if a dress is chosen, a caption is chosen
// and a file is chosen, then submit the ajax form
if (f.dressid.value != '' &&
f.dresscaption.value != '' &&
f.fileitem.value != '')
f.submit();
}
}
</script>
<input type="button" onclick="Go();"/>
Then the Go() function loops through the ajax forms, checking to see whether all 3 pieces (dressid, dresscaption, and fileitem) on each form are non-empty, and calls submits the forms that do, kicking off an async upload.
Here's the partial view:
#using SoRefeising.Models
#using (Ajax.BeginForm("UploadFile", new { }, new AjaxOptions { HttpMethod = "POST" }, new { enctype="multipart/form-data"}))
{
List<SelectListItem> items = (List<SelectListItem>)ViewBag.Dresses;
<span>Dress</span>
#Html.DropDownList("dressid", items, "Choose Dress");
<span>Caption</span>
#Html.TextBox("dresscaption")
<input type="file" id="fileitem" />
}
I have marked each form with the multipart attribute. When the page is generated, I get the following:
<form action="/upload/UploadFile" data-ajax="true" data-ajax-method="POST" enctype="multipart/form-data" id="form0" method="post"> <span>Dress</span>
<select id="dressid" name="dressid"><option value="">Choose Dress</option>
<option value="1">Simpson01</option>
<option value="2">Simpson02</option>
</select> <span>Caption</span>
<input id="dresscaption" name="dresscaption" type="text" value="" /> <input type="file" id="fileitem" />
</form>
<form action="/upload/UploadFile" data-ajax="true" data-ajax-method="POST" enctype="multipart/form-data" id="form1" method="post"> <span>Dress</span>
<select id="dressid" name="dressid"><option value="">Choose Dress</option>
<option value="1">Simpson01</option>
<option value="2">Simpson02</option>
</select> <span>Caption</span>
<input id="dresscaption" name="dresscaption" type="text" value="" /> <input type="file" id="fileitem" />
</form>
<form action="/upload/UploadFile" data-ajax="true" data-ajax-method="POST" enctype="multipart/form-data" id="form2" method="post"> <span>Dress</span>
<select id="dressid" name="dressid"><option value="">Choose Dress</option>
<option value="1">Simpson01</option>
<option value="2">Simpson02</option>
</select> <span>Caption</span>
<input id="dresscaption" name="dresscaption" type="text" value="" /> <input type="file" id="fileitem" />
</form>
Everything looks ok...
Here's the controller action that is called
[HttpPost]
public ActionResult UploadFile(string dressid, string dresscaption)
{
HttpPostedFileBase hpf = Request.Files[0] as HttpPostedFileBase;
...
When the action is called, the Request.Files collection has 0 items, rather than the selected file. I have enabled unobtrusive javascript, the unobtrusive file is loaded in the master page, and works on other pages.
Ive seen some messages on the forum about being careful with file sizes. The file I am testing with is < 2k
Any ideas why there are no items in Request.Files?
Thanks
You cannot upload files using AJAX. So replace the Ajax.BeginForm with a normal Html.BeginForm. You may checkout the following blog post as well.
If you want to use asynchronous uploads you may try some of the available upload components such as Ajax Upload and Uploadify.
First of all, I am not sure why you have this three times.
#Html.Partial("_UploadItem")
#Html.Partial("_UploadItem")
#Html.Partial("_UploadItem")
Are you trying to upload multiple files? There are quite a few scripts that allow you to do this quite efficiently. You are also generating multiple forms with fields that contain the same id. This wont effect the upload process, but is bad practice. I do think you need to refactor the above. Anyway change the field in your partial view to
<input type="file" name="file" />
I think the problem may be with your actual action and how you are trying to retrieve the file. Try this
HttpPostedFileBase postedFile = Request.Files["file"];
Let me know if that works.

How do I unhide a CFDIV that has dynamic content with AJAX binding itself?

I have the following CFSELECT tags that are used to populate a text input:
<cfselect id="this" name="this" bind="cfc:Data.getThis()" bindonload="true" />
<cfselect id="that" name="that" bind="cfc:Data.getThat({p1})" />
<cfselect id="theOther" name="theOther" bind="cfc:Data.getTheOther({p1}, {p2})" />
The text input is the only value that needs to be submitted in a form:
<cfform name="addItem" method="post" action="somepage.cfm">
<cfinput
type="text"
id="item"
name="item"
bind="cfc:Data.getResult({this}, {that}, {theOther})" /><br />
<cfinput
type="submit"
name="addButton"
value="Add Item" />
</cfform>
I want the form and it's contents to be visible only when all three selections have been made, and there is a value for the text input. What is the best way to do this? I'm assuming some use of CFDIV is the best way, but I'm not sure how to load the dynamic content (the CFINPUTs) this way.
<cfselect id="this" name="this" bind="cfc:Data.getThis()" bindonload="true" onChange="toggleForm();" />
<cfselect id="that" name="that" bind="cfc:Data.getThat({p1})" onChange="toggleForm();" />
<cfselect id="theOther" name="theOther" bind="cfc:Data.getTheOther({p1}, {p2})" onChange="toggleForm();" />
<div id="theForm" style="display:none">
<cfform name="addItem" method="post" action="somepage.cfm">
<cfinput
type="text"
id="item"
name="item"
bind="cfc:Data.getResult({this}, {that}, {theOther})" /><br />
<cfinput
type="submit"
name="addButton"
value="Add Item" />
</cfform>
</div>
<script type="text/javascript">
function toggleForm(){
var a = document.getElementById("this").selectedIndex;
var b = document.getElementById("that").selectedIndex;
var c = document.getElementById("theOther").selectedIndex;
if (a > -1 && b > -1 && c > -1){
document.getElementById("theForm").style.display = "";
}
}
</script>
Personally I would simplify that JS a bit by using jQuery, but I don't know if you're already using jQuery on your site, and I don't want to be another "use jquery" empty answer; so this should work without jQuery, should you want/need to go without it. (But jQuery is awesome!)

Resources