0

I have problem with dynamic object.

I have method which return something like:

 public async Task<dynamic> GetItemBasicInformation(string itemId)
    {
        var apiUrl = $"{WebConfigurationManager.AppSettings["apiAdress"]}{itemId}";
        var result = await _httpClientHelper.GetRequest(apiUrl);

        return new
        {
            name = result["name"].Value<string>(),
            itemId = result["itemId"].Value<string>(),
            attributes = result["attributes"].Values<JToken>()
        };
    }

Then I want to read properties from dynamic object in another class:

    [ActionName("test")]
    public async Task<IHttpActionResult> GetTest()
    {
         dynamic item = await _testItemHelper.GetItemBasicInformation("TI-1658001");
         var name = item.name;

        return Ok();
    }

Also this method is in another assembly than GetItemBasicInformation() method.

Unfortunately I get ''object' does not contain a definition for 'name'' exception, but debugging show me that item contains all properties with value.

Why am I getting this error and how can I solve this problem?

Konrad S
  • 21
  • 4
  • 1
    Just a question, why do you need dynamic here? Why dont you just create a model and return that model instead? Seems much easier that way – Manish Mallavarapu Apr 10 '20 at 06:55
  • 1
    If the exception says that the object doesn't have a `name` property, then it doesn't have a `name` property. Simple as that. I grant that the code you posted looks like it ought to work, but since it doesn't, there's something you're not telling us. Please fix your question so that it includes a good [mcve] that reliably reproduces the problem. In the meantime, double-check your code...the code you posted is trying to access `name` in the `testItem` variable, while the object returned by the method is stored in `item`. – Peter Duniho Apr 10 '20 at 06:58
  • If you really want to use dynamic (and Manish here is probably right, if you can keep type safety then by all means do), know that anonymous types and dynamic don't have much to do with each other. Read [this answer](https://stackoverflow.com/a/3740035/129782) (basically you want to use `ExpandoObject`). – s.m. Apr 10 '20 at 06:58
  • @s.m.: it's true the two language features don't have _much_ to do with each other. In particular, anonymous types are about _declaring_ types implicitly, while `dynamic` is about _using_ types implicitly. They are separate features. But, I can see how someone might be lulled into a false sense of happiness when they discover they can use `dynamic` as a way of accessing an instance of an anonymous type returned by another method. In that sense, they do sort of "go together" (even if it is an abuse of the language :) ). (And I disagree that what the OP is looking for is `ExpandoObject`.) – Peter Duniho Apr 10 '20 at 07:00
  • @PeterDuniho yes, I can see how one might think it should just work. For the record, I don't think OP wants Expando either, just that it would work if they did use it. Perhaps I wasn't clear enough. Me, I would declare a model and be done with it unless there's a very good reason to give up type safety. – s.m. Apr 10 '20 at 07:06
  • @s.m.: _"just that it would work if they did use it"_ -- well, to be fair...`dynamic` would work too, if they'd use it properly (i.e. use the correct variable name). Conversely, they could just as easily have the same typo using `ExpandoObject` as they do using `dynamic`. – Peter Duniho Apr 10 '20 at 07:09
  • @PeterDuniho I have updated my question with picture which show you that I'm getting this error. Also this is all my code . – Konrad S Apr 10 '20 at 07:13
  • 1
    No, it's obviously not all your code. Heck, the picture you posted doesn't even match the code you posted. Please fix your question. (No one is disputing that you are getting the error, so posting the picture is pointless. What we need is for you to post an _actual_ [mcve] that reliably reproduces the problem. Or, you could just double-check your code more closely, and fix whatever typo is causing the problem yourself.) – Peter Duniho Apr 10 '20 at 07:16
  • @PeterDuniho are you sure that it would work, variable names aside? I don't think it would: https://dotnetfiddle.net/2gvXHI. Uncomment and it works, leave the comment and it throws an exception. Am I missing something? – s.m. Apr 10 '20 at 07:24
  • @PeterDuniho You are right. I also forgot that GetTest() method is in another assembly than GetItemBasicInformation() method. When I moved my TestItemHelper to the same assembly it works perfectly. Do you know why it isn't work when methods are in different assembly? – Konrad S Apr 10 '20 at 07:46
  • @s.m.: yes, I'm sure it would work. The exception you're getting in the "fiddle" is related to that environment, not the inability to get the property. Code runs with restricted rights (i.e. it's probably not "full trust") in that context. Try it in Visual Studio. – Peter Duniho Apr 10 '20 at 14:41
  • @KonradS: _"Do you know why it isn't work when methods are in different assembly?"_ -- I infer that you've already found your answer to that question, in the duplicate question. `dynamic` simply postpones compilation to run-time, filling in details as necessary. But the code still has to comply with the C# rules...since anonymous types aren't `public`, it isn't found when `dynamic` tries to compile the code at runtime, just like it wouldn't find the type if you compiled it at build time. – Peter Duniho Apr 10 '20 at 14:46
  • Even within an assembly it's poor form to use anonymous types this way...for public code in a library, you definitely should be declaring a named type for all interactions with calling code. – Peter Duniho Apr 10 '20 at 14:50

0 Answers0