Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Portal
  • |
  • Mitglieder
Beiträge von T-Man
Thema: [erledigt] WCF - Aufruf e. ext. Prozesses in e. Service Methode sorgt für fault beim nächsten Aufruf
Am im Forum: Netzwerktechnologien

Moin zusammen,

ich habe einen WCF service mit wsHttpBinding und Message Security.

Bislang funktionierte alles wunderbar.

Nun rufe ich in einer Methode des Service eine exe auf:

                using (var proc = new Process())
                {
                    proc.EnableRaisingEvents = false;
                    proc.StartInfo.FileName = Path.Combine(exePath, "ex.exe");
                    proc.StartInfo.Arguments = string.Format("\"{0}\" \"{1}\"", sourceFile, destFile);
                    proc.StartInfo.RedirectStandardError = true;
                    proc.StartInfo.UseShellExecute = false;
                    proc.Start();
                    if (!proc.WaitForExit(10000 + (int)Math.Min(filesize / 50L, 600000L)))
                    {
                        proc.Kill();
                        Thread.Sleep(1000);
                        throw new Exception("Timeout");
                    }
                    using (var errorReader = proc.StandardError)
                    {
                        var error = errorReader.ReadToEnd();
                        if (!string.IsNullOrEmpty(error)) throw new Exception(error);
                    }
                }
Das funktioniert auch wunderbar. Ich werte das Ergebnis aus liefere es zurück...
Bei dem nächsten Aufruf einer (anderen) Methode des Services bekomme ich allerdings eine FaultException mit der folgenden Fehlermeldung:
Fehler
Die Nachricht konnte nicht verarbeitet werden. Wahrscheinliche Ursache: Die Aktion "..." ist falsch ist, die Nachricht enthält ein ungültiges oder abgelaufenes Sicherheitskontexttoken oder zwischen Bindungen besteht ein Konflikt. Das Sicherheitskontexttoken wäre ungültig, wenn der Dienst den Kanal aufgrund von Inaktivität abgebrochen hätte. Erhöhen Sie das Empfangszeitlimit für die Bindung des Dienstendpunkts, um zu verhindern, dass der Dienst Leerlaufsitzungen vorzeitig abbricht.

Unter InnerException.Code.SubCode.Name steht BadContextToken.

Wenn ich den obigen Code auskommentiere läuft alles wie es soll.

Hat jemand eine Idee, wieso der (erfolgreiche) Aufruf eines externen Prozesses in einer Service Methode dafür sorgt, dass der Kanal "gefaulted" wird?

Gruß
T-Man

Thema: [erledigt] WCF Service mit wsHttpBinding auf Windows Server 2008
Am im Forum: Netzwerktechnologien

Weitere Infos:

Auf dem Win7 Rechner ist die Identität des Anwendungspools "ApplicationPoolIdentity".

Auf dem 2008 Server ist es "NetworkService". Wenn ich es dort mit "ApplicationPoolIdentity" versuche kann ich den Service gar nicht erst starten.

Gruß T-Man

Thema: [erledigt] WCF Service mit wsHttpBinding auf Windows Server 2008
Am im Forum: Netzwerktechnologien

Moin zusammen,

ich habe einen WCF Service mit zwei Schnittstellen.
Eine ungesicherte Basisschnittstelle mit einfachem basicHttpBinding
Und eine gesicherte Schnittstelle mit wsHttpBinding

Hier die web.config des Servers:


<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicBinding" />
      </basicHttpBinding>
      <wsHttpBinding>
        <binding name="wsHttpBinding">
          <security>
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="amagnoBehavior" name="Amagno.AmagnoService.AmagnoService">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding"
          name="wsHttp" contract="Amagno.ExternalServiceContracts.IAmagnoService" />
        <endpoint address="/Basic" binding="basicHttpBinding" bindingConfiguration="BasicBinding"
          name="Basic" contract="Amagno.ExternalServiceContracts.IAmagnoBasicService" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="amagnoBehavior">
          <serviceCredentials>
            <serviceCertificate storeName="My" storeLocation="LocalMachine" findValue="CN=test.amagno.org" />
            <userNameAuthentication userNamePasswordValidationMode="Custom"
              customUserNamePasswordValidatorType="Amagno.Base.AmagnoUserNamePasswordValidator, AmagnoBase" />
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  <appSettings>
...
  </appSettings>

</configuration>

Und nun die app.config des Clients:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <endpointBehaviors>
                <behavior name="wsHttpBehavior">
                    <clientCredentials>
                        <serviceCertificate>
                            <authentication certificateValidationMode="None" revocationMode="NoCheck" />
                        </serviceCertificate>
                    </clientCredentials>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <bindings>
            <basicHttpBinding>
                <binding name="Basic" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
                    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="268435456" maxBufferPoolSize="524288" maxReceivedMessageSize="268435456"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="268435456"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
            <wsHttpBinding>
                <binding name="wsHttp" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
                    transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="268435456"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" negotiateServiceCredential="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost/AmagnoService/AmagnoService.svc"
                behaviorConfiguration="wsHttpBehavior" binding="wsHttpBinding"
                bindingConfiguration="wsHttp" contract="AmagnoServiceReference.IAmagnoService"
                name="wsHttp">
                <identity>
                    <dns value="test.amagno.org" />
                    <certificate encodedValue="Aw....." />
                </identity>
            </endpoint>
            <endpoint address="http://localhost/AmagnoService/AmagnoService.svc/Basic"
                binding="basicHttpBinding" bindingConfiguration="Basic" contract="AmagnoServiceReference.IAmagnoBasicService"
                name="Basic">
              <identity>
                <dns value="test.amagno.org" />
              </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Da ich bloß ein selbst erstelltes Test Zertifikat verwende, muss vorläufig
<authentication certificateValidationMode="None" revocationMode="NoCheck" />
in der app.config stehen. Das wird sich natürlich später ändern.

Wenn ich den Server auf meinem Windows-7 Rechner laufen lasse, klappt alles wunderbar. Beide Services sind erreichbar. Egal ob ich den Client auf dem selben Rechner oder auf einem anderen laufen lasse.

Wenn ich den Server allerdings auf unserem 1&1 Server (Windows 2008 R2 Server) laufen lasse, klappt nur die Verbindung zum basis Service. Auch wenn der Client ebenfalls auf diesem Server läuft.
Scheinbar wird die Anfrage bereits vom IIS geblockt, denn die Authentifizierungs-Methode des AmagnoUserNamePasswordValidator wird gar nicht erst aufgerufen.

Folgende SecurityNegotiationException bekomme ich, wenn ich eine Methode des gesicherten Service aufrufe:
Fehler
Der Aufrufer wurde vom Dienst nicht authentifiziert.
InnerException (FaultException): Die Anforderung für ein Sicherheitstoken konnte nicht erfüllt werden, weil ein Fehler bei der Authentifizierung auftrat.
InnerException StackTrace: bei System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target)
bei System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)

StackTrace:

Server stack trace:
bei System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
bei System.ServiceModel.Security.SspiNegotiationTokenProvider.OnOpen(TimeSpan timeout)
bei System.ServiceModel.Security.TlsnegoTokenProvider.OnOpen(TimeSpan timeout)
bei System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
bei System.ServiceModel.Security.CommunicationObjectSecurityTokenProvider.Open(TimeSpan timeout)
bei System.ServiceModel.Security.SymmetricSecurityProtocol.OnOpen(TimeSpan timeout)
bei System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
bei System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout)
bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
bei System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
bei System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
bei System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
bei System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
bei System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
bei System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
bei System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
bei System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
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 Amagno.WindowsClient.AmagnoServiceReference.IAmagnoService.GetAuthenticatedUser(GetAuthenticatedUserArg arg)
bei Amagno.WindowsClient.AmagnoServiceReference.AmagnoServiceClient.GetAuthenticatedUser(GetAuthenticatedUserArg arg) in d:\Amagno\Client\AmagnoWindowsClient\Service References\AmagnoServiceReference\Reference.cs:Zeile 6849.

Ich habe auf dem Server VisualStudio installiert um debuggen zu können und die Verbindung zum basic Service klappt auch wunderbar...

Leider habe ich keine Ahnung, wo ich ansetzen soll. Ich bin kein Admin und habe auch keinen zu Verfügung.
Wo loggt der IIS die Verbindungsversuche und die Fehler? Wo kann ich da reinschauen? Was muss ich im IIS einstellen, damit die Anfrage durchkommt?

Kann mir jemand weiterhelfen?

Gruß
T-Man

Thema: Klasse bekommt eine Referenz via ref von einem primitiven Typ, wie speichern?
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Das mit dem event klappt aber nicht, wenn er im destruktor den aktuellen Wert lesen möchte.

Thema: Klasse bekommt eine Referenz via ref von einem primitiven Typ, wie speichern?
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Du könntest statt der Referenz auf die bool Variable zwei Lambda Expressions übergeben, eine die die Variable setzt, eine zweite, die den Wert liefert, sofern Du beides brauchst...

Gruß
T-Man

Thema: WCF Service mit Identity Type RSA
Am im Forum: Netzwerktechnologien

Moin zusammen,

ich möchte einen WCF Service erstellen mit zwei Endpunkten.
Bindings: netTcp und wsHttp
Security Mode: jeweils Message
Client Credential Type: jeweils UserName

Die Beispiele aus dem Wrox-Buch "Professionasl WCF 4" setzen für die Identität der Endpunkte X509-Zertifikate ein. Darauf möchte ich gerne verzichten. Wenn ich das richtig verstanden habe, kann man aber auf die Identität nicht verzichten, da diese für die Server Zertifizierung nötig ist. Nun gibt es die Möglichkeit für die Identität einen RSA Schlüssel, statt eines X509 Zertifikats zu verwenden. Nun mein Problem: Ich finde nirgends 'ne Anleitung, wie das geht. Kann mir da jemand weiterhelfen?

Danke
T-Man

Thema: 403.14 beim Start einer WCF Dienstanwendung
Am im Forum: Netzwerktechnologien

Moin zusammen,

hier die Systemdetails:

OS: Windows 7 Home Premium (x64)
Visual Studio 2010 Professional
IIS7.5 (Features siehe angehängtes Bild)

Der IIS wurde erst nach dem Visual Studio installiert.

Ich habe ein Framework 4.0 Projekt "wcf dienstanwendung" angelegt.
Kompiliert.
Dann mit dem wcf konfigurations editor die web.config bearbeitet.
- Neuen Dienst erstellt
- die dll ausgewählt ...
- HTTP
- Basic
- keine Adresse
- Endpunkt in "Basic" benannt
- Ein Binding erstellt und auch Basic benannt
Gespeichert
In den Projekteigenschaften unter WEB "Lokalen IIS-WebServer verwenden" angewählt.
Mit F5 gestartet

Nun bekomme ich statt einer Seite auf der u.a. "Metadata publishing for this service is currently disabled" stehen sollte eine Fehlerseite mit dem Fehler 403.14.

Ich habe aspnet_regiis -i für Framework64\v4.... und Framework\v4....
ausgeführt. Außerdem "ServiceModelReg -ia" für beide 4er Frameworks und "ServiceModelReg -i" in ....\v3.0\Windows Communication Foundation"

Das hat alles nichts geholfen.

Weiß jemand Rat?

Vielen Dank im voraus
T-Man

Thema: Linq to sql: complexe Suche
Am im Forum: Datentechnologien

Ich weiß jetzt wie es theoretisch geht.
Da ich nur herausfinden sollte, ob es geht kann ich hier nicht die konkrete Lösung präsentieren.

Gruß
T-Man

Thema: Linq to sql: complexe Suche
Am im Forum: Datentechnologien

Zitat von witte
OT:
@T-Man: wo hast Du das NotNullAttribute her? Habe ich was verpaßt oder ist das eine Eigenkreation?
Von ReSharper. Das hätte ich hier weglassen können...

Thema: Linq to sql: complexe Suche
Am im Forum: Datentechnologien

Danke für den Tipp, er führt mich schon etwas weiter. Leider noch nicht zum Ziel.

ExpressionTrees verstehe ich jetzt ungefähr. Für einfachere Abfragen könnte ich auch einen aufstellen.

Hier müsste ich ja sowas wie

Where(sv => sv._BracketValues[0].DestinationItemId == _BracketValues[0].DestinationItemId && 
sv._BracketValues[1].DestinationItemId == _BracketValues[1].DestinationItemId && ...)

dynamisch erstellen.

Aber wie referenziere ich die einzelnen Elemente von _BracketValues um sie zu vergleichen? Der Indexer und ElementAt sind nicht in SQL übersetzbar, sprich, mein Beispiel funktioniert nicht.

Kann mir da jemand einen weiteren Tipp geben?

Danke!
T-Man

Thema: Linq to sql: complexe Suche
Am im Forum: Datentechnologien

verwendetes Datenbanksystem: MSSQL

Moin!

Hier zunächst die wichtigsten Klassen aufs wesentliche reduziert:


    public abstract class DataValue
    {
        [Column(IsPrimaryKey = true)]
        public Guid Id { get; internal set; }

        [Column(IsDiscriminator = true)]
        private string Class;

        [Column]
        public Guid? MetadataId { get; internal set; }
        private EntityRef<Bracket> _Metadata;
        [DataMember]
        [Association(ThisKey = "MetadataId", OtherKey = "Id")]
        internal Bracket Metadata { get { return _Metadata.Entity; } set { _Metadata.Entity = value; } }

        internal virtual IQueryable FindEqualInList([NotNull]IQueryable list)
        {
            return list.Cast<DataValue>().Where(dv => dv.MetadataId == MetadataId || dv.MetadataId == null && MetadataId == null);
        }
    }

    public class BoolValue : SimpleValue
    {
        [Column(CanBeNull = true)]
        private bool? boolValue;

        internal override IQueryable FindEqualInList(IQueryable list)
        {
            return base.FindEqualInList(list.OfType<BoolValue>().Where(bv => bv.boolValue == null && boolValue == null || bv.boolValue == boolValue));
        }
    }

    public class Bracket : DataValue
    {
        [Association(OtherKey = "SourceItemId")]
        internal EntitySet<ValueAssign> _BracketValues = new EntitySet<ValueAssign>();

        internal override IQueryable FindEqualInList(IQueryable list)
        {
            return base.FindEqualInList(list.OfType<Bracket>()).Cast<Bracket>().Where(sv => sv._BracketValues.Count() == _BracketValues.Count).ToList().FindAll(sv =>
                sv._BracketValues.All(va1 => _BracketValues.FirstOrDefault(va2 =>
                    va2.Ordinal == va1.Ordinal && va2.DestinationItemId == va1.DestinationItemId) != null)).AsQueryable();
        }
    }

    public class ValueAssign
    {
        [Column(IsPrimaryKey = true)]
        internal Guid SourceItemId { get; set; }

        [Column]
        public Guid DestinationItemId { get; internal set; }

        [Column(IsPrimaryKey = true)]
        public int Ordinal { get; internal set; }

        private EntityRef<DataValue> _DestinationItem;
        [Association(ThisKey = "DestinationItemId", OtherKey = "Id")]
        public DataValue DestinationItem
        {
            get { return _DestinationItem.Entity; }
            set { _DestinationItem.Entity = value; }
        }
    }
Wenn ein neuer DataValue gespeichert werden soll, rufe ich für diesen zunächst FindEqualInList() mit der Tabelle als Parameter auf um zu sehen, ob es schon einen identischen Wert gibt... Das funktioniert auch wunderbar. Leider verlasse ich in dem FindEqualInList in der Klasse Bracket den DataBase-Context in dem Moment in dem ich das ToList() aufrufe. Hier werden alle in Frage kommenden Brackets aus der DB geladen und dann wird die Liste weiter eingeschränkt. Ich mache das ToList().FindAll(), da ein Where nicht funktioniert, da die weitere Lambda-Expression nicht in SQL übersetzt werden kann.

Nun meine Frage: (Wie) kann ich die Lambda-Expression so umwandeln, dass sie in SQL übersetzbar ist? Das würde das Laden in den Speicher verhindern und sicher wesentlich schneller laufen.

Vielen Dank schon mal in voraus.
T-Man

Thema: Feststellen, ob ein Treenode oder dessen Pluszeichen angeklickt wurde
Am im Forum: GUI: Windows-Forms

Über die EventArgs kannst Du die Klick-Position bekommen. Ich vermute, damit müsstest Du es berechnen können...

Gruß
T-Man

Thema: Table Attribut auf Klasse die IEnumerable ist
Am im Forum: Datentechnologien

Moin!

ich habe folgende Klassen:


    [DataContract]
    [Table(Name = "DataValues")]
    [InheritanceMapping(Code = "BoolValue", Type = typeof(BoolValue))]
    [InheritanceMapping(Code = "Bracket", Type = typeof(Bracket), IsDefault = true)]
    public abstract class DataValue
    {
        [Column(IsPrimaryKey = true)]
        public Guid Id { get; set; }

        [Column(IsDiscriminator = true)]
        private string Class;

        public Enum Association { get { return _Association.ToEnum(); } set { _Association = value.ToFullName(); } }
        [Column]
        [DataMember]
        private string _Association { get; set; }

        [Column]
        public Guid? MetadataId { get; set; }
        private EntityRef<Bracket> _Metadata;
        [DataMember]
        [Association(ThisKey = "MetadataId", OtherKey = "Id")]
        public Bracket Metadata { get { return _Metadata.Entity; } set { _Metadata.Entity = value; } }
    }


    [DataContract]
    public class BoolValue : DataValue
    {
        [DataMember]
        [Column(CanBeNull = true)]
        public bool Bool { get; set; }
    }


    [DataContract]
    public class Bracket : DataValue, IEnumerable<ValueAssign>
    {
        [Association(OtherKey = "SourceItemId")]
        internal EntitySet<ValueAssign> _BracketValues = new EntitySet<ValueAssign>();

        [DataMember]
        private List<ValueAssign> BracketValues { get; set; }

        public IEnumerator<ValueAssign> GetEnumerator()
        {
            return BracketValues.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return BracketValues.GetEnumerator();
        }
    }


    [DataContract]
    [Table(Name = "ValueAssigns")]
    public class ValueAssign
    {
        [Column(IsPrimaryKey = true)]
        internal Guid SourceItemId { get; set; }

        [Column(IsPrimaryKey = true)]
        public Guid DestinationItemId { get; internal set; }

        [DataMember]
        [Column(IsPrimaryKey = true)]
        public int Ordinal { get; internal set; }

        private EntityRef<DataValue> _DestinationItem;
        [DataMember]
        [Association(ThisKey = "DestinationItemId", OtherKey = "Id")]
        public DataValue DestinationItem { get { return _DestinationItem.Entity; } set { _DestinationItem.Entity = value; } }

        public Enum Association { get { return _Association.ToEnum(); } internal set { _Association = value.ToFullName(); } }
        [DataMember]
        [Column]
        private string _Association { get; set; }
    }

Nun zum Problem: Vorher war die Liste BracketValues in der Klasse Bracket public und es wurde überall direkt darauf zugegriffen. Bracket war nicht IEnumerable.

Jetzt wollte ich gerne im Add und anderen Methoden noch was prüfen und den Zugriff auf BracketValues nur noch indirekt zulassen. Dazu habe ich Methoden wie Add und Remove in Bracket angelegt und Bracket auch die Schnittstelle IEnumerable gegeben, da ich häufig in foreach-Schleifen über die BracketValues ging...

Nun bekomme ich aber ein Problem mit der Erzeugung der Tabellen in der Datenbank. Wenn ich mein Programm startete, wurden alle Tabellen in der DB erzeugt, wenn sie noch nicht da waren. Jetzt bekomme ich dort folgende Fehlermeldung: Das Schlüsselelement "Id" für Schlüssel "Id" im Typ "ValueAssign" konnte nicht gefunden werden. Entweder ist der Schlüssel falsch, oder der Name des Felds bzw. der Eigenschaft in "ValueAssign" wurde geändert.

Mir ist klar, das es an dem IEnumerable liegt, aber ich weiß nicht, was das Problem genau ist und wie ich es lösen kann. Ich habe mal das IEnumerable rausgenommen und dafür eine ToArray() Methode eingeführt, über die ich die foreach Schleifen nun laufen lasse. Damit funktioniert es wieder. Dennoch würde ich lieber das IEnumerable drin lassen. In meinem Linq-Buch steht dazu natürlich nichts. Auch die Beschreibung des Table-Attributes liefert nichts. Kann mir einer von Euch das Problem erklären, oder auf gute Lektüre verweisen, in der es geklärt wird?

Ich habe die Klassen hier natürlich auf das nötigste reduziert...

Vielen Dank in voraus!
T-Man

Hat echt keiner 'ne Ahnung? :-(

Thema: [erledigt] Probleme mit Access-Update bei bestimmtem Tabellennamen
Am im Forum: Datentechnologien

Kann es sein, das evtl. auch einige Spaltennamen reservierte Wörter sind? Auch die Spaltennamen solltest Du mit [] klammern...

Gruß
T-Man

Thema: C# Methode über vbscript auf einem 64 Bit System aufrufen
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Moin zusammen!

Ich bastele gerade mit Advanced Installer einen neuen Installer für mein Produkt. Vorher hatte ich einen selbst gebauten, der nicht Windows Installer benutzte. Nun habe ich eine Aufwendigere Custom Action in C# geschrieben, da ich weder c++ noch vbscript beherrsche. Die dll ist ComVisible und wird mit regasm registriert. Mit einem einfachen VBScript rufe ich nun die c#-Methode auf.

Script: Session.Property("OLDAPPLICATIONPATH") = CreateObject("InstallationTool.InstallationTool").GetOldApplicationPath()

Auf 32 Bit Systemen funktioniert es wunderbar.

Nun versuche ich das selbe auf einem 64 Bit System.
Im Advanced Installer gibt es bei der Custom Action eine CheckBox "64 Bit Script"
Wenn ich dieses setzte bekomme ich einen Fehler. InstallationTool.InstallationTool kann nicht erstellt werden.
Wenn ich das Häkchen nicht setze, gibt es keinen Fehler, aber die Funktion liefert nicht das zurück was sie sollte. Sie liefert null statt des Pfades, der in der Registry steht...

Ich habe dann eben schnell zum Test in c# eine Consolen Anwendung geschrieben, die die Methode (GetOldApplicationPath()) aufruft und das Ergebnis auf der Console ausgibt. Wenn ich dieses ausführe, bekomme ich das erwünschte Ergebnis.

Wieso klappt es mit VBScript nicht? Was läuft falsch, bzw. was muss ich anders machen?

Hier eben noch der Code der GetOldApplicationPath:

        public string GetOldApplicationPath()
        {
            string path = null;
            using (RegistryKey softwareKey = Registry.LocalMachine.OpenSubKey("Software"))
                if (softwareKey != null)
                    using (RegistryKey dpKey = softwareKey.OpenSubKey("DocuPortal.NET"))
                        if (dpKey != null)
                            using (RegistryKey verKey = dpKey.OpenSubKey("Version"))
                                if (verKey != null)
                                {
                                    using (RegistryKey volKey = verKey.OpenSubKey("VOL8"))
                                        if (volKey != null)
                                            foreach (string v8Instance in volKey.GetSubKeyNames())
                                                using (RegistryKey instKey = volKey.OpenSubKey(v8Instance))
                                                    if (instKey != null)
                                                    {
                                                        var val = instKey.GetValue("ApplicationPath");
                                                        if (val != null)
                                                            path = val.ToString();
                                                        if (Directory.Exists(path))
                                                        {
                                                            instKey.Close();
                                                            break;
                                                        }
                                                        path = null;
                                                    }
                                    if (path == null)
                                        using (RegistryKey volKey = verKey.OpenSubKey("VOL7"))
                                            if (volKey != null)
                                                foreach (string v7Instance in volKey.GetSubKeyNames())
                                                    using (RegistryKey instKey = volKey.OpenSubKey(v7Instance))
                                                        if (instKey != null)
                                                        {
                                                            var val = instKey.GetValue("ApplicationPath");
                                                            if (val == null) continue;
                                                            path = val.ToString();
                                                            if (Directory.Exists(path))
                                                            {
                                                                string dllPath = Path.Combine(Path.Combine(path, "bin"), "data.dll");
                                                                if (File.Exists(dllPath))
                                                                {
                                                                    var fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(dllPath);
                                                                    if (fvi.ProductBuildPart ≥ 1235) break;
                                                                }
                                                            }
                                                            path = null;
                                                        }
                                }
            if (path != null) path = Path.GetDirectoryName(path);
            return path;
        }

Vielen Dank schon Mal im voraus für eventuelle Hilfe.
Gruß T-Man

Thema: Regex: Alle Wörter finden, die mit @ beginnen
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

(<!\w)@\w+\b

Thema: Aus String einen bestimmten Teil extrahieren
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hier ein Beispiel:


string oldName = "000_111_test_2.jpg";
string newName = Regex.Match(oldName, @"(?≤\d+_\d+_).+").Value; // liefert test_2.jpg

Gruß
T-Man

Thema: Array mit mehreren Objecten nach bestimmten Value sortieren
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Oh, sehe gerade, dass es Absteigend sein soll.
Dann

p2.Relevance - p1.Relevance

T-Man

Thema: Array mit mehreren Objecten nach bestimmten Value sortieren
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Ich bin mir nicht sicher, aber wäre nicht folgende Lösung das richtige:

System.Array.Sort(array, (p1, p2) => p1.Relevance - p2.Relevance);

Ich gehe dabei davon aus das dein Product ein Feld oder Property vom Typ int mit Namen "Relevance" hat.

Gruß
Tony

Thema: Aus String einen bestimmten Teil extrahieren
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Wie ist denn die Regel des Namens?

zahl, unterstrich, zahl, unterstrich, name ?

oder

zahl, unterstrich, zahl, unterstrich, "test", eventuelle zahl, ".jpg"

Je nachdem muss die Regex unterschiedlich aussehen.

Ich würde Dir das Regex-Tutorial empfehlen http://www.regular-expressions.info/tutorial.html

Wenn klar ist, dass es nur die beiden Unterstriche gibt, kannst Du auch mit FindLast("_") die Position des letzten Unterstrichs ermitteln und mit SubString arbeiten...

Wichtig ist, dass Du weißt, wie die Namen allgemein aussehen können...

Gruß
T-Man

Thema: Sortierreihenfolge in Access einstellen
Am im Forum: Datentechnologien

Hatte tatsächlich noch niemand dieses Problem?
Muss ich es wirklich selber lösen?

Wenn ich mal Zeit dafür habe, werde ich es wohl tun müssen. Dann stelle ich hier die Lösung ein...

Gruß
T-Man

Thema: Sortierreihenfolge in Access einstellen
Am im Forum: Datentechnologien

Eine Möglichkeit ist natürlich, eine weitere Spalte mit der Länge oder dem Hashcode des Wortes einzufügen und diese dann mit in den PK aufzunehmen. Bei einer schon bestehenden Tabelle ist diese Änderung allerdings nicht so trivial. Und außerdem gefällt es mir nicht eine weitere Spalte einzubauen, die ich eigentlich gar nicht benötige, nur weil ACCESS und MSSQL scheinbar nicht in der Lage sind dass von daß zu unterscheiden.

Thema: Sortierreihenfolge in Access einstellen
Am im Forum: Datentechnologien

Das Datenbankdesign ist in der tat nicht das beste, aber ich kann es jetzt nicht mal eben ändern.

Es geht hier um Schlagworte, die ich in einer Tabelle speichere. Jedes sollte natürlich nur einmal vorkommen, daher der PK. Nun kann ich aber nicht mehr 'dass' eintragen, wenn schon 'daß' drin steht. Eben so nicht 'Masse', wenn schon 'Maße' drin steht, was viel schlimmer ist, da es sich hier um verschiedene Worte handelt.

Es geht nicht um Sortierung bei einem Select, sondern um das Speichern ansich (INSERT). Das funktioniert schon nicht...

Desshalb muss ich der Spalte eine andere Sortierregel geben. Und das muss ich programmatisch (z.B. per SQL) machen können, da ich nicht zu jedem Kunden rennen kann um in seiner DB die Spalte zu bearbeiten.
Und ich möchte es den Kunden auch nicht zumuten das selbst machen zu müssen.

Da meine Applikation sowohl MSSQL als auch ACCESS unterstützt benötige ich für beide DBs eine Lösung. Meine App erstellt die Tabellen und Spalten selbst. Sie sollte auch solche Regeln einstellen können...

Noch jemand eine Idee?

Danke!
T-Man

Thema: Propertys dynamisch setzen?
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo Briefkasten,

das dynamischste ist Reflection, wie herbivore schon vorschlug. Wenn Du auf Reflection verzichten möchtest, kannst Du alternativ zur switch-Anweisung ein Dictionary benutzen:


        class MyClass
        {
            bool IsSyncing { get; set; }
            string LastCopiedFile { get; set; }

            protected void RemoteServiceEvents_OnHostToClient(object sender, RemotePropertyChangedEventArgs e)
            {
                SetProperty setter;
                if (PropertySetter.TryGetValue(e.PropertyName, out setter))
                    setter(this, e.PropertyValue);
                else
                    System.Diagnostics.Debug.WriteLine("unknown propertyname");
            }

            private delegate void SetProperty(MyClass instance, object value);
            private static readonly Dictionary<string, SetProperty> PropertySetter = new Dictionary<string, SetProperty>
            {
                { "IsSyncing", (inst, v) => inst.IsSyncing = (bool)v },
                { "LastCopiedFile", (inst, v) => inst.LastCopiedFile = (string)v },
            };
        }

Das Dictionary musst Du dann halt pflegen...

Gruß
T-Man

Thema: Sortierreihenfolge in Access einstellen
Am im Forum: Datentechnologien

verwendetes Datenbanksystem: Access und MSSQL

Moin allerseits,

ich habe das ss/ß Problem.
In einer Spalte, die Primary Key ist, will ich sowohl dass als auch daß eintragen können. Leider sehen Access und MSSQL die Worte als identisch an und es geht nicht. Habe schon viel gegoogelt und dabei immer wieder den Tipp gefunden, man solle die Sortierreihenfolge ändern. Z.B. auf LATIN1_GENERAL_BIN. Wie das geht habe ich nirgends gefunden.
Optimal wäre, wenn ich für eine Spalte per SQL Befehl diese Sortierreihenfolge ändern könnte.
Es wäre aber auch OK, wenn ich die Einstellung für die gesammte DB angeben müsste.

Kann mir da jemand weiterhelfen?

Ich brauche sowohl für ACCESS als auch für MSSQL eine Lösung.

Vielen Dank schon mal in vorraus!

Gruß
T-Man

Thema: Fragen zu Fileupload
Am im Forum: Web-Technologien

Brauchst Du nicht einfach 'ne ComboBox ?

Thema: Konstanten definieren
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Wozu überhaupt Properties verwenden?
Konstanten reichen doch...

Thema: IIS: Eine Anwendung für alle URLs
Am im Forum: Web-Technologien

Werds gleich morgen ausprobieren.

Danke!

Thema: IIS: Eine Anwendung für alle URLs
Am im Forum: Web-Technologien

Hallo Spezialisten & Co.

Ich habe eine asp.NET Anwendung, die in der global.asax im Event-Handler BeginRequest die URL auswertet und dann entsprechend eine Seite zurückliefert.

Wenn ich sie aus dem VS starte, klappt es. Egal, ob ich main.aspx, oder fgsfdgv.dffw als url angebe, der Event-HAndler wird angesprungen uns alles funzt.

Nun muss ich den IIS (6.0) auf unserem Server so konfigurieren, dass er genau so funktioniert. Und daran beiß ich mir bislang die Zähne aus. Rufe ich die main.aspx auf, ist alles OK, aber bei hggsgh.asad bekomme ich die Standard 404 Fehlermeldung. Meine Anwendung wird nicht gestartet.

Weiß einer, was ich machen muss?

Schonmal vielen Dank im Vorraus!!!

Gruß
T-Man

Thema: Bedingte Assembly-Verweise
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Gibt es tatsächlich keine "schöne" Lösung?

Gruß
T-Man