Laden...

Forenbeiträge von Cord Worthmann Ingesamt 1.215 Beiträge

29.11.2023 - 13:38 Uhr

Jepp, das war der richtige Hinweis - vielen Dank!

Eigentlich sollte diese Enumeration gar kein Teil einer Relation sein, sondern der Wert händisch gesetzt werden, weshalb der Setter auch internal ist. Aber ich hatte absolut keinen Plan, dass das Framework die Eigenschaft dennoch entsprechend interpretieren und sogar ergänzen würde.

Habe jetzt einfach ein NotMapped-Attribut drüber gesetzt, und nun arbeitet der Code auch wie gewünscht.

29.11.2023 - 12:03 Uhr

Entität "DangerousGoods":

public class DangerousGoods : DbModel
{
    public int Position { get; set; }
    public int TransportContainerId { get; set; }
    public bool? IndicatorTank { get; set; }
    public string EmsNumbers { get; set; }
    public string ProperShippingName { get; set; }
    public string UNNumber { get; set; }
    public string Class { get; set; }
    public string PackingGroup { get; set; }
    public bool? TransportProhibited { get; set; }
    public double? DangerWeightNet { get; set; }
    public int PackingNumber { get; set; }
    public string PackingCode { get; set; }
    public double? DangerWeightNetExplosive { get; set; }
    public string LegalNorm { get; set; }

    public TransportContainer TransportContainer { get; set; }
}

Entität "TransportContainer":

public class TransportContainer : DbModel
{
    public string ContainerNumber { get; set; }
    public string OceanVoyageBookingNumber { get; set; }
    public double NetWeight { get; set; }
    public double GrossWeight { get; set; }
    public double? TaraWeight { get; set; }
    public int? OceanVoyagePortId { get; set; }
    public bool? IsForOceanVoyage { get; set; }
    public string Description { get; set; }
    public string OriginCountryCode { get; set; }
    public string DestinationCountryCode { get; set; }
    public int? CustomsId { get; set; }
    public bool IsFullContainer { get; set; }
    public bool? IsActiveReefer { get; set; }
    public string OceanVoyageShip { get; set; }
    public string Comments { get; set; }
    //public string OceanVoyage { get; set; }
    public string TransportPaperReference { get; set; }
    public double? MaxTemperature { get; set; }
    public string SealNumbers { get; set; }

    public IEnumerable<DangerousGoods> DangerousGoods { get; set; }
}

Builder:

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<GoodsItemCustomsNumber>()
        .HasOne<GoodsItem>(gicn => gicn.GoodsItem)
        .WithMany(gi => gi.GoodsItemCustomsNumbers)
        .HasForeignKey(gicn => gicn.GoodsItemId);
    builder.Entity<DangerousGoods>()
        .HasOne<TransportContainer>(dg => dg.TransportContainer)
        .WithMany(tc => tc.DangerousGoods)
        .HasForeignKey(dg => dg.TransportContainerId);
    ...

Tabellen und Relationen s. Anhang.

29.11.2023 - 11:05 Uhr

Es gibt zwei weitere Tabellen, die eine Fremdschlüsselbeziehung haben. Dort gibt es auch die Spalte "GoodsItemId":

public class GoodsItem : DbModel
{
    public int TransportContainerId { get; set; }
    public int Position { get; set; }
    public string Contents { get; set; }
    public double? MonetaryValueEUR { get; set; }
    public string PackagingCode { get; set; }
    public double PackagingGrossWeight { get; set; }
    public int PackagingNumberUnits { get; set; }
    public string CustomsTariffNumber { get; set; }

    public IEnumerable<GoodsItemCustomsNumber> GoodsItemCustomsNumbers { get; set; }
    public IEnumerable<DangerousGoods> DangerousGoods {  get; internal set; }
}
public class GoodsItemCustomsNumber : DbModel
{
    public int GoodsItemId { get; set; }
    public string RegistrationNumber { get; set; }

    public GoodsItem GoodsItem { get; set; }
}

Und so wird die Relation abgebildet:

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<GoodsItemCustomsNumber>()
        .HasOne<GoodsItem>(gicn => gicn.GoodsItem)
        .WithMany(gi => gi.GoodsItemCustomsNumbers)
        .HasForeignKey(gicn => gicn.GoodsItemId);
    ...

Diese Tabellen frage ich in der Methode im oberen Beitrag auch problemlos ab. Die Exception kommt erst bei der Abfrage von "DangerousGoods", und dort gibt es diese Spalte eben nicht und auch keine Fremdschlüsselbeziehung zu "GoodsItems". Die Relation von "DangerousGoods" zeigt auf eine andere Tabelle, die aber ebenfalls keine Spalte "GoodsItemId" enthält.

@Abt: Nein, es gibt keinen Zeitzonen-Bug. Hier läuft alles nach MEZ, und auch die Server stehen in Deutschland. Datenbank und frühere Software stammen allerdings auch nicht von mir. Ich hätte alles per UTC + Zeitzone gemacht.

Edit: Screenshot Tabelle hinzugefügt.

28.11.2023 - 14:51 Uhr

Verwendetes Datenbanksystem: SQL Server Express, NET v7

Moin-moin,

ich habe hier ein Problem mit einem ungültigen Spaltennamen, auf das ich mir absolut keinen Reim machen kann.

Und zwar erscheint der Fehler beim Binding in ein Listenobjekt nach einer simplen Tabellenabfrage. Nur dass die besagte Spalte gar keine Eigenschaft meines Models ist, und in der Db-Tabelle existiert sie natürlich auch nicht.

So sieht mein Modell aus:

public class DangerousGoods : DbModel
{
    public int Position { get; set; }
    public int TransportContainerId { get; set; }
    public bool? IndicatorTank { get; set; }
    public string EmsNumbers { get; set; }
    public string ProperShippingName { get; set; }
    public string UNNumber { get; set; }
    public string Class { get; set; }
    public string PackingGroup { get; set; }
    public bool? TransportProhibited { get; set; }
    public double? DangerWeightNet { get; set; }
    public int PackingNumber { get; set; }
    public string PackingCode { get; set; }
    public double? DangerWeightNetExplosive { get; set; }
    public string LegalNorm { get; set; }
}

Von dieser Klasse erbt es:

public abstract class DbModel
{
    bool Modified;

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public int Version { get; set; }
    public string ModifiedBy { get; set; }
    public DateTime? ModifiedOn { get; set; }

    protected DbModel()
    {
    }

    public virtual void Update(string modifier = null, DateTime? date = null)
    {
        if (!this.Modified)
            this.Version++;
        this.ModifiedBy = modifier ?? ApiUser.UserName;
        this.ModifiedOn = date ?? DateTime.Now;

        this.Modified = true;
    }
}

Hier wird der Aufruf ausgeführt:

public IEnumerable<GoodsItem> GetFullGoodsDescription(ContainerTransportOrder order)
{
    if (order != null)
    {
        var id = order.TransportContainerId;
        var goodsItems = this.GoodsItems
            .Include(gi => gi.GoodsItemCustomsNumbers)
            .AsSingleQuery()
            .Where(gi => gi.TransportContainerId == id).ToList();

        if (order.ContainsDangerousGoods == true)
        {
            var dangerousGoods = this.DangerousGoods.Where(dg => dg.TransportContainerId == id).ToList(); // hier erscheint die Exception

            foreach (var item in goodsItems)
                item.DangerousGoods = dangerousGoods.Where(dg => dg.Position == item.Position).ToList();
        }

        return goodsItems;
    }

    return null;
}

Die Exception lautet:

Ungültiger Spaltenname "GoodsItemId".

Es ist mir schleierhaft, warum NET hier diesen Spaltennamen mokiert. Auf der Basisklasse "DbModel" basieren Dutzende weitere Klassen zu Tabellen, wo es noch nie vergleichbare Probleme gab.

Hat hier irgendwer eine Idee? Ich bin völlig ratlos und habe schon alles mögliche ausprobiert, inkl. Umbenennungen und Neuanlage der beteiligten Klassen u. Tabellen.

05.06.2023 - 12:48 Uhr

Die Lösung war jetzt folgende:

Als AppPools u. Websites eingerichtet wurden, war der Server noch auf en-US konfiguriert, und diese Einstellungen haben die AppPools übernommen, so dass die jeweilige Culture aus den AppPool-Settings kam. Offenbar haben die Vorrang vor globalen Einstellungen in der web.config.

Es wurden nun einfach neue AppPools angelegt, die de-DE verwenden, und damit stimmen auch die Datumsformate wieder.

Trotzdem vielen Dank für die Ratschläge!

26.05.2023 - 15:31 Uhr

Ich verstehe. Allerdings wollen wir ja gerade den Code nicht ändern, weil das Ausgabeformat auf dem alten Server korrekt war, und wir jetzt davon ausgehen, dass irgendeine Windows-seitige Andersartigkeit für das falsche Datumsformat verantwortlich ist, die man eigentlich abstellen können müsste. Zeitzone, Systemzeit u. Standardsprache wurden inzwischen per Powershell auf UTC+2 u. Deutsch festgelegt. Festlegen der Culture per web.config hat auch nichts gebracht.

Ich meine, wenn ein und derselbe Code zuvor wie beabsichtigt ausgegeben wurde und auf dem neuen System nicht, dann muss das Problem doch auf Server-Ebene behebbar sein und nicht (nur) per Code-Anpassung.

26.05.2023 - 15:00 Uhr

Das hilft mir leider nicht weiter, denn es geht nicht um den Offset, sondern um das Datums/Zeitformat, das eben nicht in Englisch (05/26/2022 02:55 PM), sondern in Deutsch (26.05.2022 14:55) ausgegeben werden soll. Und da die Ausgabe auf dem alten Server wie beabsichtigt funktionierte, muss es sich hier um eine globale, systemabhängige Einstellung handeln, die wir gerne ändern wollen, wenn wir denn wüssten, was zu tun ist.

26.05.2023 - 14:23 Uhr

Moin-moin!

Wir haben gestern einen Serverumzug vorgenommen. Das neue System (Win Server 2022) lag dabei in Englisch vor und hatte zunächst auch eine falsche Zeitzone (UTC-7, Pacific Time), obwohl der Server in Frankfurt stehen soll.

Auf dem System wurde u.a. das NETv7.0.5 Hosting Bundle installiert, und alle migrierten Apps liefen auch einwandfrei. Allerdings wird bei mehreren Anwendungen jetzt das Englische Datumsformat ausgegegeben, wenn dieses per DateTime.ToString erzeugt wurde.

Wir haben verschiedene Dinge ausprobiert, um dieses Verhalten abzustellen, z.B. Deutsch auf Systemebene als Sprache eingerichtet, NET-Framework neu installiert... aber das Datumsformat bleibt Englisch.

Jetzt in allen Anwendungen den Code oder die Culture anzupassen kann die Lösung IMO nicht sein. Weiß hier zufällig jemand Rat, was zu tun ist, um ASP.NET die Englische Schreibweise auszutreiben?

Bin über jede Anregung dankbar

Grüße

07.12.2022 - 12:08 Uhr

Okay, ich sehe gerade, mein Problem liegt ganz woanders.

Sorry wegen der aufgewendeten Zeit!

07.12.2022 - 11:27 Uhr

Nein, nicht ICH deserialisiere das JSON, sondern ASP.NET macht das vor der Übergabe an die Action. Und ASP.NET deserialisiert Strings aus dem JSON in einen Mix aus Latin u. Unicode, und zwar auch dann, wenn ich obige Aufrufe verwende. Genaugenommen scheinen sie gar keinen Einfluss auf das Deserialisierungsverhalten von ASP.NET zu haben.

Ich habe bespielsweise folgendes JSON:


{
    "foo": "Holzmühle 1",
    "bar": "Württemberg"
}

Das geht in folgendes Objekt:


public class MyObj
{
    public string Foo { get; set; }
    public string Bar { get; set; }
}

Die String-Literale, die ich erhalte, lauten aber:


MyObj.Foo -> "Holzm\u00FChle 1"
MyObj.Bar -> "W\u00FCrttemberg"

Ist es jetzt verständlich?

EDIT: Für den Aufruf der Drittanbieter-API habe ich mir eine Klasse gebaut, die im Kern HttpClient u. JsonSerializer verwendet. Die hat auch schon in Dutzenden anderen Fällen funktioniert, und ich sehe das Problem auch nicht dort, sondern an der Stelle, an der ich den GET-URL aus u.a. obigen Literalen zusammenbaue.

07.12.2022 - 11:07 Uhr

Wenn eine Action JSON entgegennimmt und in ein Objekt deserialisiert, dann können String-Eigenschaften dieses Objekts Werte erhalten, die lateinische Zeichen und Unicode-Zeichen haben.

Diese String-Eigenschaften verwende ich dann in der Action, um sie als URL-Parameter an eine weitere API (Google Maps API) zu senden. Das geht aber nicht, wenn die Strings u.U. ein Mix aus Buchstaben und Unicode-Escape-Sequenzen sind. Und ich hatte gehöfft, dass ich mittels oben zitiertem Code abstellen kann, dass ASP.NET einzelne Zeichen als Unicode darstellt.

Ich muss diesen Mix aus Latin und Unicode in normale Buchstaben bekommen, damit ich sie an die Google-API senden kann. Und hier stehe ich gerade total auf dem Schlauch und habe seit gestern Nachmittag schon etliches ausprobiert.

07.12.2022 - 09:39 Uhr

Moin-moin,

ich habe hier ein Problem, an dem ich schon einige Stunden arbeite, das ich aber nicht gelöst bekomme:

Eine WebAPI verarbeitet per POST gesendete JSON-Daten, die von ASP.NET automatisch in ein Objekt deserialisiert werden. Soweit, so gut.

Nun enthält das JSON u.a. Strings, aus denen beim Decoding einzelne Zeichen als Unicode escaped werden. Und da die Strings als URL-Parameter beim Aufruf einer Drittanbieter-API direkt weiterverarbeitet werden, führen die Unicode-Chars jetzt zu Problemen.

Meine Frage: Wie kann ich es ASP.NET austreiben, einzelne Zeichen in Unicode zu escapen?

Folgendes habe ich bereits ausprobiert, ohne dass es einen Effekt auf das Deserialisieren gehabt hätte:


public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All));
    // bzw.
    services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping);
    ...
}

Das Projekt liegt in NETv6 vor.

Gruß

07.08.2020 - 10:13 Uhr

Ah okay, das habe ich wohl überlesen.

Schade, das ist jetzt natürlich blöd fürs Debuggen. Dann werde ich die CSS- u. JS-Files wohl auf unseren Server für statische Inhalte auslagern müssen.

Trotzdem vielen Dank!

06.08.2020 - 14:55 Uhr

Das bedeutet, dass die Dateien wie CSS u. JS nicht ins wwwroot der WebApp kopiert oder verlinkt werden, so dass ein Browser sie runterladen könnte.

06.08.2020 - 14:38 Uhr

Hi,

ich komme nicht weiter mit statischen Inhalten in Razor-Klassenbibliotheken (RCLs). Laut diesem Artikel muss man seit Net Core v3.1 in seinem RCL-Projekt nur einen "wwwroot"-Ordner anlegen und statische Dateien dort reinpacken, damit sie in der Webanwendung, die die RCL verwendet, zur Verfügung stehen. Aber leider funktioniert das nicht, die Dateien werden nicht übernommen.

Hat evtl. jemand eine Idee dazu?

03.02.2020 - 14:03 Uhr

Okay, vielen Dank für den Hinweis!

Die Iframe-Lösung ist leider eine Anforderung seitens unserer Leitung. Es geht um ein Modul, das verschiedene Abfragen an unsere Hauptanwendung richtet und auswertet. Die Abfragen selber mache ich schon per AJAX, aber es gehört auch ein Registrierungs- und Loginsystem dazu.

Das Iframe-Modul soll möglichst einfach in die Websites unserer Kunden eingebunden werden, die i.d.R. irgendein PHP-CMS verwenden wie Wordpress, Joomla o.ä., weswegen das mit einem eingebetteten Formular schwer wird. Aber wenn die Browser-Entwicklung diesen Weg geht, werde ich das wohl mittelfristig so umbauen müssen, dass die gesamte Funktionalität per AJAX/REST-Api abgewickelt wird.

03.02.2020 - 13:13 Uhr

Nach allerhand Recherche und Ausprobieren hat sich ergeben, dass man Sessions doch in einem Iframe verwenden kann. Man muss allerdings den AntiForgery-Mechanismus von ASP.NET deaktivieren. Bin darauf gestoßen, weil Formulardaten innerhalb des Iframes auch im Nirvana verschwunden sind.

Nur für den Fall, dass jemand mal vor einem ähnlichen Problem steht, hier der notwendige Befehl:


services.AddMvc().AddRazorPagesOptions(options =>
{
    options.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute());
});

03.02.2020 - 11:19 Uhr

So etwas hatte ich schon vermutet, war mir aber nicht sicher, ob der Browser die Cookies unterschiedlicher Domains nicht auch getrennt verwaltet.

Aber danke für den Hinweis bzw. die Bestätigung.

03.02.2020 - 10:51 Uhr

Hallo,

ich habe noch mal ein Problem mit Cookies in ASP.NET Core.

Unsere Anwendung läuft in einem Iframe, der auf Websites mit abweichender Domain erscheint. Sobald dies der Fall ist, werden keine Session-Cookies mehr geschrieben bzw. überhaupt keine Cookies mehr, die von ASP.NET automatisch erstellt werden wie Antiforgery u.ä. Im Testszenario innerhalb derselben Domain funktioniert alles wie erwünscht. Also offensichtlich ein Problem, das mit der domainübergreifenden Funktionsweise der App zu tun hat.

In der Startup.cs habe ich das so konfiguriert:



            services.AddDistributedMemoryCache();
            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromMinutes(UserManagement.SessionTimeout);
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = true;
                //options.Cookie.Name = UserManagement.SessionCookieName;
                options.Cookie.SameSite = SameSiteMode.None;
                options.Cookie.SecurePolicy = CookieSecurePolicy.None;
            });


            services.AddAntiforgery(options =>
            {
                options.SuppressXFrameOptionsHeader = true;
            });

Hat evtl. jemand eine Idee, was hier zu tun ist?

Gruß

28.01.2020 - 21:07 Uhr

Ein paar Fragen hätte ich noch zu diesem Verfahren.

Gehe ich recht in der Annahme, dass ein so authentifizierter Nutzer dann über die User-Eigenschaft des HttpContexts ansprechbar ist? Und sind somit auch die zuvor festgelegten Claims wieder abrufbar? Und schließlich, wenn ja, wo speichert ASP.NET diese Informationen überhaupt? Im Cookie-Wert?

28.01.2020 - 14:28 Uhr

Dann muss ich mir das mal näher anschauen. Danke soweit.

28.01.2020 - 14:19 Uhr

Nein, es geht nicht um Sessions, das erledigt hier ebenfalls NET Core. Es geht darum, länger abwesende User automatisch zu identifizieren - und das erfolgt per Cookie und UserAgent. Die Nutzer müssen auch die Möglichkeit haben, mit mehreren Geräten gleichzeitig angemeldet zu sein. Es geht also um kein Session-Cookie.

Der Gedanke war nun, dass der Nutzer, der sich einmal angemeldet hat und permanenten Login mit diesem Browser wählt, einmal ein Identifier-Cookie erhält und einmal ein AuthToken-Cookie. Beide Werte werden zusammen mit dem UserAgent in der DB gespeichert.

Kommt der Nutzer nun nach längerer Zeit auf die Seite, wird er anhand von Cookies u. UserAgent identifiziert, wenn er auf diesem Gerät/Browser schon mal angemeldet war. Und dann sollten als weiterer Schutz gegen Cookie-Diebstahl der AuthToken-Wert im Cookie und in der DB geändert werden.

Aber da es mir nicht gelingt (weil es wohl nicht geht), den AuthToken-Wert im bestehenden Cookie zu ändern oder in einem Rutsch das Cookie zu löschen und neu zu schreiben, ohne die Seite zwischendurch zurückzuschicken, ist diese Idee wohl hinfällig. Zumindest ist bis jetzt jeder Versuch fehlgeschlagen, das Cookie zu überschreiben. Auch nach einem Redirect hat es immer noch den alten Wert.

Ob man dieses Szenario mit Net-Core-Boardmitteln auch so umsetzen kann, weiß ich nicht. Zumal dabei ja höchstwahrscheinlich auch eine eigene Nutzer-Tabelle angelegt würde.

28.01.2020 - 13:09 Uhr

Hallo Foristi,

gehe ich Recht in der Annahme, dass man bestehende Cookies in ASP.NET Core nicht mit einem neuen Wert überschreiben kann, oder habe ich da was übersehen?

In meiner Anwendung können Nutzer dauerhaft angemeldet bleiben. Dazu verwende ich eine Kombination aus AuthToken per Cookie und UserAgent.

Nun möchte ich die Sicherheit noch weiter verbessern, indem jedes Mal, wenn ein Nutzer auf diese Weise identifiziert wurde, der AuthToken-Wert in der DB und im Cookie auf einen neuen geändert wird.

Nur habe ich leider keine Methode gefunden, wie ich den Wert eines bestehenden Cookies ändern könnte. Selbst Folgendes hat zu keinem Ergebnis geführt:

Response.Cookies.Delete(".AuthToken");
Response.Append(".AuthToken", "New Value", options);

Beim nächsten Seitenaufruf steht immer noch der alte Wert im Cookie, während sich der in der DB natürlich geändert hat, wodurch die automatische Authentifizierung nun fehlschlägt, und der User sich händisch neu einloggen muss.

Meine Frage also noch mal, kann man Werte bestehnder Cookies überschreiben, oder kann ich mein Sicherheitskonzept so nicht umsetzen?

Gruß, Cord

18.02.2013 - 13:57 Uhr

@Abt:

Du hast Recht, ich habe hier ein paar Begrifflichkeiten durcheinandergebracht, ich arbeite ausschließlich mit LINQ2SQL. Das ist eine Vorgabe, so dass ich auf keine andere Technolgie ausweichen kann. Ich werde mir deinen Vorschlag zu den Repositories gerne einmal anschauen, wobei ich keine direkten Zugriffe auf die Datenbank vornehme, sondern ausschließlich mit LINQ arbeite. Bis jetzt hat sich zumindest noch nicht die Notwendigkeit für einen direkten Zugriff ergeben.

Mein Problem konnte ich inzwischen lösen, indem ich die referenzierten Objekte in EntityRef<>-Instanzen lege. Jetzt werden auch die assoziierten Daten einwandfrei in die entsprechenden Objekte übertragen. An einem exemplarischen Beispiel sieht das so aus:


private EntityRef<Person> _Person = new EntitiyRef<Person>();

[Column(Name="PersonID")]
private int PersonID { get; set; }

[Association(ThisKey = "PersonID", IsForeignKey = true, IsUnique = true, Storage = "_Person")]
public Person Person
{
    get { return this._person.Entity; }
}

public Employee()
{
    this._Person.Entity = new Person();
}

17.02.2013 - 11:53 Uhr

verwendetes Datenbanksystem: SQL Server 2008 Express

Hallo Forumsgemeinde,

ich verwende eine Reihe von Klassen, die als Entitäten für LINQ fungieren. Dabei gibt es eine Tabelle pro konkreter Klasse. Im Einzelnen geht's um eine Entität namens "Employee", die ich mit drei anderen Entitäten assoziiere ("Person", "Address", "BankAccount") - es besteht eine 1:1-Beziehung. Das habe ich in der Employee-Klasse so realisiert:


// Die Fremdschlüssel als private members.
[Column(Name="PersonID")]
private int PersonID { get; set; }
[Column(Name = "AddressID")]
private int AddressID { get; set; }
[Column(Name = "BankAccountID")]
private int BankAccountID { get; set; }

// Die Entitäten dazu
[Association(ThisKey = "PersonID", IsForeignKey = true, IsUnique=true)]
public Person Person { get; private set; }
[Association(ThisKey = "AddressID", IsForeignKey = true, IsUnique=true)]
public Address Address { get; private set; }
[Association(ThisKey = "BankAccountID", IsForeignKey = true, IsUnique=true)]
public BankAccount BankAccount { get; private set; }

// Instanzierung der Entitäten im Constructor
public Employee()
{
    this.Person = new Person();
    this.Address = new Address();
    this.BankAccount = new BankAccount();
}

Nun zu meinem Problem. Wenn ich ein neues Employee-Objekt erstelle und in die Datenbank schreibe, klappt alles prima, die Eigenschaftswerte werden alle übernommen, auch die aus den drei assoziierten Objekten. Auch werden die neu erzeugten IDs als Fremdschlüssel in die EMPLOYEE-Tabelle eingetragen. Wenn ich allerdings per LINQ-Syntax eine Abfrage auf ein oder mehrere Employee-Entitätsobjekte starte, dann funktioniert zwar die Abfrage selbst korrekt, aber LINQ füllt nur das Employee-Objekt mit Daten aus der DB, die assoziierten Objekte bleiben hingegen leer. Ich hoffe, dass ich mein Problem verständlich schildern konnte. Mit LINQ/SQL bin ich noch ziemlich neu, und ich habe jetzt einen kompletten Tag drauf verwendet, dieses Problem zu lösen - leider ohne Ergebnis. Kann mir jemand von euch hier weiterhelfen?

Gruß
Cord

13.08.2007 - 17:20 Uhr

Schau Dich doch mal nach Implementierungen eines Socks-Proxys um - der macht im Grunde nichts anderes.

Grüße
Cord

27.07.2007 - 15:16 Uhr

Hallo Community,

es existiert die Aufgabe, eine umfangreiche erweiterbare Unternehmenslösung für sozialpflegerische Einrichtungen zu entwickeln.
Den Kern der Anwendung bilden eine Reihe von Geschäftsobjekten, welche die interne Struktur des Unternehmens plastisch nachbilden.

Im Einzelnen sind dies hierarchisch gegliederte Organisationseinheiten und die ihnen angehörenden Mitarbeiter sowie an Einheiten und Personen geknüpfte Rollen u. Berechtigungssätze, die auf späteren Prozesse und Arbeitsabläufe angewendet werden sollen.
Im weiteren Sinne gehören noch die Patienten/Zubetreuenden dazu.

Anwendungszielgruppe sind mittlere bis grosse Unternehmen mit einigen hundert bis einige tausend Mitarbeiter und ebenso grosser Zahl an Zubetreuenden.

Datenspeicherung erfolgt in erster Linie über Datenbanken, zweitrangig kommen noch Verzeichnisdienste und XML-Strukturen hinzu.

Als Anwendungsserver sollen vorrangig Webserver eingesetzt werden.

Nun komme ich zur eigentlichen Frage...

Es besteht nun die konkrete Überlegung, die oben genannten strukturellen Elemente statisch (bzw. cached) zur Verfügung zu stellen, da auf diese Objekte häufig zugegriffen wird und sie äusserst selten geändert werden.
Weniger häufig benötigte Zusatzinformationen zu den aufgeführten Objekten (z. B. Privatadresse eines MA oder Angehörige eines Zubetreuenden) werden in Profilen gespeichert, die ggf. als nicht statische Instanz aufgerufen werden. Dies gilt auch für alle anderen Geschäftsobjekte.

Der Hauptgrund für eine solche Vorgehensweise ist in erster Linie die Minimalisierung von Datenspeicher-Zugriffen und damit verbundene Optimierung von Auslastung und Geschwindigkeit.

Dem entgegen steht die ständige Belastung des Hauptspeichers, die in ihrem Ausmass nur schwer zu kalkulieren ist, da sie einerseits von der Unternehmensgrösse und damit schlicht der Anzahl der Objekte und andererseits von der durchaus variierenden Grösse der in den Objekten gespeicherten Werte abhängig ist. Dazu kommen noch die wechselnd personenspezifischen Anzahlen von Berechtigungssätzen, die vor allem abhängig von der Zahl der später verwendeten Module sind, welche alle ihre eigenen Berechtigungssätze mitbringen, denn die Module repräsentieren die Arbeitsabläufe, die innerhalb des Unternehmens anfallen.

Nun ist meine Frage an Euch, wie würdet Ihr diese Überlegung bewerten - ist es sinnvoll, dieses Kompromiss aus Minimierung der DB-Zugriffe und Hauptspeicherbelastung zu machen oder haltet Ihr es eher für eine falsche Herangehensweise, mit einer grossen Zahl statischer Objekte zu arbeiten?

Hat jemand bereits Erfahrungen mit vergleichbaren bzw. ähnlichen Architekturen bzw. Aufgabenstellungen?
Ich selbst habe an etwas Vergleichbaren noch nie zuvor gearbeitet.

Ich freue mich über jeden Beitrag bzw. Anregung oder Denkanstoss zu dieser Fragestellung.

Grüße
Cord

25.05.2007 - 14:52 Uhr

Hallo,

es gibt eine Vektorgrafik-Erweiterung für JS im Browser, Stichwort: Canvas.
Das wird inzwischen von allen gängigen Browsern unterstützt, und für den MSIE gibt's einen schönen Wrapper bei Google Code.

Die Parameter überträgst Du dann auf den Server, wo die echten Grafiken erstellt werden.

Das wäre ein Höchstmass an Interaktion.

Grüße

25.05.2007 - 14:44 Uhr

Wenn Du aktiviertes JS beim Client voraussetzen kannst, ist das auch sehr komfortabel per JS zu erledigen. Du brauchst nur eine einzige Grafik und kannst diese rotieren und mit entsprechender Farbe versehen (sogar Farbverläufe und Transparenzen sind machbar).

Grüße

10.05.2007 - 01:29 Uhr

Du kannst die J#-BrowserControls verwenden.
Diese verwenden dieselbe Schnittstelle wie sie die JRE nutzt; allerdings braucht es analog auch die entsprechenden Binaries - also die VM und die notwendigen Libs...

Eine wesentlich universellere Alternative, die allerdings ausschliesslich auf dem MSIE läuft, wäre noch ein sogenanntes .NET-Applet, welches aber ein Windows-kompatibles System und die vollständige .NET-Installation voraussetzt.

Grüsse

27.04.2007 - 14:13 Uhr

Ansonsten gibt es die PARAM Tags innerhalb des OBJECT Tags, in welches Flash etc. einzubinden ist. Diese Tags sind extra für Programmparameter gedacht. Du kannst hier Variablen und Werte angeben, auf die Dein Flash in Form externer Vars zugreifen kann.

Grüsse

26.04.2007 - 15:09 Uhr

Ein ActiveX Control, das mit dem Dateisystem interagiert, wird bestimmt als unsicher eingestuft.

26.04.2007 - 15:06 Uhr

In die Code-Ansicht wechseln und folgendes Attribut angeben...
style="position:absolute;left:100px;top:50px"

Grüsse

17.04.2007 - 13:21 Uhr

Original von M@TUK
Das activeX-Controll soll keine UI haben sondern im Hintergrund werkeln
Das UI soll nur die HTML-Tabelle mit den Files am Server sein.

Das wird so nicht funktionieren.
Du benötigst eine UI, mit der Du per Drag&drop interagieren kannst - HTML ist dazu nicht in der Lage.

Original von M@TUK
Ist es möglich activex-Controls mit C# zu entwickeln?

Ja.
Webchat wie in JAVA

Grüsse

16.04.2007 - 17:53 Uhr

Versuche einmal etwas in der Art...


<%# Eval("Name").ToString().Replace(Environment.NewLine, "<br />") %>

Grüsse

16.04.2007 - 16:17 Uhr

Man könnte evtl. folgendes machen...

Eine Erweiterung wird sicher in erster Linie ein UserControl sein, dass seine eigenen Binaries und ggf. weitere UCs oder WebControls mitbringt.

Um eine generelle Struktur festzulegen, könnte man ein Unterverzeichnis für Plugins erstellen oder man bindet diese in einem bestimmten Konfigurationsabschnitt in der web.config ein. Am Optimalsten ist sicher eine Kombination aus beidem.

Wird das Web gestartet, liest es die vorhandenen Plugins in der web.config aus und überprüft deren Vorhandensein im Unterverzeichnis u. ggf. bin/appCode-Ordner. Dann wird eine Instanz der statischen Repräsentation des Plugins gebildet und einer statischen Auflistung zugefügt. Dieses Objekt enthält die Konfigurationseinstellungen der Erweiterung und kommuniziert ggf. mit dem DataLayer.
Zukünftig in Seiten instanzierte Controls als UI-Frontend des Plugins können dann mit der statischen Instanz (dem Manager) kommunizieren.

Grüsse

14.04.2007 - 14:41 Uhr

Die Page Klasse verfügt auch über allerhand Methoden zur Skriptintegration.
Die werden dann ab v2.0 als obsolet erklärt u. tauchen im ClientScriptManager wieder auf.

Grüsse

13.04.2007 - 15:53 Uhr

Original von crusada
Wie würdet ihr eine ASP .NET -Anwendung erstellen das pfluginfähig ist? Ist das so in dieser Form überhaupt möglich wie bei WinForms-Anwendungen?

Ich würde sagen, ein Plugin-System ist hier schlicht nicht nötig, da hinzugefügte Seiten z. B. automatisch Bestandteil der Anwendung werden. Ihre Integration könnte evtl. durch Modifizierung der .sitemap Datei optimiert werden.

Wenn Du eigene HttpModule oder -Handler verwenden möchtest, müssen diese in der web.config eingetragen werden, womit sie auch ausreichend integriert sind.

//EDIT:
Wenn Du Erweiterungen einsetzen willst, die in Seiten eingebettet werden sollen, dann schreibe einfach WebControls oder UserControls, die ggf. ein oder mehrere Interfaces implementieren müssen, um reibungslos mit der vorhandenen Anwendung kommunizieren zu können.

Grüsse

12.04.2007 - 23:45 Uhr

Flash ist eine ganz eigene Geschichte - es wird lediglich vom MSIE als ActiveX eingestuft, um in dessen Rechtemodell erfassbar zu sein.

Im Browser kannst Du mit einer Flash-Anwendung per Scripting kommunizieren. die notwendige API findest Du hier.

Wenn du Einsprungstellen ausserhalb der Standard-API suchst, kannst Du in Flash Methoden definieren, die von z. B. Javascript als Event gebucht werden können.

Grüsse

05.04.2007 - 19:13 Uhr

using System.DirectoryServices;
...
DirectoryEntry root = new DirectoryEntry("WinNT://");
root.Children.SchemaFilter.Add("Domain");
foreach (DirectoryEntry domain in root.Children)
{
    Console.WriteLine(domain.Name.ToUpper());
    domain.Children.SchemaFilter.Add("Computer");
    foreach (DirectoryEntry host in domain.Children)
        Console.WriteLine("* " + host.Name);
    Console.WriteLine();
}

Ist nicht getestet, sollte aber so hinhauen.
Voraussetzung ist ein Verzeichnisdienstanbieter (z. B. PDC) im Netz - ggf. das Protokoll ändern (z. B. LDAP://).

Grüsse

05.04.2007 - 13:23 Uhr

Angemeldete Benutzer erhälst Du über API Call NetWkstaUserEnum (netapi32).

Grüsse

01.04.2007 - 14:39 Uhr

Hmmm, stimmt.
'Scheint daran zu liegen, dass es in einem Template initialisiert aber vom UpdateProgress-Control nicht in dessen Controls-Auflistung eingefügt wird bzw. darin nicht als Control weiter existiert.

Das scheint sich nicht lösen zu lassen.

01.04.2007 - 12:59 Uhr

this.LabelDownloadProgress
😉

Grüsse

31.03.2007 - 17:36 Uhr

Du meinst den UNC-Pfad?

Wenn ja, schau Dir mal den namespace System.Management und die WMI-Klasse Win32_NetworkConnection an.

Grüsse

31.03.2007 - 17:30 Uhr

Es gilt grundsätzlich folgendes Prinzip, wobei es völlig egal ist, innerhalb welchen Templates (Master, Page od. UC) man sich befindet:

Hardcodierte (deklarative) Elemente werden automatisch von ASP.NET erzeugt und verwaltet - für dynamische Controls muss man alles selber machen.
Das betrifft das Erzeugen, Eigenschaften Zuweisen, Inhalte Einfügen und Events Registrieren.

Eine Lösung wäre es, wenn Du Dein Menü z. B. als UserControl realisierst und die Inhalte über DataBinding persistierst.
Wenn das Menü für alle Besucher der Site verfügbar sein soll, würde ich seine Struktur im Cache ablegen oder im Application-Objekt, nachdem sie einmal eingelesen und erstellt wurde.

Das Session-Objekt sollte für eine solche Angelegenheit immer die letzte Lösung sein, da sie bei höherer Nutzerzahl immer auch zu einer zusätzlichen Speicherbelastung oder abhängig von der Art der Session-Verwaltung zu Performance-Einbußen führt.
Der ViewState ist definitiv nicht für das Persistieren von Seiteninhalten gedacht.

Grüsse

27.03.2007 - 14:37 Uhr

Ich würde das eher so versuchen...


public static void SaveDS(DataSet savingDS, string savingPath)
{
    object thisLock = new Object();
    lock(thisLock)
    {
        savingDS.WriteXml(savingPath);
    }
}

Grüsse

26.03.2007 - 23:46 Uhr

Nimm einfach das Application Objekt her und mach's, wie Du es beschrieben hast - das ist ausreichen und, vor allem, transparent.


this.Application["activeUsers"] = 0;
...
int GetActiveUsers()
{
    return (int)this.Application["activeUsers"];
}
...
void AddActiveUser()
{
    this.Application.Lock();
    ((int)this.Application["activeUsers"])++;
    this.Application.Unlock();
}
...
void RemoveActiveUser()
{
    this.Application.Lock();
    ((int)this.Application["activeUsers"])--;
    this.Application.Unlock();
}

Grüsse

26.03.2007 - 23:30 Uhr

Du kannst den Pfad nicht beeinflussen, da er automatisch das Arbeitsverzeichnis repräsentiert - und dieses ist immer 1). /app/bin, 2). GAC, 3). %System-Ausführungsverzeichnis%...

Grüsse