I have made some code inside of the spring boot back-end application which allows me to change a property of a specific object, this property which needs to be changed is the "status" property:
#Entity
public class Pakketje {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private int code;
private String status = "In magazijn";
public Pakketje() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
To change the property of that object, i will need to state the ID of that object (i think) inside of the react frontend application, and then fetch the PUT-method.
I will show you the method to change the property inside of my spring boot back-end application, this method can be found in the 'Service' class. 'bestaandPakketje' means existing pakketje.
#Override
public Pakketje getPakketjeById(int id) {
return pakketjeRepository.findById(id).orElse(null);
}
#Override
public Pakketje statusOnderweg(Pakketje pakketje) {
Pakketje bestaandPakketje = pakketjeRepository.findById(pakketje.getId()).orElse(null);
bestaandPakketje.setStatus(pakketje.getStatus());
return pakketjeRepository.save(bestaandPakketje);
}
}
And here is the controller:
public class PakketjeController {
#SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
#Autowired
private PakketjeService pakketjeService;
#PostMapping("/add")
public String add(#RequestBody Pakketje pakketje) {
pakketjeService.pakketjeOpslaan(pakketje);
return "Pakketje opgeslagen!";
}
#GetMapping("/getAll")
public List<Pakketje> getAllePakketjes(){
return pakketjeService.getAllePakketjes();
}
#GetMapping("/getById/{id}")
public Pakketje findPakketjeById(int id) {
return pakketjeService.getPakketjeById(id);
}
#PutMapping("/updateOnderweg")
public Pakketje statusIsOnderweg(#RequestBody Pakketje pakketje) {
return pakketjeService.statusOnderweg(pakketje);
}
}
Now the next step is verry hard for me. Each 'pakketje' has his own button which can be clicked to change the property (I will upload the picture so please check it). When that button is clicked the property automatically should change from "In magazijn "to "onderweg".
I would appreciate some help!
Now I face with some problems about principal data. Maybe it sounds like a fool. But I'm new to Spring..
I wanted to get some specific data from principal data, but it occured an error, So I cant.
this is my customUserDetails that implement UserDetails.
private String id;
private String pw;
private String name;
private String auth;
private String level;
private String label;
private int enabled;
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
ArrayList<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
authList.add(new SimpleGrantedAuthority(auth));
return authList;
}
#Override
public String getPassword() {
return pw;
}
#Override
public String getUsername() {
return id;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return enabled==1?true:false;
}
public String getName() {
return name;
}
public String getLabel() { return label;} // 4월 19일 동현 추가
public void setName(String name) {
this.name = name;
}
public String getAuth() {
return auth;
}
And this is principal data I got from console.log
CustomUserDetails(id=admin, pw=$2a$10$Z9C0gTGV0weknBvNi4YFY.l41vjrYo4UgO3MlPwgmIn4uDeYlepFq, name=Admin, auth=ROLE_ADMIN, level=null, label=N, enabled=1)
I want to extract label value from Principal, so I tried to do this code, but I can't.
console.log('${sessionScope.SPRING_SECURITY_CONTEXT.authentication.principal.label}');
How can I get 'label' data from principal?
Thank you for your kind support :)
In your Controller or any other bean, autowire user details like
public String doSomething(#AuthenticationPrincipal CustomUserDetails userDetails) {
String label = userDetails.getLabel();
}
I can"t understand the problem because i found nowhere the same problem.
i tried to insert product with type "pièces détachées". On the browser path /Produits the product doesn't show up but when i remove the accents from the string it's inserting in the mysql db. I tried to insert accents in the db the query is ok. But with my code it's impossible to do the same. here's a sample of my code for Produit :
//ajouter un produit
#PostMapping(value = "/Produits")
public ResponseEntity<Void> ajouterProduit(#RequestBody ProduitDTO produit) {
Produit produitCK = new Produit();
produitCK.setIdPM(new ProduitMagasin(produit.getId(), produit.getIdMagasin()));
produitCK.setDateAjout(produit.getDateAjout());
produitCK.setEtatProduit(produit.getEtatProduit());
produitCK.setIdReference(produit.getIdReference());
produitCK.setNumeroSerie(produit.getNumeroSerie());
produitCK.setPrixVente(produit.getPrixVente());
produitCK.setTVA(produit.getTVA());
produitCK.setType(produit.getType());
Produit produitAdded = produitDao.save(produitCK);
if (produitAdded == null)
return ResponseEntity.noContent().build();
else
return new ResponseEntity<>(HttpStatus.CREATED);
}
ProduitDTO :
package com.stationphone.db.model;
import java.sql.Timestamp;
/**
*
* #author Administrateur
*/
public class ProduitDTO {
private int id;
public enum Type {
PIECES {
public String getString() {
return "pièces detachées";
}
},
VENTE {
public String getString() {
return "vente en magasin";
}
};
public abstract String getString();
}
private String type;
private int id_reference;
private String numero_serie;
private Timestamp date_ajout;
private String marque;
private String modele;
private float prix_vente;
private double prixHT;
private float tva;
private String etat_produit;
private int id_magasin;
public int getId(){
return this.id;
}
public void setId(int id){
this.id=id;
}
public int getIdOnline(){
return this.id;
}
public void setIdOnline(int id){
this.id=id;
}
public String getType(){
return this.type;
}
public void setType(String type){
this.type=type;
}
public int getIdReference(){
return this.id_reference;
}
public void setIdReference(int id_reference){
this.id_reference=id_reference;
}
public String getNumeroSerie(){
return this.numero_serie;
}
public void setNumeroSerie(String numero_serie){
this.numero_serie=numero_serie;
}
public Timestamp getDateAjout(){
return this.date_ajout;
}
public void setDateAjout(Timestamp date_ajout){
this.date_ajout=date_ajout;
}
public String getMarque(){
return this.marque;
}
public void setMarque(String marque){
this.marque=marque;
}
public String getModele(){
return this.modele;
}
public void setModele(String modele){
this.modele=modele;
}
public float getPrixVente(){
return this.prix_vente;
}
public void setPrixVente(float prix){
this.prix_vente=prix;
}
public double getPrixHT(){
return this.prixHT;
}
public void setPrixHT(double prix){
this.prixHT=prix;
}
public float getTVA(){
return this.tva;
}
public void setTVA(float tva){
this.tva=tva;
}
public String getEtatProduit(){
return this.etat_produit;
}
public void setEtatProduit(String etat){
this.etat_produit=etat;
}
public int getIdMagasin(){
return this.id_magasin;
}
public void setIdMagasin(int id_magasin){
this.id_magasin=id_magasin;
}
}
class Produit :
package com.stationphone.db.model;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
/**
*
* #author Administrateur
*/
#Entity
public class Produit implements Serializable {
#EmbeddedId
private ProduitMagasin idPM;
#OneToOne
#JoinColumn(name = "id_magasin", insertable=false, updatable=false)
Magasin magasin;
public enum Type {
PIECES {
public String getString() {
return "pièces detachées";
}
},
VENTE {
public String getString() {
return "vente en magasin";
}
};
public abstract String getString();
}
private String type;
private int id_reference;
private String numero_serie;
private Timestamp date_ajout;
private float prix_vente;
private float tva;
private String etat_produit;
public ProduitMagasin getIdPM(){
return this.idPM;
}
public void setIdPM(ProduitMagasin id){
this.idPM=id;
}
public String getType(){
return this.type;
}
public void setType(String type){
this.type=type;
}
public int getIdReference(){
return this.id_reference;
}
public void setIdReference(int id_reference){
this.id_reference=id_reference;
}
public String getNumeroSerie(){
return this.numero_serie;
}
public void setNumeroSerie(String numero_serie){
this.numero_serie=numero_serie;
}
public Timestamp getDateAjout(){
return this.date_ajout;
}
public void setDateAjout(Timestamp date_ajout){
this.date_ajout=date_ajout;
}
public float getPrixVente(){
return this.prix_vente;
}
public void setPrixVente(float prix){
this.prix_vente=prix;
}
public float getTVA(){
return this.tva;
}
public void setTVA(float tva){
this.tva=tva;
}
public String getEtatProduit(){
return this.etat_produit;
}
public void setEtatProduit(String etat){
this.etat_produit=etat;
}
}
I hope i'll find an answer here. Thanks.
EDIT : the post method :
public static HttpResponse post(Object object, String type){
HttpResponse response=null;
try{
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPost postRequest = new HttpPost(getUrl(type));
System.out.println(getUrl(type));
ObjectMapper mapper= new ObjectMapper();
String jsonInString = mapper.writeValueAsString(object);
System.out.println(jsonInString);
StringEntity input = new StringEntity(jsonInString);
input.setContentType("application/json");
postRequest.setEntity(input);
response = client.execute(postRequest);
if (response.getStatusLine().getStatusCode() != 201) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
System.out.println(response.getStatusLine().getStatusCode()+" ");
client.close();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
return response;
}
EDIT 2 : the error on tomcat local :
018-07-24 18:55:32.196 WARN 10860 --- [nio-8084-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP
message:
org.springframework.http.converter.HttpMessageNotReadableException:
JSON parse error: Invalid UTF-8 middle byte 0x63
at [Source: (PushbackInputStream); line: 1, column: 21]; nested
exception is com.fasterxml.jackson.databind.JsonMappingException:
Invalid UTF-8 middle byte 0x63
at [Source: (PushbackInputStream); line: 1, column: 21]
at [Source: (PushbackInputStream); line: 1, column: 16] (through
reference
chain: com.stationphone.db.model.ProduitDTO["type"])
Thanks tp billy frost what to do 2 things :
HttpPost postRequest = new HttpPost(getUrl(type));
postRequest.setHeader("Content-Type", "application/json;charset=UTF-8");
StringEntity input = new StringEntity(jsonInString, "UTF-8");
I have a bean that implements JSObject ( & Map ) interface as shown below. I have removed some overridden methods to make it easy to read.
package test.nashorn;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import jdk.nashorn.api.scripting.JSObject;
public class JSBean implements JSObject, Map<String,Object>{
/**
* The current values for this object.
*/
private HashMap<String, Object> values = new HashMap<>();
#Override
public String toString() {
System.out.println("ToString");
Set<Entry<String,Object>> entries = values.entrySet();
StringBuilder sb = new StringBuilder();
for(Entry<String,Object> entry:entries){
sb.append(entry.getKey()+ " "+(String)entry.getValue());
}
System.out.println("Completed ToString");
return sb.toString();
}
#Override
public boolean hasMember(String name) {
return has(name);
}
// get the value of that named property
#Override
public Object getMember(String name) {
return get(name);
}
// get the value of that named property
#Override
public void setMember(String name,Object value) {
put(name,value);
}
public Object get(String name) {
System.out.println("JAVA Get is called."+name);
System.out.println("Called for this"+name+" and returned"
+":"+values.get(name));
return values.get(name);
}
#Override
public Object put(String name, Object value) {
System.out.println("JAVA Put is called. Input name: " + name + "\n Input values: " + value);
return values.put(name, value);
}
public boolean has(String name) {
System.out.println("JAVA Has is called. Input name: " + name);
return values.containsKey(name);
}
public JSBean() {
// TODO Auto-generated constructor stub
}
#Override
public Object call(Object arg0, Object... arg1) {
// TODO Auto-generated method stub
return null;
}
#Override
public Object eval(String arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public String getClassName() {
// TODO Auto-generated method stub
return null;
}
#Override
public Object getSlot(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean hasSlot(int arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isArray() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isFunction() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isInstance(Object arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isInstanceOf(Object arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isStrictFunction() {
// TODO Auto-generated method stub
return false;
}
}
When i run the test shown below
#Test
public void testDefaultValMethod(){
JSBean bean = new JSBean();
bean.setMember("hello", " Sport ");
//Add stuff to engine.
engine.put("jsBean", bean);
String source = "(function(){\n"
+ "print(jsBean);"
+ "} )();";
Object obj=null;
try {
obj = engine.eval(source);
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Returned : " + String.valueOf(obj));
}
I see the below error in the console. Ideally Nashorn should have directly called the toString() method of the bean to get the String implementation. Not sure what is going wrong here. I did try adding a call to 'toString()' explicitly in the getMember() method call but that did not fix the problem.
JAVA Put is called. Input name: hello
Input values: Sport
JAVA Get is called.toString
Called for thistoString and returned:null
JAVA Get is called.valueOf
Called for thisvalueOf and returned:null
javax.script.ScriptException: TypeError: cannot.get.default.string in <eval> at line number 2
at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:467)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:451)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
at test.nashorn.NashornTest.testDefaultValMethod(NashornTest.java:386)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: <eval>:2 TypeError: cannot.get.default.string
at jdk.nashorn.internal.runtime.JSType.toPrimitive(JSType.java:514)
at jdk.nashorn.internal.runtime.JSType.toPrimitive(JSType.java:480)
at jdk.nashorn.internal.runtime.JSType.toStringImpl(JSType.java:1391)
at jdk.nashorn.internal.runtime.JSType.toString(JSType.java:589)
at jdk.nashorn.internal.objects.Global.printImpl(Global.java:2782)
at jdk.nashorn.internal.objects.Global.println(Global.java:1497)
at jdk.nashorn.internal.scripts.Script$Recompilation$1$11$\^eval\_.L:1(<eval>:2)
at jdk.nashorn.internal.scripts.Script$\^eval\_.:program(<eval>:1)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:640)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446)
... 29 more
Caused by: java.lang.UnsupportedOperationException: cannot.get.default.string
at jdk.nashorn.api.scripting.DefaultValueImpl.getDefaultValue(DefaultValueImpl.java:53)
at jdk.nashorn.api.scripting.AbstractJSObject.getDefaultValue(AbstractJSObject.java:289)
at jdk.nashorn.internal.runtime.JSType.toPrimitive(JSType.java:512)
... 40 more
Returned : null
print or "toString" conversions from scripts call "toString" method on the script object. Any property access (including function valued property) on a JSObject is routed to getMember method. So, to make "valueOf" or "toString" you've to implement appropriate getMember in your JSObject subtype.
Example:
import jdk.nashorn.api.scripting.*;
import javax.script.*;
public class Main {
static class MyJSObject extends AbstractJSObject {
#Override
public Object getMember(String name) {
if (name.equals("toString")) {
// return a "function" object for "toString" property
return new AbstractJSObject() {
#Override
public boolean isFunction() {
return true;
}
#Override
public Object call(Object self, Object...args) {
return self.toString();
}
};
}
return null; // other properties here
}
#Override
public String toString() {
return "my js object";
}
}
public static void main(String[] a) throws Exception {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByName("nashorn");
e.put("myObj", new MyJSObject());
e.eval("print(myObj)");
}
}
Alternatively, you can also override
Object getDefaultValue(final Class<?> hint) throws UnsupportedOperationException
method in your AbstractJSObject subclass.
import jdk.nashorn.api.scripting.*;
import javax.script.*;
public class Main2 {
static class MyJSObject extends AbstractJSObject {
#Override
public Object getDefaultValue(Class<?> hint) {
if (hint == String.class) {
return toString();
}
throw new UnsupportedOperationException("no conversion for " + hint);
}
#Override
public String toString() {
return "my js object";
}
}
public static void main(String[] a) throws Exception {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByName("nashorn");
e.put("myObj", new MyJSObject());
e.eval("print(myObj)");
}
}
In MVC 4, you could install this package Twitter.bootstrap.mvc and this would add lots of HTML helpers.
Once istalled you could send alert to view right from controller.
For example:
public class AccountController : BaseController
{
public ActionResult AlertExample()
{
Success("This is a success alert");
Error("This is error alert");
Information("This is information alert");
...
etc.
}
}
This would send the success alert right from controller to the view.
Objective: Sending Growl Messages from controller
I've tried to implement same thing from the project I mentioned.
So, this is what I've added to my project.
Base controller that other controller derives from
public class BaseController : Controller
{
//
// GET: /Base/
public void Warning(string message)
{
TempData.Add(Alerts.WARNING, message);
}
public void Success(string message)
{
TempData.Add(Alerts.SUCCESS, message);
}
public void Information(string message)
{
TempData.Add(Alerts.INFORMATION, message);
}
public void Error(string message)
{
TempData.Add(Alerts.ERROR, message);
}
}
ControlGroupExtensionClass
namespace BootstrapSupport
{
public class ControlGroup : IDisposable
{
private readonly HtmlHelper _html;
public ControlGroup(HtmlHelper html)
{
_html = html;
}
public void Dispose()
{
_html.ViewContext.Writer.Write(_html.EndControlGroup());
}
}
public static class ControlGroupExtensions
{
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty)
{
return BeginControlGroupFor(html, modelProperty, null);
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty, object htmlAttributes)
{
return BeginControlGroupFor(html, modelProperty,
HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty, IDictionary<string, object> htmlAttributes)
{
string propertyName = ExpressionHelper.GetExpressionText(modelProperty);
return BeginControlGroupFor(html, propertyName, null);
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, string propertyName)
{
return BeginControlGroupFor(html, propertyName, null);
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, object htmlAttributes)
{
return BeginControlGroupFor(html, propertyName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static IHtmlString BeginControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, IDictionary<string, object> htmlAttributes)
{
var controlGroupWrapper = new TagBuilder("div");
controlGroupWrapper.MergeAttributes(htmlAttributes);
controlGroupWrapper.AddCssClass("control-group");
string partialFieldName = propertyName;
string fullHtmlFieldName =
html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(partialFieldName);
if (!html.ViewData.ModelState.IsValidField(fullHtmlFieldName))
{
controlGroupWrapper.AddCssClass("error");
}
string openingTag = controlGroupWrapper.ToString(TagRenderMode.StartTag);
return MvcHtmlString.Create(openingTag);
}
public static IHtmlString EndControlGroup(this HtmlHelper html)
{
return MvcHtmlString.Create("</div>");
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty)
{
return ControlGroupFor(html, modelProperty, null);
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, Expression<Func<T, object>> modelProperty, object htmlAttributes)
{
string propertyName = ExpressionHelper.GetExpressionText(modelProperty);
return ControlGroupFor(html, propertyName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, string propertyName)
{
return ControlGroupFor(html, propertyName, null);
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, object htmlAttributes)
{
return ControlGroupFor(html, propertyName, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static ControlGroup ControlGroupFor<T>(this HtmlHelper<T> html, string propertyName, IDictionary<string, object> htmlAttributes)
{
html.ViewContext.Writer.Write(BeginControlGroupFor(html, propertyName, htmlAttributes));
return new ControlGroup(html);
}
}
public static class Alerts
{
public const string SUCCESS = "success";
public const string WARNING = "warning";
public const string ERROR = "error";
public const string INFORMATION = "info";
public static string[] ALL
{
get { return new[] { SUCCESS, WARNING, INFORMATION, ERROR }; }
}
}
}
ViewHelperExtensionClass
namespace BootstrapSupport
{
public static class DefaultScaffoldingExtensions
{
public static string GetControllerName(this Type controllerType)
{
return controllerType.Name.Replace("Controller", String.Empty);
}
public static string GetActionName(this LambdaExpression actionExpression)
{
return ((MethodCallExpression)actionExpression.Body).Method.Name;
}
public static PropertyInfo[] VisibleProperties(this IEnumerable Model)
{
var elementType = Model.GetType().GetElementType();
if (elementType == null)
{
elementType = Model.GetType().GetGenericArguments()[0];
}
return elementType.GetProperties().Where(info => info.Name != elementType.IdentifierPropertyName()).ToArray();
}
public static PropertyInfo[] VisibleProperties(this Object model)
{
return model.GetType().GetProperties().Where(info => info.Name != model.IdentifierPropertyName()).ToArray();
}
public static RouteValueDictionary GetIdValue(this object model)
{
var v = new RouteValueDictionary();
v.Add(model.IdentifierPropertyName(), model.GetId());
return v;
}
public static object GetId(this object model)
{
return model.GetType().GetProperty(model.IdentifierPropertyName()).GetValue(model, new object[0]);
}
public static string IdentifierPropertyName(this Object model)
{
return IdentifierPropertyName(model.GetType());
}
public static string IdentifierPropertyName(this Type type)
{
if (type.GetProperties().Any(info => info.PropertyType.AttributeExists<System.ComponentModel.DataAnnotations.KeyAttribute>()))
{
return
type.GetProperties().First(
info => info.PropertyType.AttributeExists<System.ComponentModel.DataAnnotations.KeyAttribute>())
.Name;
}
else if (type.GetProperties().Any(p => p.Name.Equals("id", StringComparison.CurrentCultureIgnoreCase)))
{
return
type.GetProperties().First(
p => p.Name.Equals("id", StringComparison.CurrentCultureIgnoreCase)).Name;
}
return "";
}
public static string GetLabel(this PropertyInfo propertyInfo)
{
var meta = ModelMetadataProviders.Current.GetMetadataForProperty(null, propertyInfo.DeclaringType, propertyInfo.Name);
return meta.GetDisplayName();
}
public static string ToSeparatedWords(this string value)
{
return Regex.Replace(value, "([A-Z][a-z])", " $1").Trim();
}
}
public static class PropertyInfoExtensions
{
public static bool AttributeExists<T>(this PropertyInfo propertyInfo) where T : class
{
var attribute = propertyInfo.GetCustomAttributes(typeof(T), false)
.FirstOrDefault() as T;
if (attribute == null)
{
return false;
}
return true;
}
public static bool AttributeExists<T>(this Type type) where T : class
{
var attribute = type.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
if (attribute == null)
{
return false;
}
return true;
}
public static T GetAttribute<T>(this Type type) where T : class
{
return type.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
}
public static T GetAttribute<T>(this PropertyInfo propertyInfo) where T : class
{
return propertyInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
}
public static string LabelFromType(Type #type)
{
var att = GetAttribute<DisplayNameAttribute>(#type);
return att != null ? att.DisplayName
: #type.Name.ToSeparatedWords();
}
public static string GetLabel(this Object Model)
{
return LabelFromType(Model.GetType());
}
public static string GetLabel(this IEnumerable Model)
{
var elementType = Model.GetType().GetElementType();
if (elementType == null)
{
elementType = Model.GetType().GetGenericArguments()[0];
}
return LabelFromType(elementType);
}
}
//public static class HtmlHelperExtensions
//{
// public static MvcHtmlString TryPartial(this HtmlHelper helper, string viewName, object model)
// {
// try
// {
// return helper.Partial(viewName, model);
// }
// catch (Exception)
// {
// }
// return MvcHtmlString.Empty;
// }
//}
}
and the _alert partial View
#using BootstrapSupport
#if (TempData.ContainsKey(Alerts.WARNING))
{
<div class="alert alert-block">
<a class="close" data-dismiss="alert" href="#">x</a>
<h4 class="toast-title">Attention!</h4>
#TempData[Alerts.WARNING]
</div>
}
#foreach (string key in Alerts.ALL.Except(new[] { Alerts.WARNING }))
{
if (TempData.ContainsKey(key))
{
<div class="toast toast-top-full-width toast-key">
<button type="button" class="toast-close-button" data-dismiss="alert">x</button>
#TempData[key]
</div>
}
}
After all this I can send alert messages right from controller:
And it works!
For example
public ActionResult Test()
{
Success("Person was successfully added to your addressbook");
}
above code would result this in view
but it is just displaying as content block. Not as I expected to work, as it just appears in view, no effect, nothing. I wanted it to work as in this site Toastr.
I'm guessing I have to implement javascript somewhere in my _alert view and get the message and type(success, error,...) and then use javascript to growl it, to make it behave it as it should.
But i don't have much knowledge about it.
Something like below? Thats just idea, because of my lack of knowledge of Javascript and jquery i couldn't make it work
#*if (TempData.ContainsKey(key))
{
<div class="toastMessageHolder" style="display: none">
<div class="toastMessage">#TempData[key]</div>
<div class="toastMessageType">#key</div>
</div>
if($(".toastMessageHolder"))
{
//loop all toastMessageHolders
$(".toastMessageHolder").foreach(function(){
var message = $(".toastMessage", this).html();
var messageType = $(".toastMessageType", this).html();
});
//feed this parameters to javascript
}*#
Could somebody help me how to make my growling from controller behave as mentioned in example of Toastr?
If I had to growl from any normal view if I hadn't implemented sending msgs from controller to view this is how I would do using toastr:
function foo(response) {
if (response.SomeTest) {
toastr.error(response.ErrorMessage, "Error");
}
else {
$(#Html.IdFor(m=>m.abc)).val('');
}
};
Asp.Net MVC version: 5.1.1
Growling package used: Toastr
This is what I ended up doing.
_alert view(partial). To send alert messages right from controller.
#using BootstrapSupport
<script>
toastr.options = {
closeButton: true,
debug: false,
positionClass: "toast-top-full-width",
onclick: null,
showDuration: "300",
hideDuration: "1000",
timeOut: "5000",
extendedTimeOut: "1000",
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
}
</script>
#if (TempData.ContainsKey(Alerts.SUCCESS))
{
foreach (var value in TempData.Values)
{
<script>
toastr.success("#value.ToString()");
</script>
}
TempData.Remove(Alerts.SUCCESS);
}
#if (TempData.ContainsKey(Alerts.ERROR))
{
foreach (var value in TempData.Values)
{
<script>
toastr.error("#value.ToString()");
</script>
}
TempData.Remove(Alerts.ERROR);
}
#if (TempData.ContainsKey(Alerts.INFORMATION))
{
foreach (var value in TempData.Values)
{
<script>
toastr.warning("#value.ToString()");
</script>
}
TempData.Remove(Alerts.INFORMATION);
}
#if (TempData.ContainsKey(Alerts.WARNING))
{
foreach (var value in TempData.Values)
{
<script>
toastr.warning("#value.ToString()");
</script>
}
TempData.Remove(Alerts.WARNING);
}