Hallo zusammen,
ich stecke bei meinem ersten .NET-Projekt fest. Ich soll einen kleinen Webshop mit einem Warenkorbdienst bauen (stateful web services soll man vermeiden, ich weiß, aber so lautet die Aufgabenstellung). Jetzt taucht eine FaultException auf, seit ich die folgende Funktion geschrieben habe und sie im view aufrufen will
Cart.Service1Client cart = new Cart.Service1Client();
...
public string showCart() {
return cart.showCartContents(); <== unbehandelte FaultException
}
showCartContents ist wie folgt definiert (korb ist eine ArrayList):
Interface:
[OperationContract]
string showCartContents();
Servicedef.:
public string showCartContents()
{
string contents="";
for (int i = 0; i < korb.Count; i++)
{
contents += "Position: " + i;
contents += "Artikel: " + ((Product)korb[i]).Name;
contents += "\n";
}
return contents;
}
Woher kommt diese FaultException, und wie kann ich sie beseitigen?
Vielen Dank für jede Hilfe.
Gruß j2f
PS: Hier ist das "Ausnahmedetail":> Fehlermeldung:
===================================================
System.ServiceModel.FaultException wurde nicht von Benutzercode behandelt.
Message=Der Server konnte die Anforderung aufgrund eines internen Fehler nicht verarbeiten. Wenn Sie weitere Informationen zum Fehler erhalten möchten, aktivieren Sie entweder IncludeExceptionDetailInFaults (entweder über das ServiceBehaviorAttribute oder das <serviceDebug>-Konfigurationsverhalten) für den Client, um die Ausnahmeinformationen zurück an den Server zu senden, oder aktivieren Sie die Ablaufverfolgung gemäß der Microsoft .NET Framework 3.0 SDK-Dokumentation, und prüfen Sie die Serverablaufverfolgungsprotokolle.
Source=mscorlib
StackTrace:
Server stack trace:
bei System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
bei System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
bei System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
bei System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
bei System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
bei Elve2010.Cart.IService1.showCartContents()
bei Elve2010.Cart.Service1Client.showCartContents() in C:\Dokumente und Einstellungen\Nutzer\Eigene Dateien\Visual Studio 2010\Projects\Elve2010\Elve2010\Service References\Cart\Reference.cs:Zeile 175.
bei Elve2010.Warenkorb.showCart() in C:\Dokumente und Einstellungen\Nutzer\Eigene Dateien\Visual Studio 2010\Projects\Elve2010\Elve2010\Warenkorb.aspx.cs:Zeile 27.
bei ASP.warenkorb_aspx.__RenderForm1(HtmlTextWriter __w, Control parameterContainer) in c:\Dokumente und Einstellungen\Nutzer\Eigene Dateien\Visual Studio 2010\Projects\Elve2010\Elve2010\Warenkorb.aspx:Zeile 56.
bei System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
bei System.Web.UI.HtmlControls.HtmlForm.RenderChildren(HtmlTextWriter writer)
bei System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer)
bei System.Web.UI.HtmlControls.HtmlForm.Render(HtmlTextWriter output)
bei System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
bei System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
bei System.Web.UI.HtmlControls.HtmlForm.RenderControl(HtmlTextWriter writer)
bei System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
bei System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
bei System.Web.UI.Page.Render(HtmlTextWriter writer)
bei System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
bei System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
bei System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
bei System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
InnerException:
==================================================
Die Lösung steht im Fehlertext.
Der Server konnte die Anforderung aufgrund eines internen Fehler nicht verarbeiten. Wenn Sie weitere Informationen zum Fehler erhalten möchten, aktivieren Sie entweder IncludeExceptionDetailInFaults (entweder über das ServiceBehaviorAttribute oder das <serviceDebug>-Konfigurationsverhalten) für den Client, um die Ausnahmeinformationen zurück an den Server zu senden, oder aktivieren Sie die Ablaufverfolgung gemäß der Microsoft .NET Framework 3.0 SDK-Dokumentation, und prüfen Sie die Serverablaufverfolgungsprotokolle.
Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)
Hallo jahr2000fehler, willkommen im Forum!
Wenn du den Service selbst erstellst kannst du auch einen FaultContract
definieren und dann eine FautlException<T> werfen und im Client beim catch die FaultException<T> fangen.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Hallo jahr2000fehler,
Die Exception tritt auf, weil innerhalb deiner Service-Implementierung eine Exception ausgelöst wird, die du nicht behandelst. So auf den ersten Blick habe ich zwei Vermutungen:
Deine ArrayList "Korb" wirft beim Zugriff über Count eine NullreferenceException, weil keine Instanz erstellt hast
Der Cast in "Product" bei (Product)korb_ geht schief, weil der Inhalt null oder einfach nicht in den Typ Product umgewandelt werden kann.
Ich würde so oder so vorschlagen, du verwendest eine generische Liste, Bsp. List<Product>, somit hast du Typsicherheit und das Casten fällt weg.
Hallo,
Ich würde so oder so vorschlagen, du verwendest eine generische Liste, Bsp. List<Product>
Anstatt List<T> würde ich IList<T> verweden. Eine Begründung findet warum findet sich im etwas längeren Thread IList<T> oder List<T> als Parameter- bzw. Rückgabetyp?. Kurz: Ich hab die Vorteile die CSharperUser genannt hat und zusätzlich noch die Flexibilität die List<T> gegen alles andere tauschen zu können solange es IList<T> ist.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Hallo allerseits,
erstmal vielen Dank für die Antworten.
Ich habe jetzt wieder ein bisschen daran gebastelt und durch diverse Änderungen gemerkt, dass der Aufruf der Methode aus der Anwendung heraus zu nichts führt, d. h. in die ArrayList wurde nichts eingetragen. An der Stelle von cart.addItem steht jetzt
cart.changeMessage("TEST"); //Und hier kommt KEINE Fehlermeldung - es passiert einfach nichts
in der Schnittstelle
[OperationContract]
void changeMessage(string msg);
[OperationContract]
string showMessage();
und im Service
public string nachricht="...";
...
[WebMethod]
public void changeMessage(string msg)
{
nachricht = msg;
}
[WebMethod]
public string showMessage()
{
return nachricht;
}
Wenn ich in meiner Warenkorbansicht showMessage() aufrufe, wird nur "..." angezeigt. Die Variable nachricht wird nicht geändert, obwohl weder bei der Kompilierung des Services noch der Anwedung Fehlermeldungen ausgeworfen werden. Was mache ich hier nur falsch? 🙁
Hallo jahr2000fehler,
zuerst: ArrayList gehört in die Mottenkiste und sollte wie alle untypisierten Collections aus System.Collections nicht mehr benutzt werden. Verwende stattdessen List<T> und alle anderen typisierten Collections aus System.Collections.Generic.
Setzt auch alles was dir bisher vorgeschlagen wurde mal um. Dann fallen zum Einen potentielle Fehlerquellen weg und zum Anderen wirst du über Fehler informiert.
Für dein jetztiges Problem geh einfach mit dem Debugger durch und schau ob sich die Werte so ändern wie erwartet oder nicht. Dann weist du - auch mit Hilfe vom Callstack - wo die Ursache lauert. Siehe auch [Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden.
Recht mehr kann mit den vorhandenen Informationen nicht beigetragen werden.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Hallo Gü,
erstmal danke für die schnelle Antwort. Die ArrayList habe ich schon entfernt, aber das Problem ist, dass die Methode changeMessage nicht aufgerufen wird. Ich wollte grade meinen Beitrag editieren und das "Umfeld" meiner Anwendung hinzufügen.
So siehts also aus:
[...]
Button inkorb = new Button();
inkorb.Attributes["runat"] = "server";
inkorb.Text= "In den Warenkorb legen";
inkorb.CommandArgument = r.ToString();
inkorb.Command += new CommandEventHandler(inkorb_Command);
add.Controls.Add(inkorb);
myRow.Cells.Add(add);
[...]
void inkorb_Command(object sender, CommandEventArgs
{
Cart.Service1Client cart = new Cart.Service1Client();
Label lblCart = (Label)Form1.FindControl("lblCart");
//neuen Artikel für Warenkorb-Produktklasse anlegen und Werte
Cart.Product tmpArticle = new Cart.Product();
[...]
cart.changeMessage("TEST");
}
protected void Page_Load(object sender, EventArgs
{
Cart.Service1Client cart = new Cart.Service1Client();
//Dropdown-Liste catList mit Kategorien füllen. Nach Änderung dieser Liste wird die //Seite neu geladen und die Artikel der gewählten Kategorie in der Tabelle (s. u.) //angezeigt
//Ein Service, der vom Lehrstuhl, an dem ich diese Aufgabe bearbeite, bereitgestellt wird
ProductCatalog.ArrayOfString categories = kclient.GetAllCategories();
DropDownList catList = (DropDownList)Form1.FindControl("catList");
for (int i=0; i<categories.Count; i++)
{
ListItem li = new ListItem();
li.Value = categories[i];
li.Text = categories[i];
catList.Items.Add(li);
}
//Artikel in der aktuellen Kategorie holen
artikel = kclient.FindProductsByCategory(catList.SelectedValue);
//Tabelle zeichnen, auch wenn noch kein Wert in catList ausgewählt wurde
//in dieser Tabelle stehen auch die o. g. Buttons
DrawTable(artikel);
}
Besten Dank & gute N8
j2f
Bitte beachte [Hinweis] Wie poste ich richtig? Punkt 6.