I've created a newsletter subscription form in Umbraco 5 using a Surface Controller. The controller renders a form with the input fields for the user. When I translate text in the view all works fine. I can use:
Umbraco.GetDictionaryItem("newslettertitle")
Or
#("newslettertitle".Localize())
When I handle the form submit I need to send a localized email. But localizing text doesn't work:
example:
var mail = new MailMessage();
mail.From = new MailAddress(settings.Smtp.From);
mail.To.Add(aSubscriber.Email);
mail.Subject = "newslettersucces".Localize();
The subject of the mail = (Umbraco.Cms.Web.newslettersucces). No localization. The same happens when I use GetDictionaryItem("newslettersuccess"). Any advice will be greatly appreciated.
You can push an Umbraco Helper in the view where you need Umbraco.GetDictionaryItem.
Created a BaseSurfaceController like:
public class BaseSurfaceController : SurfaceController {
public UmbracoHelper Umbraco{
get {
IRenderModelFactory modelFactory = DependencyResolver.Current.GetService<IRenderModelFactory>();
return new UmbracoHelper(this.ControllerContext, this.RoutableRequestContext, modelFactory);
}
}
}
And also a base ViewModel:
public class BaseViewModel
{
public UmbracoHelper Umbraco { get; set; }
}
Example:
[ChildActionOnly]
public PartialViewResult ContactForm()
{
var model = new ContactViewModel();
model.Umbraco = this.Umbraco;
return PartialView(model);
}
Source: http://our.umbraco.org/forum/core/umbraco-5-general-discussion/29601-MVC-form-localization-ViewModel-plus-Umbraco-DictionaryItem
Related
Hi i am started working on umbraco CMS can anybody tell me how to display contents from model to controller and return data to respective view, want to do something like this :-
ContactViewModel.cs
public int id { get; set; }
public string Name { get; set; }
public string address { get; set; }
public string Email { get; set; }
public string phone { get; set; }
ContactController.cs
var result = new ContactViewModel()
{
id = 1,
address = "ghivto",
Email = "nimesh#gmail.com",
Name = "Nimesh khatri",
phone = "9898989898"
};
return View("contactsDemo",result);
how do i list above data to particular view..? i had already tried "https://www.youtube.com/watch?v=sDQwu_DzYyc" but still i didn't get...can anyone elaborate it..thanks in advance..
SurfaceController exposes a controller like you would use in standard MVC and also gives access to the Umbraco helpers.
public MyController : SurfaceController {
[ChildActionOnly]
public PartialViewResult MyAction(SomeObject data)
{
var result = new ContactViewModel()
{
id = 1,
address = "ghivto",
Email = "nimesh#gmail.com",
Name = "Nimesh khatri",
phone = "9898989898"
};
return View("~/Views/PartialViews/contactsDemo.cshtml",result);
}
}
You can access this data from a Template's razor view or a Macro partial by using:
#Html.Action("MyAction","MyController", new { data = new { Test = "I am data" } })
Note: The data passing can be anything, from a single string to full object which binds to variables at the action.
As with MVC there a few ways to access a partial view file. The above example has an "absolute" path, which you could also match your view folder structure to the name of the controller and the view name to the action name. (MyAction.cshtml).
If you want to do that in Umbraco, and still have access to the Umbraco tempting system etc, you need to use a SurfaceController. This is a controller that inherits all of the useful Umbraco Stuff.
Basically, you'd create your ViewModel, and then a Surface Controller to handle all the actions (Render, Process etc). You'd then call that Surface Controller on your Umbraco View for the Contact Page (or whichever page you want this to show on).
It looks like the video you linked to already covers how to do this, but you can find an example that's pretty similar to your example here: http://creativewebspecialist.co.uk/2013/07/22/umbraco-mvc-what-on-earth-is-a-surface-controller/
I have only taken a small draft from the side,
it is such that I must have sent some data in my database,
what I've read me to is that such textbox must have the same name throughout from the controller has and model,
index.cshtml
#Html.TextBox("Email", null, new
{
#class = "form-control input-lg",
placeholder = "Skriv email her",
type = "email"
})
Kontocontroller.cs
[HttpPost]
public ActionResult CreateUsers(OpretBrugere brugere)
{
if (ModelState.IsValid)
{
//Is that the right way that I must find out something with database or should I do it differently?
var email = Request["Email"].ToString();
var CreateAnAccount = db.Users.FirstOrDefault(b => b.Email == email);
if(CreateAnAccount != null)
{
brugere.Email = email;
}
}
}
on my model have i opretbrugere.cs
public class OpretBrugere
{
public int UserId { get; set; }
public string Email { get; set; }
}
What do I wrong såden that it will not go into the database, as I said, I have much more to model and cshtml ago to be entered into the database, but I will make a brief description of the task that make it easy for you.
It could be better if you use MVC's model binder. Do something like this:
In your view add your model OpretBrugere as view model
#model Mynamespace.OpretBrugere
and then use html helper to generate proper input like this:
#html.EditorFor(m=>m.Email)
then in your controller you could read data from action's parameter:
[HttpPost]
public ActionResult CreateUsers(OpretBrugere brugere)
{
if (ModelState.IsValid)
{
var email = brugere.Email; // user's submitted data is here
// save to db or whatover you want
}
}
I have a _LoginPartial View and want to send data to it by ViewBag, but the Controller that I'am sending data from, doesn't have a View.
public PartialViewResult Index()
{
ViewBag.sth = // some data
return PartialView("~/Views/Shared/_LoginPartial.cshtml");
}
This code didn't work for me.
It seems you're expecting this Index action to be called when you do: #Html.Partial('_LoginPartial'). That will never happen. Partial just runs the partial view through Razor with the current view's context and spits out the generated HTML.
If you need additional information for your partial, you can specify a custom ViewDataDictionary:
#Html.Partial("_LoginPartial", new ViewDataDictionary { Foo = "Bar" });
Which you can then access inside the partial via:
ViewData["Foo"]
You can also use child actions, which is generally preferable if working with a partial view that doesn't need the context of the main view. _LoginPartial seems like a good candidate, although I'm not sure how exactly you're using it. Ironically, though, the _LoginPartial view that comes with a default MVC project with individual auth uses child actions.
Basically, the code you have would already work, you would just need to change how you reference it by using Html.Action instead of Html.Partial:
#Html.Action("Index")
Notice that you're calling the action here and now the view.
You can always pass data directly to the partial view.
public PartialViewResult Index()
{
var data = // some data
return PartialView("~/Views/Shared/_LoginPartial.cshtml", data);
}
Pass multiple pieces of data
public class MyModel
{
public int Prop1 { get; set; }
public int Prop2 { get; set; }
}
public PartialViewResult Index()
{
var data = new MyModel(){ Prop1 = 5, Prop2 = 10 };
return PartialView("~/Views/Shared/_LoginPartial.cshtml", data);
}
I passed viewBag data to my partial view like below, and I converted that viewBag data object to JSON in my partial view by using #Html.Raw(Json.Encode(ViewBag.Part));
my code sample is given below.
public async Task<ActionResult> GetJobCreationPartialView(int id)
{
try
{
var client = new ApiClient<ServiceRepairInspectionViewModel>("ServiceRepairInspection/GetById");
var resultdata = await client.Find(id);
var client2 = new ApiClient<PartViewModel>("Part/GetActive");
var partData = await client2.FindAll();
var list = partData as List<PartViewModel> ?? partData.ToList();
ViewBag.Part = list.Select(x => new SelectListItem() {Text = x.PartName, Value = x.Id.ToString()});
return PartialView("_CreateJobCardView" ,resultdata);
}
catch (Exception)
{
throw;
}
}
Here i have passed both model and viewBag .
First off, the code in your question does not run. When you do #Html.Partial("_SomeView") the Index() method you have there does not run. All #Html.Partial("_SomeView") does is render _SomeView.cshtml in your current view using the current view's ViewContext.
In order to get this to work you need a bit of functionality that's common to all the controllers in your project. You have two options: extension method for ControllerBase or a BaseController that all the controllers in your project inherit from.
Extension method:
Helper:
public static class ControllerExtensions
{
public static string GetCommonStuff(this ControllerBase ctrl)
{
// do stuff you need here
}
}
View:
#ViewContext.Controller.GetCommonStuff()
BaseController
Controller:
public class BaseController : Controller
{
public string GetCommonStuff()
{
// do stuff you need here
}
}
Other controllers:
public class SomeController : BaseController
...
...
View:
#((ViewContext.Controller as BaseController).GetCommonStuff())
I am developing an application. I have created a view and a controller. The view has a button, on the click of which I am supposed to do database operations. I have put the database operations in the model, I am creating the object of model in the controller. On clicking the button the action is handled by a method in the controller, and the object of the model is created to get the records from the database. I would like to know if there is any way to display this data in the view.Is the approach correct or the view is supposed to interact with model directly to get the data.
Following is the code in controller that gets invoked on the button click
public ActionResult getRecord()
{
DataModel f_DM = new DataModel();
DataTable f_DT = f_DM.getRecord();
return View();
}
DataModel is the model class with simply a method "getRecord".
Any help will be highly appreciated.
I would like to add that i am using vs2010 and mvc4
Regards
you should write the logic of retrieving data in your controller. Store all your data in view model and pass it to the view.
for eg.
Model
namespace Mvc4App.Models
{
public class Product
{
public string Name { get; set; }
}
public class ProductViewModel
{
public Product Product { get; set; }
public string SalesPerson { get; set; }
}
}
Controller
public class ProductController : Controller
{
public ActionResult Info()
{
ProductViewModel ProductViewModel = new ProductViewModel
{
Product = new Product { Name = "Toy" },
SalesPerson = "Homer Simpson"
};
return View(ProductViewModel);
}
}
View
#model Mvc4App.Models.ProductViewModel
#{ ViewBag.Title = "Info"; }
<h2>Product: #Model.Product.Name</h2>
<p>Sold by: #Model.SalesPerson</p>
This is the best known practice to pass data from controller to the view.
you may use other techniques also like,
1. ViewData
2. ViewBag
3. TempData
4. View Model Object
5. Strongly-typed View Model Object
Yes, it's possible, but actually now very logical way to to this.
Lets follow your way. You have some View were you have a button, that will trigger this action.
For ex:
public ActionResult Index()
{
return View();
}
Inside view you can have a Ajax link, that will trigget your getRecord method:
<div id="GetDataDiv"></div>
<div>
#Ajax.ActionLink("Get Record", "getRecord", "ControllerName", null, new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "GetDataDiv" })
</div>
In the getRecord method you should have:
public ActionResult getRecord()
{
DataModel f_DM = new DataModel();
DataTable f_DT = f_DM.getRecord();
return PartialView(f_DT);
}
And in View it should be:
#model DataTable
#Model.PropertyOne #Model.PropertyTwo
It should works for you.
Actually same exaple here: http://www.dotnetpools.com/Article/ArticleDetiail/?articleId=151
I'm using ASP.Net MVC 4 and MVCMailer 4.0 from Nuget. When I create a message and send it to the scaffolded Welcome message everything works fine and I'm able to send the email just fine (the only thing is that its in plain text where as I have html in it)
My problem comes when I use the Contact form to send a message. First let me show you what I have and how I'm using it:
/*UserMailer.cs*/
public virtual MvcMailMessage ContactForm(MailMessage mailmessage)
{
ViewBag.Name = mailmessage.Name;
ViewBag.Body = mailmessage.MessageBody;
return Populate(x =>
{
x.Subject = "Scheduler) " + mailmessage.Subject;
x.ViewName = "Contact Form";
x.To.Add("Hiva#Varyan.com");
});
}
Now on to the View
#*ContactForm.cshtml*#
<h2>ContactForm</h2>
<strong>Name: </strong> #ViewBag.Name <br />
<strong>Message: </strong> #ViewBag.Body
And Lastly the Contact Controller actions that instantiates the mailer and sends the mail
//ContactController.cs
namespace Scheduler.Controllers
{
public class ContactController : Controller
{
//
// GET: /Contact/
private IUserMailer _userMailer = new UserMailer();
public IUserMailer UserMailer
{
get { return _userMailer; }
set { _userMailer = value; }
}
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(MailMessage _mailMessage)
{
UserMailer.ContactForm(_mailMessage).Send();
return View();
}
}
}
Just for Completeness I'll include my model as well
//MailMessage.cs
namespace Scheduler.Model
{
public class MailMessage
{
public string Name { get; set; }
public string EmailAddress { get; set; }
public string Subject { get; set; }
public string MessageBody { get; set; }
}
}
ok, so there are multiple issues that I'm having:
This code somehow generates 2-3 copies of the email and just in case I was even very careful of clicking the submit button on the form.
All the copies of the messages, contain the right From Email address, subject but it does not have any body at all (the messages actually show as "This message has no content" on my phone)
Lastly, when I did have it working (when I first implemented it, and I can't for the life of me see what I did for it to stop working) it sends all messages as plain text and not html.
I've just started learning ASP.Net MVC and if there are any pointers on how to implement the above correctly would be greatly appreciated.
I'm sorry, I've mistakenly placed a space in the x.ViewName and since it was really late didn't catch it.