I'm developing a small system with four areas, when I test it in Localhost, it works fine, but when I publish it in IIS 7.5 it does not find the routes of any area
I have tried adding namespaces in the route config, in the config of the areas and it does not work in any way
File RouteConfig:
namespace Gamma
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
//routes.RouteExistingFiles = true;
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
Areas:
File AdministradorAreaRegistration
namespace Gamma.Areas.Administrador
{
public class AdministradorAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Administrador";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Administrador_default",
"Administrador/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
}
File GestorAreaRegistration
namespace Gamma.Areas.Gestor
{
public class GestorAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Gestor";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Gestor_default",
"Gestor/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
}
File UsuarioAreaRegistration
namespace Gamma.Areas.Usuario
{
public class UsuarioAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Usuario";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Usuario_default",
"Usuario/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
}
Controllers:
Start of the application
Home
Areas:
HomeAdminController
VehiculoController
ProveedorController
HomeGestorController
VehiculoController
ProveedorController
HomeUsuarioController
VehiculoController
ProveedorController
Global.asax
namespace Gamma
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
In Account Controllers Login
switch (ViewBag.RoleName)
{
case "Admin":
return RedirectToAction("Bienvenida", "HomeAdmin", new { #area = "Administrador" });
case "Usuario":
return RedirectToAction("Bienvenida", "HomeUsuario", new { #area = "Usuario" });
case "Gestor":
return RedirectToAction("Bienvenida", "HomeGestor", new { #area = "Gestor" });
case "Cliente":
return RedirectToAction("Bienvenida", "HomeClientes", new { #area = "Clientes" });
default:
return RedirectToAction("Bienvenida", "HomeUsuario", new { #area = "Usuario" });
In Localhost works fine
In IIS:
Error.
Error al procesar la solicitud.
Administrador/HomeAdmin/Bienvenida
In the tests he tells me he can not find the route
Error de servidor en la aplicación '/'.
________________________________________
No se encuentra el recurso.
Descripción: HTTP 404. El recurso que está buscando (o una de sus dependencias) se puede haber quitado, haber cambiado de nombre o no estar disponible temporalmente. Revise la dirección URL siguiente y asegúrese de que está escrita correctamente.
Dirección URL solicitada: /Administrador/HomeAdmin/Bienvenida
Thank you in advance for your help
Have you updated the Global.asax file with AreaRegistration.RegisterAllAreas();
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
Related
I am working with a BD rom or DAo everyone calls her in a way. It is a shopping list with 2 activity 1 a recycleView and another to add. When you start the app, the idea is to verify if there is something in the database or in the array of the recycler, if there is, then start it and if not, then go to the activity to add. The problem is that even having products, it tells me that there are none. I leave the code. This is the Main
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE = 10;
private RecyclerView rv1;
private AdaptadorProducto adaptador;
private List<Producto> datos = new ArrayList<>();
private Context contexto;
private ListaCompraViewModel listaCompraViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
contexto = this;
setContentView(R.layout.activity_main);
listaCompraViewModel =
ViewModelProviders.of(this).get(ListaCompraViewModel.class);
rv1 = findViewById(R.id.rv1);
adaptador = new AdaptadorProducto(this, datos);
rv1.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
rv1.setHasFixedSize(true);
rv1.setAdapter(adaptador);
registerForContextMenu(rv1);
listaCompraViewModel.getProductos().observe(this, adaptador::setDatos);
if (datos.isEmpty()) {
Toast.makeText(this, "La lista de la compra esta vacia le enviamos a la opcion de añadir",
Toast.LENGTH_SHORT).show();
Intent i = new Intent(this, NuevoProductoActivity.class);
startActivityForResult(i, REQUEST_CODE);
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
int posicion = -1;
try {
posicion = adaptador.getPosicion();
} catch (Exception e) {
return super.onContextItemSelected(item);
}
switch (item.getItemId()) {
case R.id.mi1:
Snackbar.make(this.rv1, "Se ha elegido borrar el elemento " + posicion, Snackbar.LENGTH_LONG)
.show();
Producto p = adaptador.getDatos().get(posicion);
new borrarProducto(BaseDatosApp.getInstance(contexto)).execute(p);
adaptador.notifyDataSetChanged();
if (datos.isEmpty()) {
AlertDialog.Builder dialogo1 = new AlertDialog.Builder(this);
dialogo1.setTitle("Infornacion");
dialogo1.setMessage("La lista de la compra esta vacia añada un producto o salga de la aplicacion");
dialogo1.setCancelable(false);
dialogo1.setPositiveButton("Añadir", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogo1, int id) {
añadir();
}
});
dialogo1.setNegativeButton("Salir", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogo1, int id) {
finish();
}
});
dialogo1.show();
}
break;
case R.id.mi2:
añadir();
}
return super.onContextItemSelected(item);
}
public void añadir() {
Intent i = new Intent(this, NuevoProductoActivity.class);
startActivityForResult(i, REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
Producto nProducto = (Producto) data.getExtras().getSerializable("Producto");
new insertarProducto(BaseDatosApp.getInstance(contexto)).execute(nProducto);
View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
adaptador.notifyDataSetChanged();
Snackbar snackbar = Snackbar.make(rootView, "Se ha insertado un nuevo registro.", Snackbar.LENGTH_LONG);
Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) snackbar.getView();
snackbar.show();
}
}
class borrarProducto extends AsyncTask { private final BaseDatosApp database;
public borrarProducto(BaseDatosApp database) {
this.database = database;
}
#Override
protected Void doInBackground(final Producto... params) {
database.productoDAO().delete(params[0]);
return null;
}
}
class insertarProducto extends AsyncTask { private final BaseDatosApp database;
public insertarProducto(BaseDatosApp database) {
this.database = database;
}
#Override
protected Void doInBackground(final Producto... params) {
database.productoDAO().insertAll(params);
return null;
}
DB
#Database(entities = {Producto.class}, version = 1, exportSchema = false)
public abstract class BaseDatosApp extends RoomDatabase { private static BaseDatosApp INSTANCIA;
public static BaseDatosApp getInstance(Context context) {
if (INSTANCIA == null) {
INSTANCIA = Room.databaseBuilder(
context.getApplicationContext(),
BaseDatosApp.class,
"dbCompra")
.build();
}
return INSTANCIA;
}
public static void destroyInstance() {
INSTANCIA = null;
}
other class
ListaCompraViewModel extends AndroidViewModel {
private final LiveData<List<Producto>> productos;
public ListaCompraViewModel(#NonNull Application application) {
super(application);
productos = BaseDatosApp
.getInstance(application)
.productoDAO().getAll();
}
public LiveData<List<Producto>> getProductos() {
return productos;
}
public abstract ProductoDAO productoDAO();
I work on project that manages contacts database with CRUD options
But I don't know how to handle multithreading.
I use Java 8 and spring-boot 2.0.4 RELEASE
UPDATE -> Code instead of images
This is Controller :
#RestController
#RequestMapping("/api")
#CrossOrigin(origins = "http://localhost:4200", allowedHeaders="*")
public class ContactController {
#Autowired
private ContactService contactService;
/*--- Toute la liste ---*/
#GetMapping("/contact")
public List<ContactDTO> getDestinataires() {
return contactService.getContacts();
}
/* ------------------------- CRUD ----------------------- */
// Creation contact
#PostMapping("/contact/create")
public boolean create(#Valid #RequestBody ContactDTO contact) {
return contactService.create(contact);
}
// infos d'un contact
#GetMapping("/contact/{id}")
public ContactDTO read(#PathVariable Integer id) {
return contactService.getContact(id);
}
// Maj contact
#PutMapping("/contact/update")
public boolean update(#RequestBody ContactDTO contact) {
return contactService.update(contact);
}
// Maj contact
#DeleteMapping("/contact/delete/{id}")
public boolean delete(#PathVariable Integer id) {
return contactService.delete(id);
}
}
The service (with #Service annotation) retrieves ContactDTO Object sent by the front and set Contact object. It works with CoreServices (without Spring annotations) java class.
This is it:
#Service
public class ContactService extends CoreServices{
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ContactService.class);
public boolean update(ContactDTO contactDTOFront) {
logger.info("ContactService - start update method");
try {
// contrôle si contact existe
setContact(getContactRepo().findByIdaicontact(contactDTOFront.getIdaicontact()));
if (getContact() == null) {
return false;
}
// alimentation du bean hibernate par le bean dto.
contactDTOFront.alimBean(this);
// maj de la bdd
if (getContactRepo().save(getContact()) == null) {
return false;
}
} catch (Exception ure) {
logger.error("ContactService - Error update method: " + ExceptionUtils.getStackTrace(ure));
return false;
}
return true;
}
All Beans (DTO and entity) are managed in CoreServices Class :
public class CoreServices {
#Autowired
private ContactRepository contactRepo;
// Bean Contact
Contact contact = new Contact();
ContactDTO contactDTO = new ContactDTO();
List<ContactDTO> contactDTOList = new ArrayList<ContactDTO>();
List<Contact> contactList = new ArrayList<Contact>();
public ContactRepository getContactRepo() {
return contactRepo;
}
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
public ContactDTO getContactDTO() {
return contactDTO;
}
public void setContactDTO(ContactDTO contactDTO) {
this.contactDTO = contactDTO;
}
public List<ContactDTO> getContactDTOList() {
return contactDTOList;
}
public void setContactDTOList(List<ContactDTO> contactDTOList) {
this.contactDTOList = contactDTOList;
}
public List<Contact> getContactList() {
return contactList;
}
public void setContactList(List<Contact> contactList) {
this.contactList = contactList;
}
To set Contact bean , I use "alimBean" method defined in DTO OBject. This method is called in my service.
public void alimBean(CoreServices service) throws Exception {
logger.info("ContactDTO - start alimBean method");
service.getContact().setIdaicontact(this.getIdaicontact());
service.getContact().setIdentifiant(this.getIdentifiant());
service.getContact().setIdaisite(this.getIdaisite());
service.getContact().setIdaitype(this.getIdaitype());
service.getContact().setNom(this.getNom());
service.getContact().setPrenom(this.getPrenom());
service.getContact().setEmail(this.getEmail());
service.getContact().setComment(this.getComment());
service.getContact().setStatus(this.getStatus());
service.getContact().setLocked(this.getLocked());
service.getContact().setUserlock(this.getUserlock());
service.getContact().setCreuser(this.getCreuser());
service.getContact().setUpduser(this.getUpduser());
// Gestion des dates STRING -> DATE
logger.info("ContactDTO - end alimBean method");
}
Now, assuming two update requests are handled in same time. How does it work ?
I read some Tuto about "synchronization" but they are a little confused for me. I don't know if it's the best way and I don't want to break all the code except if it's the only solution to handle this multithreading case
What can I add to this code to be sure the second request will not set Contact object before the first request ended.
You should synchronize only update and delete actions with for example id if it's unique. You can use my library but it's in alfa version but it is tested and works good.
You must add the dependency:
<dependency>
<groupId>com.jsunsoft.util</groupId>
<artifactId>concurrent</artifactId>
<version>0.0.1-alpha2</version>
</dependency>
and write code like this
import com.jsunsoft.util.concurrent.locks.Lock;
public class ContactService extends CoreServices {
private final Lock contactLock = new StripedLock(minimumNumberOfStripes, lockTimeSec);
public boolean update(ContactDTO contactDTOFront) {
logger.info("ContactService - start update method");
try {
updateSynched(contactDTOFront);
} catch (Exception ure) {
logger.error("Co: " + ExceptionUtils.getStackTrace(ure));
return false;
}
return true;
}
//you can add the method updateSynched
private void updateSynched(ContactDTO contactDTOFront) throws Exception {
contactLock.lock(contactDTOFront.getId(), () -> {
setContact(getContactRepo().findByIdaicontact(contactDTOFront.getIdaicontact()));
if (getContact() == null) {
throw new Exception("msg");
}
// alimentation du bean hibernate par le bean dto.
contactDTOFront.alimBean(this);
// maj de la bdd
if (getContactRepo().save(getContact()) == null) {
throw new Exception("msg");
}
});
}
}
Note: In that library I used the guava striped lock if you want you can use directly the guava API.
I'm having trouble getting my custom tokens to work with my ContentPart. My problem is the same as what is described here:
Is it possible to create an orchard autoroute using contents of a custom type property?
I have created my tokens:
namespace MyNS.Types.Providers
{
public class BioPartTokens : ITokenProvider
{
public BioPartTokens() {
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
public void Describe(dynamic context) {
context.For("Bio", T("Bio"), T("Tokens for the Bio content type"))
.Token("FirstName", T("FirstName"), T("First name of person."))
.Token("LastName", T("LastName"), T("Last name of person."));
}
public void Evaluate(dynamic context) {
context.For<BioPart>("Bio")
.Token("FirstName", (Func<BioPart, object>) (f => f.ContentItem.Parts.OfType<BioPart>().First().FirstName.ToLower()))
.Chain("FirstName", "FirstName", (Func<BioPart, object>)(f => f.ContentItem.Parts.OfType<BioPart>().First().FirstName.ToLower()))
.Token("LastName", (Func<BioPart, object>)(f => f.ContentItem.Parts.OfType<BioPart>().First().LastName.ToLower()))
.Chain("LastName", "LastName", (Func<BioPart, object>)(f => f.ContentItem.Parts.OfType<BioPart>().First().LastName.ToLower()))
;
}
}
}
My model:
namespace MyNS.Types.Models
{
public class BioPart: ContentPart<BioPartRecord>
{
public string FirstName {
get { return Record.FirstName; }
set { Record.FirstName = value; }
}
public string LastName
{
get { return Record.LastName; }
set { Record.LastName = value; }
}
public RoleInSchool RoleInSchool
{
get { return Record.RoleInSchool; }
set { Record.RoleInSchool = value; }
}
public bool IsBlogger {
get { return Record.IsBlogger; }
set { Record.IsBlogger = value; }
}
}
}
Though I've tried URL patterns with all of the following tokens, I've not been able to get a value back from the form that I've submitted:
{Content.Bio.FirstName}
{Content.BioPart.FirstName}
{Bio.FirstName}
{BioPart.FirstName}
No errors are being logged.
In my controller, I have two method like that :
public ActionResult NouvelleDemande()
{
int NumDossier = StructureData.DonneNumDossier((string)Session["Utilisateur"], (string)Session["MotDePasse"]);
List<Contact> ListeContacts = StructureData.DonneListeContact(NumDossier);
if (ListeContacts != null)
{ ViewBag.ListeContacts = ListeContacts; }
else
{ ViewBag.ListeContacts = null; }
return View();
}
public ActionResult NouvelleDemande(DemandeAssistance nouvelleDemande)
{
bool DemandeEnregistree = nouvelleDemande.EnregistrerDemande();
if (DemandeEnregistree)
{
return Index();
}
else
{
ViewBag.Error = "La demande n'a pas été enregistrée !";
return View();
}
}
So when I want just to display the view() associated to the method, I call the first one. In the view(), I have a form which when submitted, send an object DemandeAssistance to the second method. In the routes config, i did that :
routes.MapRoute(
name: "NouvelleDemande",
url: "{controller}/{action}",
defaults: new { controller = "Accueil", action = "NouvelleDemande" }
);
routes.MapRoute(
name: "AjouterNouvelleDemande",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Accueil", action = "NouvelleDemande", id = UrlParameter.Optional }
);
But it shows me an error when I want just to display the view saying that there is a misunderstanding between these two routes. What did I do wrong ?
I manage to find out what was missing even if I don't really understand why.
I've just put that :
// POST : /Accueil/NouvelleDemande
[HttpPost]
Upon the method which contains a parameter, as follows:
// POST : /Accueil/NouvelleDemande
[HttpPost]
public ActionResult NouvelleDemande(DemandeAssistance nouvelleDemande)
{
bool DemandeEnregistree = nouvelleDemande.EnregistrerDemande();
if (DemandeEnregistree)
{
return Index();
}
else
{
ViewBag.Error = "La demande n'a pas été enregistrée !";
return View();
}
}
Maybe those interested will have time to explain why it works actually.
I would like to use nested list in my web.config. I see pieces of code that work, but not mine, i have an error when i try to read the configuration section :
System.Configuration.ConfigurationErrorsException : Élément non
reconnu IsochroneServicesTestImbrique'.
My config :
<IsochroneServicesTest>
<add name="TC">
<IsochroneServicesTestImbrique>
<add name="DEFAULT" path="success"/>
</IsochroneServicesTestImbrique>
</add>
</IsochroneServicesTest>
and the code :
[ConfigurationProperty("IsochroneServicesTest")]
[ConfigurationCollection(typeof(CollectionIsochrone), AddItemName = "add")]
public CollectionIsochroneType IsochroneServicesTest
{
get { return (CollectionIsochroneType)this["IsochroneServicesTest"]; }
set { this["IsochroneServicesTest"] = value; }
}
public class CollectionIsochroneType : ConfigurationElementCollection
{
public void Add(ProviderElement element)
{
base.BaseAdd(element);
}
protected override ConfigurationElement CreateNewElement()
{
return new IsochroneElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((IsochroneTypeElement)element).Name;
}
public IsochroneTypeElement this[int index]
{
get { return (IsochroneTypeElement)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public new IsochroneTypeElement this[string Name]
{
get { return (IsochroneTypeElement)BaseGet(Name); }
}
public int IndexOf(IsochroneTypeElement element)
{
return BaseIndexOf(element);
}
protected override void BaseAdd(ConfigurationElement element)
{
BaseAdd(element, false);
}
}
public class IsochroneTypeElement : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get { return (string)this["name"]; }
set { this["name"] = value; }
}
[ConfigurationProperty("IsochroneServicesTestImbrique", IsRequired = true)]
[ConfigurationCollection(typeof(CollectionIsochrone), AddItemName = "add")]
public CollectionIsochrone IsochroneServicesImbrique
{
get { return (CollectionIsochrone)this["IsochroneServicesTestImbrique"]; }
set { this["IsochroneServicesTestImbrique"] = value; }
}
}
public class CollectionIsochrone : ConfigurationElementCollection
{
public void Add(ProviderElement element)
{
base.BaseAdd(element);
}
protected override ConfigurationElement CreateNewElement()
{
return new IsochroneElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((IsochroneElement)element).Name;
}
public IsochroneElement this[int index]
{
get { return (IsochroneElement)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public new IsochroneElement this[string Name]
{
get { return (IsochroneElement)BaseGet(Name); }
}
public int IndexOf(IsochroneElement element)
{
return BaseIndexOf(element);
}
protected override void BaseAdd(ConfigurationElement element)
{
BaseAdd(element, false);
}
}
public class IsochroneElement : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get { return (string)this["name"]; }
set { this["name"] = value; }
}
[ConfigurationProperty("path", IsRequired = true)]
public string Path
{
get { return (string)this["path"]; }
set { this["path"] = value; }
}
}
Thanks for your help
You are getting that error because you are missing the declaration for IsochroneServicesTestImbrique in your <configSections> section. Also, at least one class must inherit from ConfigurationSection. See the example here.