#Url.Action does not pass parameters to the action method on submit - url.action

I have seen various posts for this problem and i have tried almost whatever solution I could find but nothing seems to work.
I need to pass parameter in the url from view to Controller. the url should look somethinkg like this:
https://localhost:44300/Name/GetName?name=Zeeba
In my View i have a text field and I enter a value in the text field, which i am trying to pass to Controller. My View is like this:
<div>
#Html.LabelFor(Name)
#Html.EditorFor(model => model.name)
</div>
<div>
<p><a class="btn btn-default" href="#Url.Action("GetName", "Name", new { name= Model.name})">Get Name</a>
</p>
</div>
My Controller is something like this:
public ActionResult GetName( string name)
{
string newName= Request.QueryString["name"];
}
When I enter the name in the textBox and click on the button the value of name in Controller is NULL.
Whereas if I add a hardcoded value for name the value is correctly passed to the Controller something like this:
<p><a class="btn btn-default" href="#Url.Action("GetName", "Name", new { name= "Zeeba" })">Get Name</a></p>
Why does it behave like this? Could someone please help.

Related

meteor - how to code a bootstrap modal template to re-render html input values even if the user has typed in them

I'm using iron router to pass data to a bootstrap modal template. The modal contains a html form including many text inputs. The modal is re-used for 3 different features. I use a Session variable to keep track of which modal type is in use. Type 0 = blank form, type 1 = partial edit, type 2 = full edit. The form itself remains the same visually for all types. The only thing that changes is which input boxes contain a value.
For a type 1 edit only 2 boxes would contain values. For a type 2 edit all boxes would contain values. And the type 0 would be empty boxes.
// routes.js
Router.route('/mypage', function () {
var mtype = Session.get("mtype");
this.layout('myLayout');
this.render('my_popup', {to:'my_popup', data: function() {
switch (mtype) {
case 1:
return {box1:'box 1 text', box2:'box 2 text', box3:''};
case 2:
return {box1:'box 1 text', box2:'box 2 text', box3:'box 3 value'};
default:
return {box1:'', box2:'', box3:''};
}
}});
});
// main.html
<template name="myLayout">
{{> yield "my_popup"}}
</template>
<template name="my_popup">
<div class="modal fade" id="my_popup">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title label label-primary">Title</div>
</div>
<div class="modal-body">
<form class="js-form-submit" id="my_form" name="my_form">
<div class="form-group">
<input class="form-control" type="text" name="box1" maxlength="64" placeholder="something" value="{{box1}}"/>
</div>
<div class="form-group">
<input class="form-control" type="text" name="box2" maxlength="64" placeholder="something" value="{{box2}}"/>
</div>
<div class="form-group">
<input class="form-control" type="text" name="box3" maxlength="64" placeholder="something" value="{{box3}}"/>
</div>
</form>
</div>
<div class="modal-footer">
<button class="js-form-ok btn btn-success btn-sm">submit</button>
<button class="btn btn-warning btn-sm" data-dismiss="modal">cancel</button>
</div>
</div>
</div>
</div>
</template>
Initially I tried passing an object to the modal template that only contained the properties that would be displayed. That didn't overwrite existing input values so I had to use the same object for each modal type and use empty strings for unused properties. I tried calling the reset() method on the form prior to showing the modal. In that case it caused the entire template to stop re-rendering.
Prior to showing the modal I set the session variable to the type of modal that will be displayed.
Session.set('mtype', 1);
That triggers iron router into sending the proper data to the template, unused properties are cleared and the template successfully re-renders.
Unfortunately if I type in one of the html inputs the template does not reset its value when it's re-rendered. This seems to be related to the same problem I encountered with the reset() method. If the input contains custom text (value is typed) then the modal doesn't display the new data sent to the template when the Session variable is changed. It preserves the user entered text.
What's the best way to re-use a bootstrap modal form in meteor? Should I use a helper instead of iron router to get the data object? Something like...
{{#with getData}}
Why is the user entered text being preserved?
I've also tried using the defaultValue attribute instead of value. The same issue occurs with both attributes.
To test the bug:
open the web console
Session.set('mtype',1);
$('#my_popup').modal('show');
type something in the 3rd text box
click off the modal to hide it
Session.set('mtype',0);
$('#my_popup').modal('show');
You'll see that the value you typed is still visible despite having sent empty strings to each box.
Another way:
Session.set('mtype',2);
$('#my_form')[0].reset();
Session.set('mtype',1);
$('#my_popup').modal('show');
You'll see that none of the boxes contain values despite having sent new strings of text to each box.
The only solution I've found is to use defaultValue in the template and then loop through the form fields before modal is shown and set value = defaultValue.
<input class="form-control" type="text" name="box1" maxlength="64" placeholder="something" defaultValue="{{box1}}"/>
Template.my_popup.rendered = function() {
$("#my_popup").on('show.bs.modal', function() {
var elems = $('#my_form')[0].elements;
for (var i=0; i<elems.length; i++) {
if (elems[i].hasAttribute('defaultValue')) {
elems[i].value = elems[i].getAttribute('defaultValue');
}
}
});
};

Posting Html with images (WYSIWYG) to ASP.net core controller

I'm having trouble posting my wysiwyg content to my controller in asp.net core. I can't seem to get any value from the form editor. The value for the Content property comes to the controller as null. I'm using the summernote form editor to handle my richtext box editor.
Here is my code
public class Editor
{
public int EditorId { get; set; }
public string Content { get; set; }
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Editor editor)
{
if (ModelState.IsValid)
{
_context.Add(editor);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(editor);
}
View:
<h2>Create</h2>
<h4>Editor</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Content" class="control-label"></label>
<textarea asp-for="Content" id="summernote" name="editordata"></textarea>
<span asp-validation-for="Content" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
<script>
$(document).ready(function () {
$('#summernote').summernote();
});
</script>
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote.js"></script>
}
#section Styles{
<!-- include libraries(jQuery, bootstrap) -->
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<!-- include summernote css/js -->
<link href="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.9/summernote.css" rel="stylesheet">
}
So the issue is when I post the form it's gets to the controller but the content comes over as null. I'm not sure how to post the content
Here are my thoughts, I'm thinking i'm missing a some attribute that allows html to come over the wire to my controller, but all the reserach i've found is that asp.net core doesn't require that. Or I need to handle this type of request in the middleware pipeline, but that doesn't make much sense since it's just html strings i'm sending over the wire to the controller.
It looks like the top of your view was not left out, I assume you have Editor as model.
The problem is on your text area you are using both asp-for and then setting the id and name to something that doesn't match your model property.
You should just use asp-for and let it decide the id and name instead of adding those yourself.
What is really getting posted is a string named editordata because you used that name on the textarea. remove that and it will be named Content to match the property of the model
You also don't need the [Bind] attribute shown in the controller action in your screenshot.
I have been sitting with the same issue and was able to resolve it due to Joe's answer!
Could I suggest working on the summernote class for the text area instead of using your id?
I noticed when I use the id that my textarea's display property doesn't get set to none, but it works when i use the class="summernote".
<textarea asp-for="Instructions" class="summernote"></textarea>
<script>
$(document).ready(function () {
$('.summernote').summernote();
});
</script>
Put this script in your page head:
<script src="https://cdn.ckeditor.com/4.13.0/standard/ckeditor.js"></script>
Lets say you have model called ForumModel where you save contents of editor. Property where you your content is saved is called answer:
public string Answer { get; set; }
So in your view you have following tag:
#model ForumModel
Therefore if you want to add editor:
<textarea id="editor1" asp-for="#Model.Answer" class="form-control" required=""></textarea>
<script>
CKEDITOR.replace("editor1");
</script>
And now all that is left is to call your controller on submit button. When your form is submitted you go to constructor that saves your contents.
public IActionResult Reply(ForumModel forumModel)
{
forumModel.SaveReply();
return RedirectToAction("SomeRandomPage");
}

ember.js: how to delete a record using a view

in ember's official guide, they say it's possible to delete a record using a view, but they don't provide an example of how to do it. i can't understand how views can get the id of the object do destroy.
maybe i didn't understand what's the view purpose? i think it's an event handler (but i see sometimes it's used to render chunks of hbl... maybe that's why i'm confusing)
is there an example of the whole process of deletion anywhere?
thank you
Generally, what you want to do is create an {{action}} in your view that sends an event to where it should actually be handled: either the controller or the route. (In my case, a little of both)
Note: Generally, you don't need to write a View class for templates, unless the view needs a particular event handler. Ember generates a generic view on-the-fly. You can see this through {{log view}}:
<script type="text/x-handlebars" data-template-name="app">
{{log view}}
</script>
If you look in the console you will find that the template app is associated with a view class:
For example, in the following view template, I'm defining a "Delete" button, which will trigger the action remove in the controller.
<script type="text/x-handlebars" data-template-name="product/remove">
<fieldset>
<legend>Remove</legend>
<div class="row-fluid">
Are you sure you want to delete <strong>{{content.name}}</strong>?
</div>
</fieldset>
<ht />
{{#linkTo products class="btn"}}Back to List{{/linkTo}}
<button {{action remove target="controller"}} class="btn btn-danger">
Delete
</button>
</script>
The controller simply gets the content property and signals the route to fire the confirmRemove event, passing its content as the argument
App.ProductRemoveController = Em.ObjectController.extend({
remove: function() {
this.get('target').send('confirmRemove', this.get('content'));
}
});
And the route actually handles it like this:
App.ProductRemoveRoute = Em.Route.extend(App.NotifyHandler, {
setupController: function(controller, model) {
var c = this.controllerFor('product');
controller.set('content', c.get('content'));
},
events: {
confirmRemove: function(record) {
record.deleteRecord();
// should commit here
// this.get('store').commit();
this.controllerFor('application').set(
'notification', 'Product has been removed'
);
this.transitionTo('products');
}
}
});
(see fiddle)
If you want to handle the event directly in the Route, without talking to the controller, in your view template, you simply omit the target="controller", and the framework will look up for a handler of that event in the controller, and if doesn't find, it will look up in the route. In this approach, you have to pass the event argument via Handlebars, if any argument is required. In this case, I know that this represents the content in that template:
<script type="text/x-handlebars" data-template-name="product/remove">
<fieldset>
<legend>Remove</legend>
<div class="row-fluid">
Are you sure you want to delete <strong>{{content.name}}</strong>?
</div>
</fieldset>
<ht />
{{#linkTo products class="btn"}}Back to List{{/linkTo}}
<button {{action confirmRemove this}} class="btn btn-danger">
Delete
</button>
</script>
With this approach, you don't need to define anything in your controller as it will fire the event directly in the route:
App.ProductRemoveController = Em.ObjectController.extend();
(see fiddle)
Update: In order to have the event handled in the object controller, the itemController property has to specify a controller, which should extend Em.ObjectController:
Depot.TransportDocumentsController = Ember.ArrayController.extend
itemController: 'transportDocument'
Depot.TransportDocumentController = Ember.ObjectController.extend
removeItem: ->
alert("aoooo")
The only thing that would be changed in a template would be the mention of the itemController in the {{each}} helper:
{{#each doc in controller itemController="transportDocument"}}
{{doc.number}}
<!-- rest of the template removed to make this short. -->
<button {{action removeItem}} class='btn btn-danger btn-small'>
<i class="icon-white icon-remove"></i>
</button>
{{/each}}
In the action, you don't need to say where the handler is located, as the framework can find the target on its own.
(see fiddle)

ASP.NET MVC2 +file uploading (HttpPostedFileBase class)

I have problem with uploading my file. I want to upload it from my edit view:
<%
using (Html.BeginForm("edit","profile",FormMethod.Post, new { enctype="multipart/form-data" }))
{%>
<%: Html.ValidationSummary(true) %>
<%: ViewData["ErrorMessage"] %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.Image) %>
</div>
<div class="editor-field">
<input type="file" id="Image" name="Image" />
<label id="LabelErrorImage" class="errorMessage" />
</div>
<p>
<input type="submit" value="Save" onclick="return Validate(); return false;"/>
</p>
</fieldset>
<% } %>
I want to use HttpPostedFileBase class. My edit action:
[Authorize]
[HttpPost]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(string id, HttpPostedFileBase file, FormCollection formValues)
{
if (ModelState.IsValid)
{
if (file != null && file.ContentLength > 0)
{
CustomHelpers.createFolder();
var tmpPath = MyConfig.UPLOAD_FILE_PATH + "/" + Membership.GetUser().ProviderUserKey.ToString();
var path = Path.Combine(Server.MapPath(MyConfig.UPLOAD_FILE_PATH), "Avatar");
var fileExtension = Path.GetExtension(file.FileName);
file.SaveAs(path);
user.Image = "Avatar";
}
adventureDB.SaveChanges();
return RedirectToAction("Index");
}
}
But I always have empty the file object, why????? Do you have any ideas, suggestions why it can work like that? Maybe there is problem how I pass on the file value to my Edit action?
EDIT:
IT IS REALLY STRANGE AS EVEN WHEN I REMOVE
using (Html.BeginForm("Index","Profile",FormMethod.Get, new { enctype="multipart/form-data" }))
The page source still has:
<body>
<form method="post" action="6111e591-b92d-4bcb-b214-ab8f664b35f9" id="form1">
I mean I can not change the tag but have no idea why :/
Try changing:-
public ActionResult Edit(string id, HttpPostedFileBase file,
FormCollection formValues)
to:-
public ActionResult Edit(string id, HttpPostedFileBase image,
FormCollection formValues)
as the name of your input is image
<input type="file" id="Image" name="Image" />
edit
To be honest something else is stopping the binding of image. Is this the whole form that you have posted?
A few things to test
You have HTTPOST decorating your method twice, although I don't believe this should make a difference.
View the source and make sure there is nothing else named name=image in the source.
Make sure you empty your cache and make sure source is correct before testing again
Try using <form action="/profile/index" method="post" enctype="multipart/form-data">
Judging by your last edit you have a problem with master pages/layout? Is this a mvc/webforms hybrid?
The solution of this problem when:
We use Master.Site,
We want to upload file in a view,
We are sure that it should work but we all the time has null,
Then:
Guys were right - I had wrong name in my view - check it!
Check source code of your view and if you have 2 < form > tags you should remove the < form > tag from Master site as then the second one is ignored!
Now it should work.
Well, in your view you named the file input 'image' but your action method accepts a parameter called 'file'. Rename one of those and it should work.

How can I call a controller action passing a fixed string and a value from a dropdown combo?

I'm sure what I want to do is possible, but I can't figure out how.
I have a view which shows some information about the selected user, including their roles. I have added a dropdown to the view showing all the roles and want to have a button which will add the selected role from the dropdown to the current user. To allow this I have a controller with this method:
public ActionResult AddUserRole (string userName,string roleName)
{
if (Roles.IsUserInRole (userName,roleName)==false)
{
Roles.AddUserToRole (userName,roleName);
}
return RedirectToAction("Profile", "Profile",new {userName=userName});
}
but I can't figure out how I set the selected item in the dropdown from the view to be the string roleName parameter in the controller method. I can set the userName easily enough as this is static. What am I missing? Here's my view, or at least the relevant bit:
<%
using (Html.BeginForm( "AddUserRole", "Account",new {userName=Model.UserName}))
{%>
<div id="AddRoleToUser">
<asp:Label ID="Label1" runat="server" Text="Select new role."></asp:Label>
<%:Html.DropDownListFor(model=>model.Roles,new SelectList (Model.Roles),null,new {id="roleName"}) %>
<input type="submit" value="Create" />
</div>
<% }%>
<%}%>
Model.Roles is an IEnumerable<String> type;
it seems that changing the name of the parameter in the controller action gave me what I wanted:
public ActionResult AddUserRole (string userName,string roles)
{
if (Roles.IsUserInRole (userName,roles)==false)
{
Roles.AddUserToRole (userName,roles);
}
return RedirectToAction("Profile", "Profile",new {userName=userName});
}
<%
using (Html.BeginForm( "AddUserRole", "Account",new {userName=Model.UserName}))
{%>
<div id="AddRoleToUser">
<asp:Label ID="Label1" runat="server" Text="Select new role."></asp:Label>
<%:Html.DropDownListFor(model=>model.Roles,new SelectList (Model.Roles)) %>
<input type="submit" value="Create" />
</div>
<% }%>
<%}%>
not sure how I would alias that to something else, but for now it works so it'll be ok.