Fine Uploader in Form Doesn't Submit Model Data into Controller - forms

I have 2 questions:
1.) I have placed the Fine Uploader in a form and now I'm wondering why I don't see the filled content of the entry fields in my controller. How I can solve that?
2.) How can I do field validations before the upload process fires?
I hope someone can help!
Here is my code:
Model:
public class UploadFileModel
{
[StringLength(100)]
[Display(Name = "* Title:")]
public string Title { get; set; }
[StringLength(300)]
[Display(Name = "Description:")]
public string Description { get; set; }
}
View:
#model mowee.Models.UploadFileModel
<link href="~/Scripts/fineuploader/fineuploader-3.5.0.css" rel="stylesheet" />
#using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { id = "uploadForm", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<fieldset>
<legend>Video Upload</legend>
<ol>
<li>
#Html.LabelFor(m => m.Title)
#Html.TextBoxFor(m => m.Title, new { #Class = "action add", title = "Enter your video/movie title here." })
</li>
<li>
#Html.LabelFor(m => m.Description)
#Html.TextAreaFor(m => m.Description, new Dictionary<string, object> { { "rows", "3" } })
</li>
</ol>
<div id="bootstrapped-fine-uploader"></div>
<script src="~/Scripts/fineuploader/fineuploader-3.5.0.js"></script>
<script>
function createUploader() {
var uploader = new qq.FineUploader({
element: document.getElementById('bootstrapped-fine-uploader'),
multiple: false,
validation: {
sizeLimit: 2147483648 //2GB
},
request: {
endpoint: '/Home/UploadFile'
},
text: {
uploadButton: '<div><i class="icon-upload icon-white"></i>* Upload Video</div>'
},
template: '<div class="qq-uploader span12">' +
'<pre class="qq-upload-drop-area span12"><span>{dragZoneText}</span></pre>' +
'<div id="btnUpload" class="qq-upload-button btn btn-success" style="width: 33%;">{uploadButtonText}</div>' +
'<span class="qq-drop-processing"><span>{dropProcessingText}</span><span class="qq-drop-processing-spinner"></span></span>' +
'<ul class="qq-upload-list" style="margin-top: 10px; text-align: center;"></ul>' +
'</div>',
classes: {
success: 'alert alert-success',
fail: 'alert alert-error',
dropActive: "cssClassToAddToDropZoneOnEnter"
}
});
}
window.onload = createUploader;
</script>
</fieldset>
}
Controller:
[HttpPost]
[AllowAnonymous]
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult UploadFile(string qqfile, UploadFileModel myModel)
{
if (ModelState.IsValid)
{
try
{
HttpPostedFileBase uploadFile = null;
uploadFile = Request.Files[0];
if (uploadFile != null && uploadFile.ContentLength > 0)
{
if (myModel.Title != null || myModel.Description != null)
{
**//but UploadFileModel is null. WHY??????? Anyone an idea what i did wrong???
//write data to DB**
}
}
else
{
ModelState.AddModelError("", "Please choose a video/movie.");
return Json(new { success = false, message = "Please choose a video/movie." }, "application/json");
}
}
catch (Exception ex)
{
ModelState.AddModelError("", "An error occured. Try again.");
mailUtils.SendBugMail(ex, this.HttpContext);
return Json(new { success = false, message = "An error occured during upload. Try again." }, "application/json");
}
return Json(new { success = true, VideoLink = #ViewBag.VideoLink, VideoTranscoded = #ViewBag.Transcoded }, "application/json");//"text/html");
}
return Json(new { success = false, message = "An error occured during upload. Try again." }, "application/json");
}

OK. I figured it out. The params can be set on callback 'onSubmit' with setParams like that:
callbacks: {
onSubmit: function (id, fileName, responseJSON) {
uploader.setParams({
idxTitle: $('#titleId').val(),
idxAuthor: $('#authorId').val(),
idxEmail: $('#emailId').val()
});
},
And it works fine!

Addressing your questions:
You should really have a look at the MVC4 example in the Fine Uploader server-side examples repository. Model your server-side code after this example, and you should be fine. I personally am not an MVC4 developer, but I know the example I have linked to works.
You can make use of onValidate and onValidateBatch callbacks to perform your own validation tasks. Please have a look at the callbacks documentation for more info.

Related

Why IdentityRole id gets overriden by old name in View

I'm trying to make an Edit Form for IdentityRole. When the page is loaded I normaly receive the model with Id something like this "09e43076-c333-4145-bccb-8bc7f9db470e", but when the view is created I see that #Html.HiddenFor(m => m.Id) gets an old name value instead of Id (see screenshots in the links below). Why is it happening? Thanks!
GET: Edit
[HttpGet]
public ActionResult Edit(string id)
{
_context = new ApplicationDbContext();
if (User.Identity.IsAuthenticated)
{
if (!isAdminUser())
{
return RedirectToAction("Login", "Account");
}
}
else
{
return RedirectToAction("Login", "Account");
}
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));
var role = roleManager.FindByName(id);
return View(role);
}
View: Edit
#model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
#{
ViewBag.Title = "Edit Role";
}
<h2>Edit User Role:</h2>
#section RolesCSS {
<link href="#Url.Content("~/Views/Role/style/style.css")" rel="stylesheet"/>
<div class="form-group">
#using (Html.BeginForm("Edit", "Role", FormMethod.Post, new { #class = "AddRoleForm" }))
{
#Html.HiddenFor(m => m.Id)
#Html.HiddenFor(m => m.Users)
<div class="Label">
<p>Edit New User Role Name:</p>
</div>
<div class="FormControl">
#Html.EditorFor(m => m.Name, new {htmlAttributes = new {#class = "form-control"}})
</div>
<div class="FormControl">
<input class="btn btn-default" type="submit" value="Edit Role"/>
</div>
}
</div>
}
screenshot of values received as model in the view
screenshot of the source of the rendered html
Despite I've found a solution I'm still interested what was wrong with the first aproach.
I've found a workaround here (the content/explanation is in russian lang)
I created a class EditRoleModel as a temporary model, to avoid the issue I was having before,
public class EditRoleModel
{
public string Id { get; set; }
public string Name { get; set; }
}
that I pass as a model to View:
[HttpGet]
public ActionResult Edit(string id)
{
_context = new ApplicationDbContext();
if (User.Identity.IsAuthenticated)
{
if (!isAdminUser())
{
return RedirectToAction("Login", "Account");
}
}
else
{
return RedirectToAction("Login", "Account");
}
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));
var role = roleManager.FindByName(id);
var model = new EditRoleModel() {Id = role.Id, Name = role.Name};
return View(model);
}
then I slightly change the View to recieve model of type EditRoleModel:
#model WebUI.Models.EditRoleModel
#{
ViewBag.Title = "Edit Role";
}
<h2>Edit User Role:</h2>
#section RolesCSS {
<link href="#Url.Content("~/Views/Role/style/style.css")" rel="stylesheet"/>
<div class="form-group">
#using (Html.BeginForm("Edit", "Role", FormMethod.Post, new { #class = "AddRoleForm" }))
{
<div>#Model.Id</div>
#Html.HiddenFor(m => m.Id)
<div class="Label">
<p>Edit New User Role Name:</p>
</div>
<div class="FormControl">
#Html.EditorFor(m => m.Name, new {htmlAttributes = new {#class = "form-control"}})
</div>
<div class="FormControl">
<input class="btn btn-default" type="submit" value="Edit Role"/>
</div>
}
</div>
}
and finaly this is the controller where I update the IdentityRole:
[HttpPost]
public ActionResult Edit(EditRoleModel model)
{
_context = new ApplicationDbContext();
if (User.Identity.IsAuthenticated)
{
if (!isAdminUser())
{
return RedirectToAction("Login", "Account");
}
}
else
{
return RedirectToAction("Login", "Account");
}
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));
IdentityRole role = roleManager.FindByName(model.Id);
if (role != null)
{
role.Name= model.Name;
IdentityResult result = roleManager.Update(role);
if (result.Succeeded)
{
return RedirectToAction("Index");
}
else
{
ModelState.AddModelError("", "Something went wrong!");
}
}
return View(model);
}

MVC 5 - How to pull emdx data from controller to view

New to MVC! I can pull data from my Database first Entity Framework model (emdx) just fine... Works Great - Coolest thing ever! But I have 2 questions:
1) I cannot get the data back to my view. (I want to display the security question (being returned from my stored proc in my DB First Entity Data Model - emdx) and allow the user to answer the question.
2) I also can't seem to redirect to a view in a different view folder (from the "View\Account" folder to the "View\Home" folder.
I'm pretty sure this is easy and I'm just missing something basic.
Here is my MVC controller code:
public ActionResult Login(LoginViewModel model, string returnUrl)
{
string strEncr = "";
try
{
if (ModelState.IsValid)
{
//Create Hash with Salt for For New PWs
strEncr = Helper.ComputeHash(model.Password, "SHA512", null);
string DBPW = "";
string encryptedPassword = "";
try
{
using (var context = new WMSEntities1())
{
encryptedPassword = context.users
.Where(u => u.emailAddress == model.Username)
.Select(u => u.password)
.SingleOrDefault();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
//Test for match of PW between User and what's stored in DB
bool flag = Helper.VerifyHash(model.Password, "SHA512", encryptedPassword);
var loginInfo = databaseManager.LoginAndGetSecQuestion(model.Username, encryptedPassword).ToList();
// Verification.
if (loginInfo != null && loginInfo.Count() > 0)
{
// Initialization.
var logindetails = loginInfo.First();
// Login In.
this.SignInUser(logindetails.emailAddress, false);
ViewBag.SecurityQuestion = logindetails.securityQuestion;
// Info.
return View("~/Views/Home/Index.cshtml", loginInfo);
// return this.RedirectToLocal(returnUrl);
}
else
{
// Setting.
ModelState.AddModelError(string.Empty, "Invalid username or password.");
}
}
}
catch (Exception ex)
{
// Info
Console.Write(ex);
}
// If we got this far, something failed, redisplay form
return this.View(model);
}
Here is my code snipets in my view:
#*#model System.Data.DataSet*#
#model AodNetIntegration.LoginAndGetSecQuestion_Result
#{
ViewBag.Title = "Doc Center Login Screen";
}
#*<h2>#ViewBag.Title.</h2>http://asmak9.blogspot.com/2016/03/aspnet-mvc5-integrating-existing.html
<h3>#ViewBag.Message</h3>*#
#using (Html.BeginForm("LoginStage2", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<table cellspacing="5" style="width: 293px;">
<tr>
<td></td>
</tr>
<tr>
<td>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.LabelFor(m => m.securityQuestion, new { #class = "col-md-2 control-label, width= 50" })
#Html.DisplayFor(m => m.securityQuestion, new { #class = "col-md-2 control-label, width= 50" })
#Html.ValidationMessageFor(m => m.securityQuestion, "", new { #class = "text-danger" })<br />
#Html.LabelFor(m => m.securityQuestionAnswer, new { #class = "col-md-2 control-label" })
#Html.PasswordFor(m => m.securityQuestionAnswer, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.securityQuestionAnswer, "", new { #class = "text-danger" })
</td>
</tr>
<tr>
<td align="right" style="text-align: right;">
<input type="submit" value="Submit" class="btn btn-default" />
</td>
</tr>
</table>
Here is the error I get:
When it goes back to the Index page:
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[AodNetIntegration.LoginAndGetSecQuestion_Result]', but this dictionary requires a model item of type 'AodNetIntegration.LoginAndGetSecQuestion_Result'.
Controller Model Method:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace AodNetIntegration
{
using System;
public partial class LoginAndGetSecQuestion_Result
{
public int userID { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string securityQuestion { get; set; }
public string emailAddress { get; set; }
public string securityQuestionAnswer { get; set; }
}
}
Thanks,
Your query (var loginInfo = databaseManager....) is returning a collection of LoginAndGetSecQuestion_Result, not a single object, and you then return that collection to the view using
return View("~/Views/Home/Index.cshtml", loginInfo);
but you view expects a single LoginAndGetSecQuestion_Result object, not a collection.
You code should be
return View("~/Views/Home/Index.cshtml", logindetails);
However you can simplify your code by modifying the query to return a single object and testing for null
var loginInfo = databaseManager.LoginAndGetSecQuestion(model.Username, encryptedPassword).FirstOrDefault();
if (loginInfo != null)
{
this.SignInUser(loginInfo.emailAddress, false);
ViewBag.SecurityQuestion = logindetails.securityQuestion;
return View("~/Views/Home/Index.cshtml", loginInfo);
}
else
{
ModelState.AddModelError(string.Empty, "Invalid username or password.");
}

How can i make an image as an Ajax Action Link?

How can i make an image as an Ajax Action Link?
You could do this:
<a href="<%: Url.Action("someaction", "somecontroller") %>" id="mylink">
<img src="<%: Url.Content("~/images/foo.png") %>" alt="foo" />
</a>
and then in a separate javascript file AJAXify this link:
$(function() {
$('#mylink').click(function() {
$.ajax({
url: this.href,
type: 'GET',
success: function(result) {
alert('success');
}
});
return false;
});
});
And if you want to avoid the tag soup in your views you could write a custom helper:
public static class HtmlExtensions
{
public static MvcHtmlString ImageLink(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, object htmlAttributes, string imageSource)
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);
var image = new TagBuilder("img");
image.Attributes["src"] = urlHelper.Content(imageSource);
var anchor = new TagBuilder("a");
anchor.Attributes["href"] = urlHelper.Action(actionName, controllerName, routeValues);
anchor.MergeAttributes(new RouteValueDictionary(htmlAttributes));
anchor.InnerHtml = image.ToString(TagRenderMode.SelfClosing);
return MvcHtmlString.Create(anchor.ToString());
}
}
and then in your view simply:
<%: Html.ImageLink(
"someaction",
"somecontroller",
null,
new { id = "mylink" },
"~/images/foo.png"
) %>
and of course the process of AJAXifying it stays the same.
What about something like:
<a href='<%= Url.Action(...) %>'><img src='...' /></a>
Not certain if there is a helper that does this.
Bob
To push the id to the edit control whilst displaying an edit image instead of the word Spag you can try this:
#MvcHtmlString.Create(
Ajax.ActionLink("Spag", "Edit",
new { id = item.x0101EmployeeID },
new AjaxOptions() {
UpdateTargetId = "selectDiv",
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET"
}
).ToHtmlString().Replace(
"Spag",
"<img src=\"" + Url.Content("../../Images/edit.png") + "\" />"
)
)

dropdowns in asp.net mvc 2

I have asp.net mvc application in c# language. I want to develop the scenario like, my page will have have the 4 dropdown controls. on the selection of first , second's item should be load, on selction of 2'nd, 3'rd dropdown should be load it item. where as 4'th is independent. but on 4'th dropdown I want to change the UI design. what strategy I have to use here? how can i implement this scenario here.?
Edited:
Controller->action
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetSubjects(int standardId)
{
List<Subject> subjectList = basicEntityManager.GetSubjects(standardId);
JsonResult result=Json(subjectList, JsonRequestBehavior.AllowGet);
return result;
}
i am able to debug this but not fetching data.
Script:
<script type="text/javascript">
$(function() {
$('#StandardId').change
(function() {
var url='/Test/GetSubjects';
fetchItems(url, { standardId: $(this).val() }, $('#SubjectId')
);
/* $('#SubjectId').change(function() {
fetchItems(
'/Test/GetChapters',
{
selectedItem1: $('#SubjectId').val(),
selectedItem2: $(this).val()
},
$('#SelectedItem3')
);
});*/
});
});
function fetchItems(url, data, ddl) {
$.getJSON(url, data, function(items) {
alert(items);
$.each(items, function() {
ddl.append
(
$('<option/>').val(this.Value).text(this.Text)
);
});
});
}
function OnStandardChange() {
var standard = document.getElementById("StandardId");
var subject = document.getElementById("SubjectId");
var ActionUrl = "/Test/GetSubjects/"
alert("Hi");
// $.getJSON('/Test/GetSubjects', { standardId: standard.val() }, function(data) { });
}
$('#StandardId').change(function() {
});
function OnSubjectChange() {
}
function OnChapterChange() {
}
function addOption(selectbox, text, value) {
var optn = document.createElement("OPTION");
optn.text = text;
optn.value = value;
selectbox.options.add(optn);
}
</script>
You could cascade with AJAX:
Model:
public class MyViewModel
{
public string SelectedItem1 { get; set; }
public IEnumerable<SelectListItem> Items1 { get; set; }
public string SelectedItem2 { get; set; }
public string SelectedItem3 { get; set; }
public string SelectedItem4 { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
// Load initial data
Items1 = Enumerable.Range(1, 5).Select(x => new SelectListItem
{
Value = x.ToString(),
Text = "item " + x
})
};
return View(model);
}
public ActionResult Items2(string selectedItem1)
{
// invoked to populate the second DDL
return Json(
Enumerable.Range(1, 3).Select(x => new { Value = x, Text = x }),
JsonRequestBehavior.AllowGet
);
}
public ActionResult Items3(string selectedItem1, string selectedItem2)
{
// invoked to populate the third DDL
return Json(
Enumerable.Range(1, 3).Select(x => new { Value = x, Text = x }),
JsonRequestBehavior.AllowGet
);
}
public ActionResult Items4(string selectedItem1, string selectedItem2, string selectedItem3)
{
// invoked to populate the fourth DDL
return Json(
Enumerable.Range(1, 3).Select(x => new { Value = x, Text = x }),
JsonRequestBehavior.AllowGet
);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
View:
<script type="text/javascript">
$(function () {
$('#SelectedItem1').change(function () {
fetchItems(
'<%= Url.Action("items2") %>',
{
selectedItem1: $(this).val()
},
$('#SelectedItem2')
);
});
$('#SelectedItem2').change(function () {
fetchItems(
'<%= Url.Action("items3") %>',
{
selectedItem1: $('#SelectedItem1').val(),
selectedItem2: $(this).val()
},
$('#SelectedItem3')
);
});
$('#SelectedItem3').change(function () {
fetchItems(
'<%= Url.Action("items4") %>',
{
selectedItem1: $('#SelectedItem1').val(),
selectedItem2: $('#SelectedItem2').val(),
selectedItem3: $(this).val()
},
$('#SelectedItem4')
);
});
$('#SelectedItem4').change(function () {
alert('changing UI');
});
});
function fetchItems(url, data, ddl) {
$.getJSON(url, data, function (items) {
$.each(items, function () {
ddl.append(
$('<option/>').val(this.Value).text(this.Text)
);
});
});
}
</script>
<% using (Html.BeginForm()) { %>
<%= Html.DropDownListFor(x => x.SelectedItem1, new SelectList(Model.Items1, "Value", "Text"))
<%= Html.DropDownListFor(x => x.SelectedItem2, Enumerable.Empty<SelectListItem>()) %>
<%= Html.DropDownListFor(x => x.SelectedItem3, Enumerable.Empty<SelectListItem>()) %>
<%= Html.DropDownListFor(x => x.SelectedItem4, Enumerable.Empty<SelectListItem>()) %>
<input type="submit" value="OK" />
<% } %>

How to read the values returned by the Json?

I have the following code in my view:
<% using (Ajax.BeginForm("JsonCreate", new AjaxOptions { OnComplete = "createCategoryComplete" }))
{ %><div id="createCategory">
<fieldset>
<legend>Add new category</legend>
<p>
<%=Html.TextBox("CategoryId")%>
<%=Html.TextBox("Test")%>
<label for="name">Name:</label>
<%= Html.TextBox("Name")%>
<%= Html.ValidationMessage("Name")%>
</p>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
</div>
In the controller the code is as follows:
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult JsonCreate(string Name)
{
if (ModelState.IsValid)
{
try
{
//Return a json object to the javascript
return Json(new { CategoryId = 123, Test= "test successful" });
}
catch
{
#region Log errors about the exception
//Log error to administrator here
#endregion
}
}
//If we got this far, something failed, return an empty json object
return Json(new { /* Empty object */ });
}
What should be the code in the view for the following function to read the values returned by the Json and update the textboxes for CategoryId and Test?
function createCategoryComplete() {....???}
function createCategoryComplete(e) {
var obj = e.get_object();
alert(obj.CategoryId + ' ' + obj.Test);
}
Try this,
success: function(data) {
alert(data.CategoryId + " " + data.Test);
EDIT:
function createCategoryComplete(data)
{
document.getElementById("UrTxtBoxID").value = data.Test;
}