Hallo Abt,
danke für die Infos.
Schaue mir das mit dem Staging mal an und hoffe, das ich es irgendwie nutzen kann.
Viele Grüße, Jan
Ps.:
Ich werde mich dann wohl für
Warmup ASP
entscheiden. Euch allen nen schönen Vatertag!
Hi Community,
ich habe einen selfcontained-Webservice.
Wenn ich änderungen an diesem durchführe, braucht der initiale Request teilweise 3-5 Sekunden für eine Antwort. Dananch, bis zum nächsten deploy, habe ich antwortzeiten von wenigen ms.
Ich nutze kein EF-Core oder dergleichen - kann mir jemand verraten, warum der erste Aufruf so lange dauert und wie ich nach einem Publish verhindern kann, das der User 5 sekunden beim first request warten muss?
Vg Jan / Killerkruemelchen
Edit: Danke fürs editieren des Titles, hab das zu spät bemerkt 😃
Hey Abt,
weil ich nur die Plugins programmieren "darf".
An der eigentlichen Anwendung darf ich nichts ändern.
Ich kann aber beliebig mit bspw Webservices etc arbeiten (Aus den Plugins aufrufen)
Hey Abt,
über den Sicherheitsaspekt habe ich ehrlich gesagt garnicht nachgedacht.
Hintergrund ist, das die Anwendung meine dlls als Plugin lädt.
Diese dlls enthalten Logik, um Messergebnisse eines Massenspectrometers "HumanReadable"
in einer Tabelle darzustellen.
Diese Tabelle - und ihre Spalten - würde ich gerne Copy Pasten.
Kann man sowas vielleicht pipen?
Hallo Community,
ich habe eine Applikation, welche auf einem Server läuft.
Für diese Applikation muss ich Plugins entwickeln.
Die Applikation auf dem Server ist eine WPF-Hülle, welche ich (vial dll) mit Logik befülle.
Meine Frage ist, ob es möglich ist, etwas ins Clipboard zu Kopieren, was dann auf dem Lokalen Client landet, bzw wie ich Daten aus der Applikation an mein lokales clipboard schicke.
Ist das überhaupt möglich?
Vg, Killerkruemel
Hallo Abt,
das fühlt sich auch grade nach Premature-Optimization an.^^
Trotzdem danke für euer Feedback.
Viele Grüße, Killerkruemel
>Interessanter Ansatz. Ich schaue mal was ich finde / schreibe und stelle es bei bedarf hier rein 😃
Äpfel und Birnen sind trotzdem beides Obstsorten.
Genau wie es bei QuickIO auch möglich ist, ansonsten den StandardIO namespace zu nutzen.
(Obwohl ich das seitdem ich QuickIO kenne nahezu niemandem raten würde)
Dachte lediglich, ihr kennt vielleicht eine Library/Ein Snippet, die mich einen Fileparse by Offset (o.Ä.) (Den mit Sicherheit jemand anders schon mal gemacht hat) nicht neu erfinden lassen muss.
Aber trotzdem Danke für eure Zeit.
Hallo T-Virus.
Es gibt eigentlich kein Problem, ich suche lediglich nach einer (vllt schon vorhandene Möglichkeit) eine Recht Große Textdatei (vllt mit Offset) einlesen und verwerten könnnen.
Dachte - da ich auch QuickIO kenne - das es etwas ähnliches für Textdateien gibt 😃
Hallo Community,
Ich habe eine Textdatei, welche ≥ 5000 Zeilen Text (Messergebnisse eines Runs eines Messgerätes) enthält. Die ersten 10 Lines eines Blocks sind dabei immer Metadaten (Ein Block ist etwa 100 Zeilen Lang).
Die Frage, die sich mir stellt, ist,
ob es neben StreamReadern, Buffered Readern, ReadLines/ReadLine eine einfache Lösung gibt, um
nicht jede Zeile der Datei einzeln betrachten zu müssen, oder vllt einen Ansatz für einen Mapper, welcher mir Blockweise aus der Textdatei daten holt und in eine Structur umwandelt.
Viele Grüße,
Killerkruemel
Siehe mein Beispiel
> (dachte Du hast das im anderen Thread bereits gelesen?).
Habe ich tatsächlich gerade erst, dadurch wird mir jetzt gerade auch einiges klar.
Generell habe ich scheinbar Frameworkstrukturen falsch verstanden.
Von den Assemblies ist ein solches Framework z.B. folgendermaßen aufgebaut: (Achtung: wurde dafür auch schon von Abt kritisiert - nicht gänzlich zu Unrecht):
- FluiTec.Data -> Basisschnittstellen für UnitOfWork, Entitiy, Repository
- FluiTec.Data.Dapper -> Basisimplementierungen für vorgenannte Klassen (abstrakt)
- FluiTec.Data.Dapper.Mssql -> Weitergehende Implementierungen für MsSql
- FluiTec.Data.Dapper.Pgsql -> Weitergehende Implementierungen für PgSql
- FluiTec.Data.LiteDb -> Implementierung für LiteDb
- FluiTec.Data.Sql -> Simpler SQL-Generator für verschiedene Provider
(Nur Basis-Sachen wie "Such mir alle Records", "Zähle alle Records", etc. - alles leicht cachebar)
Ich dachte bisher, das ich die entsprechenden Schichten anders abstrahieren muss.
(e.g.)
NameSpace.DAL
NameSpace.Model
NameSpace.Contract
etc.
Dein Beispiel hilft mir hier sehr weiter Abt,
und auch danke an dich für deine Zeit Taipi.
Viele Grüße, Killerkruemel
Das würde bedeuten, das ich, sofern ich keine Änderungen an den Tabellen mehr habe, die generierten Entities und den Context in die StandardBibliothek kopieren kann/muss/sollte, verstehe ich das richtig?
Mein Rat: verzichte komplett auf den Expression Parameter an der Stelle, bau Dir ein Basis Repository für CRUD und biete spezifische Methoden direkt in den implementierenden Repositories an.
Siehe mein Beispiel in:
>
Das ist der Ansatz, den ich verfolgen wollte. Vielen Dank!
Hallo Community,
heute bin ich über EF Core gestolpert und habe mich gewundert,
warum zwingend eine executable erforderlich ist.
Das würde doch bedeuten, dass die DB Operationen direkt im (e.g. ASP.NET Core) Webservice hängen und nirgendwo anders genutzt werden können, oder sehe ich das falsch?
Wie baue ich mir beispielsweise ein Framework mit EFCore auf?
e.g.
NameSpace.DAL (Hier EFCore)
NameSpace.Model
NameSpace.Contract
Viele Grüße
Killerkruemel
Edit: Ich glaube ich habe das falsche Subforum erwischt, sorry...
Ich schließe mich da eurer Argumentation an und werde vermutlich auf EFCore wechseln.
Der Grundgedanke war, das ich die Repositories nicht unnötig mit Code und parameterisierten Methoden aufblähen wollte. Ich habe ja alle Parameter, welche ich für die Abfragen in Dapper brauche, direkt in den Expressions.
Aber gerade der Performanceaspekt von Taipi und der Aspekt von Abt, das Dapper dies garnicht vorsieht, lässt mich gerade massiv daran zweifeln, dass das die richtige Lösung ist.
Ich lasse den Thread trotzdem auf gelöst wenn das ok ist, jedoch mit Vorbehalt.
Vielen Dank euch beiden für eure Hilfe.
Gruß, Killerkruemel
Hallo Abt,
die Methode ist nur Exemplarisch.
Meine Repositories implementieren alle ein Interface, welches 4 Methoden vorgibt:
protected abstract IEnumerable<T> FindAll(Expression<Func<T, bool>> @where = null);
protected abstract void Update(T entity);
protected abstract bool Delete(T entity);
protected abstract T Insert(T entity);
Innerhalb des Repos ist das dann so gelöst
protected override IEnumerable<IPlanningObject> FindAll(Expression<Func<IPlanningObject, bool>> where = null)
{
//DoSth with where and its parameter
}
//Andere Klasse
protected override IEnumerable<IFooObject> FindAll(Expression<Func<IFooObject, bool>> where = null)
{
//DoSth with where and its parameter
}
da ich innerhalb FindAll mit Dapper arbeite, welches teilweise die in den where befindlichen Parameter nutzt, entstand mein Post.
... das ist das komplizierteste "Ich spare mir einen Parameter" welches ich je geschrieben habe -.-*
Lösung:
var operation = (BinaryExpression)expression.Body;
BinaryExpression testCode = (BinaryExpression)operation.Left;
MemberExpression testCode_Right = (MemberExpression) testCode.Right;
string name = (string)Expression.Lambda(testCode_Right).Compile().DynamicInvoke();
Eidt sagt:
Danke Taipi!
Jetzt bekomme ich den Typ MethodBinaryExpression, welcher nicht in MemberExpression gecastet werden kann.
Liegt es daran, das mein T aus Expression<Func<T,bool>> ein Interface ist?
Hi Taipi,
Danke für die Antwort.
Ja, auf der Seite war ich schon.
Es scheitert gerade daran, das ich Body.Left.Right nicht zu einer ConstantExpression casten kann,
da es eine FieldExpression ist.
Ich habe auch versucht, über die PropertyInfo der Member an die Information zu kommen,
allerdings habe ich keinen Typ für propertyInfo.GetValue(???)...
Hallo Community,
ich scheitere grade an etwas vermutlich simplem.
Folgender Quick&DirtyCode aus dem LinqPad
public interface IFoo
{
string Name {get;set;}
int Number {get;set;}
}
public class Foo : IFoo
{
public string Name {get;set;}
public int Number {get;set;}
}
public List<Foo> FooCollection = new List<Foo>
{
new Foo(){Name = "Name1", Number = 1},
new Foo(){Name = "Name2", Number = 2},
new Foo(){Name = "Name3", Number = 2}
};
void Main()
{
string name = ReturnFoosName(x => x.Name == "Name1" && x.Number == 1);
name.Dump();
}
public string ReturnFoosName(Expression<Func<IFoo, bool>> where)
{
//var qq = where.??? Hier hätte ich gerne den Wert "Name" und/oder den Wert "Name1"
//var ww = where.??? Hier hätte ich gerne den Wert "Number" und/oder den Wert "1"
return FooCollection.Single(where.Compile()).Name;
}
In der Methode ReturnFoosName würde ich jetzt gerne aus dem 'where'
den Parameter auslesen.
Mit Expression<Func<T>> komme ich über den Body an die Daten.
e.g.
var body = (System.Linq.Expressions.MethodCallExpression)expression.Body;
Aber bei obigem "Predicate" nicht.
Frage:
Viele Grüße,
Killerkruemel
Stimmt. Aber anders habe ich es nicht gelöst bekommen.
Vielleicht nutze ich auch die falschen Module?
Habe die (Für mich ausreichende Lösung) nun gefunden.
Für jede Umgebung habe ich ein eigenes Artifact erstellt.
Nun funktioniert das MultiRelease.
Danke Abt für deine zeit und Mühe.
Ergänzend sei gesagt, das ich - sofern ich 2 mal hintereinander das Release triggere - auch nur auf 1 Umgebung diesen Fehler erhalte.
Fehlermeldung:
2018-09-12T06:17:58.6837939Z Download complete.
2018-09-12T06:17:58.6838207Z 355 placed file(s): 353 downloaded, 2 empty
2018-09-12T06:17:58.6838550Z 82 MB downloaded at 8295 KB/sec. Download time: 00:00:10.0129106.
2018-09-12T06:17:58.6838707Z Preparing to download artifact: SequenceGenerator
2018-09-12T06:17:58.6838817Z Artifact Type: FileShare
2018-09-12T06:17:58.6858805Z An error occurred during download: System.UriFormatException: Invalid URI: The format of the URI could not be determined.
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
at System.Uri..ctor(String uriString)
at Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.BuildArtifact.<DownloadArtifactAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.BuildArtifact.<DownloadAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.Agent.Worker.Release.ReleaseJobExtension.<>c__DisplayClass39_2.<<DownloadArtifacts>b__2>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.Agent.Worker.Release.RetryExecutor.<ExecuteAsync>d__20.MoveNext()
Bild 2
Anbei ein Bild:
Hallo Abt,
das merkwürdige ist eigentlich,
das das 2 mal exact die gleiche Phase ist. Nur 2 Verschiedene Ordner auf den Fileshares.
Drehe ich die Reihenfolge um, schlägt das Publish Artifacts fehl.
Edit sagt:
Ich möchte ein Successfull Build(Compile, UnitTest etc), genauer die Releasedateien, auf 4 unterschiedliche Rechner kopieren, dabei aber 4 Umgebungen deffinieren.
Hallo Community,
ich habe einen TFS 2017, auf welchem ich gerne folgendes erreichen möchte:
Schritt 1: Download der Artefakte des letzten Build und Kopieren auf FileShare
Schritt 2: Download und kopieren der ReleaseDateien auf NetzwerkRechner
Schritt 1 klappt.
Schritt 2 nicht.
Die Konfiguration:
1 Artefakt meines Builds.
1 Umgebung für den Schritt "Publish Build Artifacts"
1 Umgebung für den Schritt "Copy Files"
Die Fehlermeldung:
2018-09-06T13:02:10.3040280Z Artifact Type: FileShare
2018-09-06T13:02:10.3097124Z ##> Fehlermeldung:
Downloading artifacts failed: System.UriFormatException: Invalid URI: The format of the URI could not be determined.
Ich bekomme es nicht hin, ein Artefakt 2 mal zu kopieren.
Hat jemand von euch soetwas schonmal gehabt?
Hallo Abt,
vielen Dank vorab für deine Mühen.
Worum geht es Dir denn?
Was meinst Du mit "schnell und zuverlässig an Eigenschaften" kommen?
Geht es Dir um die Serialisierung der Json-Antwort, oder willst Du den Wert haben?
Reden wir hier von einer rekursiven Hierarchie und ein Container ist das gleiche wie ein SubContainer, oder sind das zwei verschiedene Objekte/Klassen) ?
Mir geht es darum, mit möglichst wenig Aufwand auf Elemente und ihre Werte innerhalb der "Produktionskette" zugreifen zu können.
Ich versuche es nochmal anders:
Gegeben sei diese Struktur:
Container C
C.Name
C.ID
C.SubContainer
SubContainer SC
SC.Name = SC1
SC.ID
SC.[...]
SC.SubContainerEigenschaftenListe<SubContainerEigenschaft>
SubContainerEigenschaft SCE_Name
SCE.Wert
SCE.[...]
SCE.SubContainerEigenschaftDeffinitionsListe<SubContainerEigenschaftDeffinition>
SubContainerEigenschaftDeffinition SCED
SCED.Typ = String
SubContainerEigenschaft SCE_Datum
SCE.Wert
SCE.[...]
SCE.SubContainerEigenschaftDeffinitionsListe<SubContainerEigenschaftDeffinition>
SubContainerEigenschaftDeffinition SCED
SCED.Typ = Date
SubContainerEigenschaft SCE_Ergebnis
SCE.Wert
SCE.[...]
SCE.SubContainerEigenschaftDeffinitionsListe<SubContainerEigenschaftDeffinition>
SubContainerEigenschaftDeffinition SCED
SCED.Typ = Double
SubContainer SC
SC.Name = SC2
SC.ID
SC.[...]
SC.SubContainerEigenschaftenListe<SubContainerEigenschaft>
SubContainerEigenschaft SCE_Name
SCE.Wert
SCE.[...]
SCE.SubContainerEigenschaftDeffinitionsListe<SubContainerEigenschaftDeffinition>
SubContainerEigenschaftDeffinition SCED
SCED.Typ = String
SubContainerEigenschaft SCE_Datum
SCE.Wert
SCE.[...]
SCE.SubContainerEigenschaftDeffinitionsListe<SubContainerEigenschaftDeffinition>
SubContainerEigenschaftDeffinition SCED
SCED.Typ = Date
SubContainerEigenschaft SCE_Ergebnis
SCE.Wert
SCE.[...]
SCE.SubContainerEigenschaftDeffinitionsListe<SubContainerEigenschaftDeffinition>
SubContainerEigenschaftDeffinition SCED
SCED.Typ = Double
[usw]
Wie komme ich möglichst flexibel an die SubContainerEigenschaft Name des Elementes SC2, ohne die gesammte Kette iterieren zu müssen?
@ Witte - die Idee mit dem VisitorPattern ist interessant.
Jedoch habe ich es entweder Missverstanden, oder es ist für meinen Ansatz nicht hilfreich. Der Kerngedanke des Patterns ist es ja, den Verarbeitungsalgorithmus von Objekten zu trennen (IMO)
Jedoch will ich nichts verarbeiten, sondern möglichst zuverlässig und schnell an einzelne Eigenschaften der SubObjekte herankommen.
Das wiederum lässt den Schluss zu, dass Du überhaupt keinen REST sondern einfach einen simplen Json-Service schreibst; denn das schlanke Navigieren über Objekte durch Url-Segmente fällt bei Dir ja flach.
[...]
Was genau ist der Grund, dass es hier der Fall ist?
Hallo Abt,
Ich muss einen Service aufrufen, welcher basierend auf einer ID eine Struktur als JSON zurückgibt, die oben definiert ist (Exemplarisch):
Eine Liste aus Containern
Jeder **Container **hat eine Liste aus SubContainern.
Jeder **SubContainer **hat eine Liste aus SubContainerEigenschaften
Jede **ContainerEigenschaft **kann, muss aber nicht, eine Liste aus **SubEigenschaften **enthalten
Es können 1-n Container vorkommen
Es können 1-n SubContainer vorkommen
Es können 1-n SubContainerEigenschaften vorkommen
Es können 0-n SubEigenschaten vorkommen.
Stell es dir am besten wie eine Fertigungsprozesskette vor:
Auto ist der Container.
Türenmontieren ist ein SubContainer
Fenster-vorne ist eine SubContainerEigenschaft
Fensterfarbe ist eine SubEigenschaft
[...]
Fenster-hinten ist eine SubContainerEigenschaft
[...]
Karosserie montieren ist ein SubContainer
[usw...]
ich brauche in der Anwendung nun zugriff auf die FensterFarbe, von
denen es wie gesagt 0-4 geben kann.
P.S.:
Ich kann die Antwort des Services nicht ändern/anpassen, ich muss den kommenden json string nutzen.
Hallo Community,
es gibt einen zu nutzenden RestService, welcher mir eine Objecthierarchie mit bis zu 100 Objekten ala
List<Container>=>
Container =>
List<ContainerItem> =>
ContainerItem =>
List<Item> =>
Item
wiedergibt, von denen Ich u.U. sogar die einzelne Items, auch bestimmte Items brauche.
Daher überlege ich mir gerade, wie ich die Datenaufarbeitung am besten realisieren könnte.
Folgende Überlegung:
public class CLAPFactory : IFactory
{
public readonly Container<IAnalyticalActivityP> _activityContainer;
private readonly Container<IAnalyticalElementaryTaskRecord> _aetrContainer;
public CLAPFactory()
{
_activityContainer = new Container<IPersistableData>();
_aetrContainer = new Container<IPersistableData>();
}
public void Persist<TPersistableData>(IList<TPersistableData> collection) where TPersistableData : IPersistableData
{
foreach (var data in collection)
{
_activityContainer.Add(data.Key, (IAnalyticalActivityP)data);
}
}
public void Persist<TPersistableData>(TPersistableData data) where TPersistableData : IPersistableData
{
_activityContainer.Add(data.Key, (IAnalyticalActivityP)data);
}
public TPersistableData LoadableData<TPersistableData>(string key) where TPersistableData : IPersistableData
{
if (typeof(TPersistableData) == typeof(IAnalyticalActivityP))
return (TPersistableData)_activityContainer[key];
if (typeof(TPersistableData) == typeof(IAnalyticalElementaryTaskRecord))
return (TPersistableData)_activityContainer[key];
return default(TPersistableData)
}
}
public interface IFactory
{
void Persist<TPersistableData>(IList<TPersistableData> collection) where TPersistableData : IPersistableData;
void Persist<TPersistableData>(TPersistableData data) where TPersistableData : IPersistableData;
TPersistableData LoadableData<TPersistableData>(string key) where TPersistableData : IPersistableData;
}
public class Container<TPersistableData> : Dictionary<string, TPersistableData> where TPersistableData : IPersistableData
{
public Container()
{
}
public Container(int capacity) : base(capacity)
{
}
public Container(IEqualityComparer<string> comparer) : base(comparer)
{
}
public Container(int capacity, IEqualityComparer<string> comparer) : base(capacity, comparer)
{
}
public Container(IDictionary<string, TPersistableData> dictionary) : base(dictionary)
{
}
public Container(IDictionary<string, TPersistableData> dictionary, IEqualityComparer<string> comparer) : base(dictionary, comparer)
{
}
protected Container(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
Wie kann ich verhindern, für jedes TPersistableData-INterface eine eigene Interfaceabfrage zu machen?
(vgl. If(typeof)[...])
Ist dies überhaupt der richtige Ansatz?
Heyho, könntest du via
machen.
<TextBox Name="txtbox">
<TextBox.Text>
<MultiBinding StringFormat="{}{0}{1}{2}">
<Binding Path="Salutation" />
<Binding Path="Name" />
<Binding Path="PreName" />
</MultiBinding>
</TextBox.Text>
</TextBox>
Und wenn ich das alles wie zuvor in einem "Rutsch" mache, dann hab ich das "GUI blockerit"-Thema.
Das wirst du auch weiterhin haben, solange du nicht [FAQ] Warum blockiert mein UI beachtest....
Stichwort Scope: Scopes in C#
void buttonplaysetzten()
{
button1.Text = "play";
textBox1.Enabled = true;
comboBox1.Enabled = true;
engine.currentlyPlayingSound.Stop();
engine.RemoveSoundSource(song);
MessageBox.Show("Stop by buttonplaysetzten"); //zum testen
}
das Objekt "engine" gibt es in der Methode buttonplaysetzen nicht.
Entweder du gibst es als Parameter mit in die Methoden, oder Intitialisierst es als Klassenvariable, was aber eigentlich auch bad practise ist.
Bsp:
void MethodeXYZ()
{
ISoundEngine engine = new ISoundEngine(SoundOutputDriver.AutoDetect, SoundEngineOptionFlag.DefaultOptions, sndDev.getDeviceID(output));
buttonplaysetzten(engine);
}
void buttonplaysetzten(ISoundEngine engine)
{
button1.Text = "play";
textBox1.Enabled = true;
comboBox1.Enabled = true;
engine.currentlyPlayingSound.Stop();
engine.RemoveSoundSource(song);
MessageBox.Show("Stop by buttonplaysetzten"); //zum testen
}
Hallo Abt,
Dann stimmt was gewaltig an eurem Versionsmanagement nicht.
Wer soll das denn funktionsgerecht garantieren?
Du hast Recht, denn es gibt keins.
Mir garantiert auch niemand, das das funktionsgerecht funktioniert.
Meine Infos beschränken sich auf
"Nutze den Contract und mock den Rest, eine echte Testumgebung bekommst du evtl im Januar, bis dahin muss aber alles umgestellt sein"
Der Service wird in Indien entwickelt. Ich bekomme täglich ein Worddokument mit dem UML eines Contracts + ein Jsonbeispiel, anhand dessen ich alles vorbereiten muss.
Daher - ich hoffe du verstehst mich - habe ich glaube ich keine andere Wahl.
[...] Hat es bei dir ohne dynamic funktioniert? Hast du die Lösungen mal verglichen? [...]
Du hast Recht...
Der Parameter ist vom Typ RealAnalyticalDetailRequest...
Aber wie kann das sein wenn ich garnicht deserialisiere? Der Body ist doch JsonSerialized...
Hallo Coffeebean,
ich hatte zwischendrin exakt das gleiche Beispiel wie du.
Was mich allerdings wundert:
Der Parameter im Controller lässt sich nur mit dynamic verarbeiten.
Lasse ich dynamic weg, ist der parameter wieder null.
!Aufruf.png!
Meine zusätzlichen Probleme sind aber die Vorgaben:
Mit dem .AddBody bediene ich jetzt einen selbst geschriebenen TestService, welcher einen Contract implementiert, der die Funktionalität eines echten Services nachbildet.
Mit .AddParameter bediene ich aber den echten Service, und auch nur wenn ich .AddParameter benutze erhalte ich ein "OK" zurück.
Hallo Killerkrümel,
...auch fügst du das, was du als Body mitschicken willst, zweimal hinzu (glaube ich. Kenne RESTSharp zu wenig.)
Nur so kann ich derzeit beide Services bedienen. Sobald der echte Service fertig ist, fliegt das .AddBody(...) raus.
@Abt:
Der TestService ist vollkommen obsolet und fällt weg, sobald der echte Service korrekt funktioniert und fertig implementiert ist.
Ich brauche ihn derzeit lediglich, um unsere anderen Programme auf den echten Service vorzubereiten, da dieser alle unsere aktuellen ServiceImplementationen ersetzen wird. Daher wollte ich keine Typisierung, um möglichst flexibel auf Änderungen im ServiceContract reagieren zu können (Welche zurzeit nahezu täglich stattfinden).
Wenn es jedoch interessante Ansätze gibt (Wie du schon sagtest [e.g. DependencyInjection...]) lasse ich mich natürlich gerne belehren.
So far danke für eure Mühe!
VG Killerkruemel
Hallo,
Danke an Coffebean und Abt!
Anbei der Code, falls jemand die gleichen Probleme hat.
ApiController:
public class BaseController<TRepository> : ApiController where TRepository : IRepository
{
[HttpPut]
[WebInvoke(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
public CoreLabOfflineResultManagementResponse GetAnalyticalDetails([FromBody] dynamic json)
{
var request = JsonConvert.DeserializeObject<RealAnalyticalDetailRequest>(json.ToString());
var resp = new CoreLabOfflineResultManagementResponse();
using (var repo = new TransferCore<TRepository>())
{
var result = repo.GetDetails(request.LabContainerCodes);
foreach (var labContainer in result.Response)
{
((List<ILabContainer>)resp.Response).Add(labContainer);
}
}
return resp;
}
}
RestSharpCall:
public async Task<TResponse> GetAnalyticalDetailResponse<TResponse>(RealAnalyticalDetailRequest request)
{
if (request == null)
throw new ArgumentException("Codes are null!", nameof(request));
var restClient = new RestClient(_httpClient.BaseAddress);
restClient.Authenticator = new NtlmAuthenticator(new NetworkCredential("USER", "PASSWORD", "DOMAIN"));
var restRequest = new RestRequest(Method.PUT);
restRequest.AddHeader("Content-Type", "application/json");
restRequest.AddHeader("Cache-Control", "no-cache");
restRequest.AddParameter("application/json", JsonConvert.SerializeObject(request, Formatting.None), ParameterType.RequestBody);
restRequest.AddBody(JsonConvert.SerializeObject(request, Formatting.None));
var restResponse = await restClient.ExecuteTaskAsync(restRequest);
return JObject.Parse(restResponse.Content).ToProxy<TResponse>();
}
Hallo Coffeebean,
auch das bleibt null. Ist vielleicht irgendwas in meinem APIController falsch?
Ist Richtig.
tun wir auch nicht. aber sowohl der RequestContent als auch der ControllerParameter sind wieder null...
Hallo Coffeebean,
var restRequest = new RestRequest(Method.PUT);
restRequest.AddHeader("Content-Type", "application/json");
restRequest.AddHeader("Cache-Control", "no-cache");
restRequest.AddBody("{\r\n\"LabContainerCodes\" : [\"00000031\"]\r\n}\r\n");
IRestResponse restResponse = restClient.Execute(restRequest);
!test.png!
Es ist zum Verzweifeln...
Hallo Coffeebean,
die LabcontainerCodes sind null. Ich finde nirgendwo im APIController / Request die entsprechenden Daten.
Hallo Abt,
das das so nicht live geht hätte ich sagen sollen. Das war nur ein test um möglichst schnell an die Daten zu kommen.
Hallo Community,
kann mir jemand adhoc sagen, wo ich den Content eines RestRequests finde, wenn ich via RestClient einen WebApiController aufrufe?
var restClient = new RestClient(requestResult.RequestUri);
restClient.Authenticator = new NtlmAuthenticator(new NetworkCredential("*****", "*****", "*****"));
var restRequest = new RestRequest(Method.PUT);
restRequest.AddHeader("Content-Type", "application/json");
restRequest.AddParameter("undefined", "{\r\n\"LabContainerCodes\" : [\"00000031\"]\r\n}\r\n", ParameterType.RequestBody);
speziell meine ich
restRequest.AddParameter("undefined", "{\r\n\"LabContainerCodes\" : [\"00000031\"]\r\n}\r\n", ParameterType.RequestBody);
Controllermethod:
[HttpPut]
[WebInvoke(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
public CoreLabOfflineResultManagementResponse GetAnalyticalDetails([FromBody] IEnumerable<string> labContainerCodes)
{
string jsonContent = Request.Content.ReadAsStringAsync().Result;
var resp = new CoreLabOfflineResultManagementResponse();
using (var repo = new TransferCore<TRepository>())
{
var result = repo.GetDetails(labContainerCodes);
foreach (var labContainer in result.Response)
{
((List<ILabContainer>) resp.Response).Add(labContainer);
}
}
return resp;
}
Hallo,
mit Ghostdoc und Sandcastle konnte man 'imho' eine Art "F1-Hilfe" erstellen.
Siehe hierzu
Ghostdoc und Sandcastle
Im Beitrag sind auch ein paar interessante Links gewesen, vielleicht ist es das was du suchst.
Hey,
Probier mal
Console.Write("{0}\t", farbe);
LG Killerkruemel
Dank Commandmap und Compisties ist mein Code nun halbwegs ok bei einer ui mit über 40 Controls . Vielen Dank für die Tips!
PS:
Oder kann mir jemand erklären, was Task.Yield macht?
Es muss ja irgendetwas anders machen, vielleicht hilft es mir, meinen Fehler zu finden
await Task.Yield() will force your method to be asynchronous [...]
Source: Task Yield - Why use it?
Btw - da steht auch
Internally, await Task.Yield() simply queues the continuation on either the current synchronization context or on a random pool thread, if SynchronizationContext.Current is null.
Kann es daher vllt sein, das durch eine eventuelle Synchronizität deiner Threads der "falsche" Dispatcher genutzt wird, während du deinen mitgibst?
Falls ich falsch liege, korregiert mich bitte.
VG Killerkruemel
**Auch Du mein Sohn ... **solltest Dir das Null Object Pattern anschauen:
>
[...]
PS.: Das mit dem Nullobjekt verstehe ich nicht ansatzweise... Und wenn ich mir die Diskussionsseite auf Wikipedia anschaue, auch sonst kaum einer...